Fri Aug 24 02:22:14 2007

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  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Zaptel Pseudo TDM interface 
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Connects to the zaptel telephony library as well as 
00026  * libpri. Libpri is optional and needed only if you are
00027  * going to use ISDN connections.
00028  *
00029  * You need to install libraries before you attempt to compile
00030  * and install the zaptel channel.
00031  *
00032  * \par See also
00033  * \arg \ref Config_zap
00034  *
00035  * \ingroup channel_drivers
00036  *
00037  * \todo Deprecate the "musiconhold" configuration option post 1.4
00038  */
00039 
00040 /*** MODULEINFO
00041    <depend>zaptel_vldtmf</depend>
00042    <depend>zaptel</depend>
00043    <depend>tonezone</depend>
00044    <use>pri</use>
00045  ***/
00046 
00047 #include "asterisk.h"
00048 
00049 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00050 
00051 #include <stdio.h>
00052 #include <string.h>
00053 #ifdef __NetBSD__
00054 #include <pthread.h>
00055 #include <signal.h>
00056 #else
00057 #include <sys/signal.h>
00058 #endif
00059 #include <errno.h>
00060 #include <stdlib.h>
00061 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00062 #include <stdint.h>
00063 #endif
00064 #include <unistd.h>
00065 #include <sys/ioctl.h>
00066 #include <math.h>
00067 #include <ctype.h>
00068 #include <zaptel/zaptel.h>
00069 #include <zaptel/tonezone.h>
00070 
00071 #ifdef HAVE_PRI
00072 #include <libpri.h>
00073 #endif
00074 
00075 #include "asterisk/lock.h"
00076 #include "asterisk/channel.h"
00077 #include "asterisk/config.h"
00078 #include "asterisk/logger.h"
00079 #include "asterisk/module.h"
00080 #include "asterisk/pbx.h"
00081 #include "asterisk/options.h"
00082 #include "asterisk/file.h"
00083 #include "asterisk/ulaw.h"
00084 #include "asterisk/alaw.h"
00085 #include "asterisk/callerid.h"
00086 #include "asterisk/adsi.h"
00087 #include "asterisk/cli.h"
00088 #include "asterisk/cdr.h"
00089 #include "asterisk/features.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/say.h"
00092 #include "asterisk/tdd.h"
00093 #include "asterisk/app.h"
00094 #include "asterisk/dsp.h"
00095 #include "asterisk/astdb.h"
00096 #include "asterisk/manager.h"
00097 #include "asterisk/causes.h"
00098 #include "asterisk/term.h"
00099 #include "asterisk/utils.h"
00100 #include "asterisk/transcap.h"
00101 #include "asterisk/stringfields.h"
00102 #include "asterisk/abstract_jb.h"
00103 #include "asterisk/smdi.h"
00104 #include "asterisk/astobj.h"
00105 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00106 
00107 /*! Global jitterbuffer configuration - by default, jb is disabled */
00108 static struct ast_jb_conf default_jbconf =
00109 {
00110    .flags = 0,
00111    .max_size = -1,
00112    .resync_threshold = -1,
00113    .impl = ""
00114 };
00115 static struct ast_jb_conf global_jbconf;
00116 
00117 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00118 #error "Your zaptel is too old.  Please update"
00119 #endif
00120 
00121 #ifndef ZT_TONEDETECT
00122 /* Work around older code with no tone detect */
00123 #define ZT_EVENT_DTMFDOWN 0
00124 #define ZT_EVENT_DTMFUP 0
00125 #endif
00126 
00127 /* define this to send PRI user-user information elements */
00128 #undef SUPPORT_USERUSER
00129 
00130 /*! 
00131  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00132  * the user hangs up to reset the state machine so ring works properly.
00133  * This is used to be able to support kewlstart by putting the zhone in
00134  * groundstart mode since their forward disconnect supervision is entirely
00135  * broken even though their documentation says it isn't and their support
00136  * is entirely unwilling to provide any assistance with their channel banks
00137  * even though their web site says they support their products for life.
00138  */
00139 /* #define ZHONE_HACK */
00140 
00141 /*! \note
00142  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00143  * before dialing on it.  Certain FXO interfaces always think they're out of
00144  * service with this method however.
00145  */
00146 /* #define ZAP_CHECK_HOOKSTATE */
00147 
00148 /*! \brief Typically, how many rings before we should send Caller*ID */
00149 #define DEFAULT_CIDRINGS 1
00150 
00151 #define CHANNEL_PSEUDO -12
00152 
00153 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00154 
00155 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00156 #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)) 
00157 
00158 static const char tdesc[] = "Zapata Telephony Driver"
00159 #ifdef HAVE_PRI
00160                " w/PRI"
00161 #endif
00162 ;
00163 
00164 static const char config[] = "zapata.conf";
00165 
00166 #define SIG_EM    ZT_SIG_EM
00167 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00168 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00169 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00170 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00171 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00172 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00173 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00174 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00175 #define SIG_FXSLS ZT_SIG_FXSLS
00176 #define SIG_FXSGS ZT_SIG_FXSGS
00177 #define SIG_FXSKS ZT_SIG_FXSKS
00178 #define SIG_FXOLS ZT_SIG_FXOLS
00179 #define SIG_FXOGS ZT_SIG_FXOGS
00180 #define SIG_FXOKS ZT_SIG_FXOKS
00181 #define SIG_PRI      ZT_SIG_CLEAR
00182 #define  SIG_SF      ZT_SIG_SF
00183 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00184 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00185 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00186 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00187 #define SIG_EM_E1 ZT_SIG_EM_E1
00188 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00189 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00190 
00191 #define NUM_SPANS       32
00192 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00193 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00194 
00195 #define CHAN_PSEUDO  -2
00196 
00197 #define DCHAN_PROVISIONED (1 << 0)
00198 #define DCHAN_NOTINALARM  (1 << 1)
00199 #define DCHAN_UP          (1 << 2)
00200 
00201 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00202 
00203 static char defaultcic[64] = "";
00204 static char defaultozz[64] = "";
00205 
00206 static char progzone[10] = "";
00207 
00208 static int distinctiveringaftercid = 0;
00209 
00210 static int numbufs = 4;
00211 
00212 #ifdef HAVE_PRI
00213 static struct ast_channel inuse;
00214 #ifdef PRI_GETSET_TIMERS
00215 static int pritimers[PRI_MAX_TIMERS];
00216 #endif
00217 static int pridebugfd = -1;
00218 static char pridebugfilename[1024] = "";
00219 #endif
00220 
00221 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00222 static int firstdigittimeout = 16000;
00223 
00224 /*! \brief How long to wait for following digits (FXO logic) */
00225 static int gendigittimeout = 8000;
00226 
00227 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00228 static int matchdigittimeout = 3000;
00229 
00230 /*! \brief Protect the interface list (of zt_pvt's) */
00231 AST_MUTEX_DEFINE_STATIC(iflock);
00232 
00233 
00234 static int ifcount = 0;
00235 
00236 #ifdef HAVE_PRI
00237 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00238 #endif
00239 
00240 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00241    when it's doing something critical. */
00242 AST_MUTEX_DEFINE_STATIC(monlock);
00243 
00244 /*! \brief This is the thread for the monitor which checks for input on the channels
00245    which are not currently in use. */
00246 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00247 
00248 static int restart_monitor(void);
00249 
00250 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);
00251 
00252 static int zt_sendtext(struct ast_channel *c, const char *text);
00253 
00254 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00255 static inline int zt_get_event(int fd)
00256 {
00257    int j;
00258    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00259       return -1;
00260    return j;
00261 }
00262 
00263 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00264 static inline int zt_wait_event(int fd)
00265 {
00266    int i, j = 0;
00267    i = ZT_IOMUX_SIGEVENT;
00268    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00269       return -1;
00270    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00271       return -1;
00272    return j;
00273 }
00274 
00275 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00276 #define READ_SIZE 160
00277 
00278 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00279 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00280 
00281 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00282 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 300 ms */
00283 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00284 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00285 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE)
00286 
00287 struct zt_pvt;
00288 
00289 static int ringt_base = DEFAULT_RINGT;
00290 
00291 #ifdef HAVE_PRI
00292 
00293 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00294 #define PRI_CHANNEL(p) ((p) & 0xff)
00295 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00296 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00297 
00298 struct zt_pri {
00299    pthread_t master;                /*!< Thread of master */
00300    ast_mutex_t lock;                /*!< Mutex */
00301    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00302    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00303    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00304    int minunused;                   /*!< Min # of channels to keep empty */
00305    int minidle;                     /*!< Min # of "idling" calls to keep active */
00306    int nodetype;                    /*!< Node type */
00307    int switchtype;                     /*!< Type of switch to emulate */
00308    int nsf;                   /*!< Network-Specific Facilities */
00309    int dialplan;                    /*!< Dialing plan */
00310    int localdialplan;                  /*!< Local dialing plan */
00311    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00312    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00313    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00314    char privateprefix[20];                /*!< for private dialplans */
00315    char unknownprefix[20];                /*!< for unknown dialplans */
00316    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00317    int trunkgroup;                     /*!< What our trunkgroup is */
00318    int mastertrunkgroup;                  /*!< What trunk group is our master */
00319    int prilogicalspan;                 /*!< Logical span number within trunk group */
00320    int numchans;                    /*!< Num of channels we represent */
00321    int overlapdial;                 /*!< In overlap dialing mode */
00322    int facilityenable;                 /*!< Enable facility IEs */
00323    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00324    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00325    struct pri *pri;                 /*!< Currently active D-channel */
00326    int debug;
00327    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00328    int offset;
00329    int span;
00330    int resetting;
00331    int resetpos;
00332    time_t lastreset;                /*!< time when unused channels were last reset */
00333    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00334    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00335    struct zt_pvt *crvs;                /*!< Member CRV structs */
00336    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00337 };
00338 
00339 
00340 static struct zt_pri pris[NUM_SPANS];
00341 
00342 #if 0
00343 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00344 #else
00345 #define DEFAULT_PRI_DEBUG 0
00346 #endif
00347 
00348 static inline void pri_rel(struct zt_pri *pri)
00349 {
00350    ast_mutex_unlock(&pri->lock);
00351 }
00352 
00353 #else
00354 /*! Shut up the compiler */
00355 struct zt_pri;
00356 #endif
00357 
00358 #define SUB_REAL  0        /*!< Active call */
00359 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00360 #define SUB_THREEWAY 2        /*!< Three-way call */
00361 
00362 /* Polarity states */
00363 #define POLARITY_IDLE   0
00364 #define POLARITY_REV    1
00365 
00366 
00367 static struct zt_distRings drings;
00368 
00369 struct distRingData {
00370    int ring[3];
00371 };
00372 struct ringContextData {
00373    char contextData[AST_MAX_CONTEXT];
00374 };
00375 struct zt_distRings {
00376    struct distRingData ringnum[3];
00377    struct ringContextData ringContext[3];
00378 };
00379 
00380 static char *subnames[] = {
00381    "Real",
00382    "Callwait",
00383    "Threeway"
00384 };
00385 
00386 struct zt_subchannel {
00387    int zfd;
00388    struct ast_channel *owner;
00389    int chan;
00390    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00391    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00392    unsigned int needringing:1;
00393    unsigned int needbusy:1;
00394    unsigned int needcongestion:1;
00395    unsigned int needcallerid:1;
00396    unsigned int needanswer:1;
00397    unsigned int needflash:1;
00398    unsigned int needhold:1;
00399    unsigned int needunhold:1;
00400    unsigned int linear:1;
00401    unsigned int inthreeway:1;
00402    ZT_CONFINFO curconf;
00403 };
00404 
00405 #define CONF_USER_REAL     (1 << 0)
00406 #define CONF_USER_THIRDCALL   (1 << 1)
00407 
00408 #define MAX_SLAVES   4
00409 
00410 static struct zt_pvt {
00411    ast_mutex_t lock;
00412    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00413                      /*!< Up to three channels can be associated with this call */
00414       
00415    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00416    struct zt_subchannel subs[3];       /*!< Sub-channels */
00417    struct zt_confinfo saveconf;        /*!< Saved conference info */
00418 
00419    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00420    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00421    int inconference;          /*!< If our real should be in the conference */
00422    
00423    int sig;             /*!< Signalling style */
00424    int radio;              /*!< radio type */
00425    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00426    int oprmode;               /*!< "Operator Services" mode */
00427    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00428    float rxgain;
00429    float txgain;
00430    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00431    struct zt_pvt *next;          /*!< Next channel in list */
00432    struct zt_pvt *prev;          /*!< Prev channel in list */
00433 
00434    /* flags */
00435    unsigned int adsi:1;
00436    unsigned int answeronpolarityswitch:1;
00437    unsigned int busydetect:1;
00438    unsigned int callreturn:1;
00439    unsigned int callwaiting:1;
00440    unsigned int callwaitingcallerid:1;
00441    unsigned int cancallforward:1;
00442    unsigned int canpark:1;
00443    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00444    unsigned int destroy:1;
00445    unsigned int didtdd:1;           /*!< flag to say its done it once */
00446    unsigned int dialednone:1;
00447    unsigned int dialing:1;
00448    unsigned int digital:1;
00449    unsigned int dnd:1;
00450    unsigned int echobreak:1;
00451    unsigned int echocanbridged:1;
00452    unsigned int echocanon:1;
00453    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00454    unsigned int firstradio:1;
00455    unsigned int hanguponpolarityswitch:1;
00456    unsigned int hardwaredtmf:1;
00457    unsigned int hidecallerid:1;
00458    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00459    unsigned int ignoredtmf:1;
00460    unsigned int immediate:1;        /*!< Answer before getting digits? */
00461    unsigned int inalarm:1;
00462    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00463    unsigned int outgoing:1;
00464    unsigned int overlapdial:1;
00465    unsigned int permcallwaiting:1;
00466    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00467    unsigned int priindication_oob:1;
00468    unsigned int priexclusive:1;
00469    unsigned int pulse:1;
00470    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00471    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00472    unsigned int threewaycalling:1;
00473    unsigned int transfer:1;
00474    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00475    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00476    unsigned int usedistinctiveringdetection:1;
00477    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00478    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00479 #if defined(HAVE_PRI)
00480    unsigned int alerting:1;
00481    unsigned int alreadyhungup:1;
00482    unsigned int isidlecall:1;
00483    unsigned int proceeding:1;
00484    unsigned int progress:1;
00485    unsigned int resetting:1;
00486    unsigned int setup_ack:1;
00487 #endif
00488    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00489    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00490 
00491    struct zt_distRings drings;
00492 
00493    char context[AST_MAX_CONTEXT];
00494    char defcontext[AST_MAX_CONTEXT];
00495    char exten[AST_MAX_EXTENSION];
00496    char language[MAX_LANGUAGE];
00497    char mohinterpret[MAX_MUSICCLASS];
00498    char mohsuggest[MAX_MUSICCLASS];
00499 #ifdef PRI_ANI
00500    char cid_ani[AST_MAX_EXTENSION];
00501 #endif
00502    char cid_num[AST_MAX_EXTENSION];
00503    int cid_ton;               /*!< Type Of Number (TON) */
00504    char cid_name[AST_MAX_EXTENSION];
00505    char lastcid_num[AST_MAX_EXTENSION];
00506    char lastcid_name[AST_MAX_EXTENSION];
00507    char *origcid_num;            /*!< malloced original callerid */
00508    char *origcid_name;           /*!< malloced original callerid */
00509    char callwait_num[AST_MAX_EXTENSION];
00510    char callwait_name[AST_MAX_EXTENSION];
00511    char rdnis[AST_MAX_EXTENSION];
00512    char dnid[AST_MAX_EXTENSION];
00513    ast_group_t group;
00514    int law;
00515    int confno;             /*!< Our conference */
00516    int confusers;             /*!< Who is using our conference */
00517    int propconfno;               /*!< Propagated conference number */
00518    ast_group_t callgroup;
00519    ast_group_t pickupgroup;
00520    int channel;               /*!< Channel Number or CRV */
00521    int span;               /*!< Span number */
00522    time_t guardtime;          /*!< Must wait this much time before using for new call */
00523    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00524    int cid_start;             /*!< CID start indicator, polarity or ring */
00525    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00526    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00527    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00528    unsigned char *cidspill;
00529    int cidpos;
00530    int cidlen;
00531    int ringt;
00532    int ringt_base;
00533    int stripmsd;
00534    int callwaitcas;
00535    int callwaitrings;
00536    int echocancel;
00537    int echotraining;
00538    char echorest[20];
00539    int busycount;
00540    int busy_tonelength;
00541    int busy_quietlength;
00542    int callprogress;
00543    struct timeval flashtime;        /*!< Last flash-hook time */
00544    struct ast_dsp *dsp;
00545    int cref;               /*!< Call reference number */
00546    ZT_DIAL_OPERATION dop;
00547    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00548    char finaldial[64];
00549    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00550    int amaflags;              /*!< AMA Flags */
00551    struct tdd_state *tdd;           /*!< TDD flag */
00552    char call_forward[AST_MAX_EXTENSION];
00553    char mailbox[AST_MAX_EXTENSION];
00554    char dialdest[256];
00555    int onhooktime;
00556    int msgstate;
00557    int distinctivering;          /*!< Which distinctivering to use */
00558    int cidrings;              /*!< Which ring to deliver CID on */
00559    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00560    int fake_event;
00561    int polarityonanswerdelay;
00562    struct timeval polaritydelaytv;
00563    int sendcalleridafter;
00564 #ifdef HAVE_PRI
00565    struct zt_pri *pri;
00566    struct zt_pvt *bearer;
00567    struct zt_pvt *realcall;
00568    q931_call *call;
00569    int prioffset;
00570    int logicalspan;
00571 #endif   
00572    int polarity;
00573    int dsp_features;
00574    char begindigit;
00575 } *iflist = NULL, *ifend = NULL;
00576 
00577 /*! \brief Channel configuration from zapata.conf .
00578  * This struct is used for parsing the [channels] section of zapata.conf.
00579  * Generally there is a field here for every possible configuration item.
00580  *
00581  * The state of fields is saved along the parsing and whenever a 'channel'
00582  * statement is reached, the current zt_chan_conf is used to configure the 
00583  * channel (struct zt_pvt)
00584  *
00585  * @seealso zt_chan_init for the default values.
00586  */
00587 struct zt_chan_conf {
00588    struct zt_pvt chan;
00589 #ifdef HAVE_PRI
00590    struct zt_pri pri;
00591 #endif
00592    ZT_PARAMS timing;
00593 
00594    char smdi_port[SMDI_MAX_FILENAME_LEN];
00595 };
00596 
00597 /** returns a new zt_chan_conf with default values (by-value) */
00598 static struct zt_chan_conf zt_chan_conf_default(void) {
00599    /* recall that if a field is not included here it is initialized
00600     * to 0 or equivalent
00601     */
00602    struct zt_chan_conf conf = {
00603 #ifdef HAVE_PRI
00604       .pri = {
00605          .nsf = PRI_NSF_NONE,
00606          .switchtype = PRI_SWITCH_NI2,
00607          .dialplan = PRI_NATIONAL_ISDN + 1,
00608          .localdialplan = PRI_NATIONAL_ISDN + 1,
00609          .nodetype = PRI_CPE,
00610 
00611          .minunused = 2,
00612          .idleext = "",
00613          .idledial = "",
00614          .internationalprefix = "",
00615          .nationalprefix = "",
00616          .localprefix = "",
00617          .privateprefix = "",
00618          .unknownprefix = "",
00619 
00620          .resetinterval = 3600
00621       },
00622 #endif
00623       .chan = {
00624          .context = "default",
00625          .cid_num = "",
00626          .cid_name = "",
00627          .mohinterpret = "default",
00628          .mohsuggest = "",
00629          .transfertobusy = 1,
00630 
00631          .cid_signalling = CID_SIG_BELL,
00632          .cid_start = CID_START_RING,
00633          .zaptrcallerid = 0,
00634          .use_callerid = 1,
00635          .sig = -1,
00636          .outsigmod = -1,
00637 
00638          .tonezone = -1,
00639 
00640          .echocancel = 1,
00641 
00642          .busycount = 3,
00643 
00644          .accountcode = "",
00645 
00646          .mailbox = "",
00647 
00648 
00649          .polarityonanswerdelay = 600,
00650 
00651          .sendcalleridafter = DEFAULT_CIDRINGS
00652       },
00653       .timing = {
00654          .prewinktime = -1,
00655          .preflashtime = -1,
00656          .winktime = -1,
00657          .flashtime = -1,
00658          .starttime = -1,
00659          .rxwinktime = -1,
00660          .rxflashtime = -1,
00661          .debouncetime = -1
00662       },
00663       .smdi_port = "/dev/ttyS0",
00664    };
00665 
00666    return conf;
00667 }
00668 
00669 
00670 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00671 static int zt_digit_begin(struct ast_channel *ast, char digit);
00672 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00673 static int zt_sendtext(struct ast_channel *c, const char *text);
00674 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00675 static int zt_hangup(struct ast_channel *ast);
00676 static int zt_answer(struct ast_channel *ast);
00677 static struct ast_frame *zt_read(struct ast_channel *ast);
00678 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00679 static struct ast_frame *zt_exception(struct ast_channel *ast);
00680 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00681 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00682 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00683 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00684 
00685 static const struct ast_channel_tech zap_tech = {
00686    .type = "Zap",
00687    .description = tdesc,
00688    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00689    .requester = zt_request,
00690    .send_digit_begin = zt_digit_begin,
00691    .send_digit_end = zt_digit_end,
00692    .send_text = zt_sendtext,
00693    .call = zt_call,
00694    .hangup = zt_hangup,
00695    .answer = zt_answer,
00696    .read = zt_read,
00697    .write = zt_write,
00698    .bridge = zt_bridge,
00699    .exception = zt_exception,
00700    .indicate = zt_indicate,
00701    .fixup = zt_fixup,
00702    .setoption = zt_setoption,
00703    .func_channel_read = zt_func_read,
00704 };
00705 
00706 #ifdef HAVE_PRI
00707 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00708 #else
00709 #define GET_CHANNEL(p) ((p)->channel)
00710 #endif
00711 
00712 struct zt_pvt *round_robin[32];
00713 
00714 #ifdef HAVE_PRI
00715 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00716 {
00717    int res;
00718    /* Grab the lock first */
00719    do {
00720       res = ast_mutex_trylock(&pri->lock);
00721       if (res) {
00722          ast_mutex_unlock(&pvt->lock);
00723          /* Release the lock and try again */
00724          usleep(1);
00725          ast_mutex_lock(&pvt->lock);
00726       }
00727    } while (res);
00728    /* Then break the poll */
00729    pthread_kill(pri->master, SIGURG);
00730    return 0;
00731 }
00732 #endif
00733 
00734 #define NUM_CADENCE_MAX 25
00735 static int num_cadence = 4;
00736 static int user_has_defined_cadences = 0;
00737 
00738 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00739    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00740    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00741    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00742    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00743 };
00744 
00745 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00746  * is 1, the second pause is 2 and so on.
00747  */
00748 
00749 static int cidrings[NUM_CADENCE_MAX] = {
00750    2,                            /*!< Right after first long ring */
00751    4,                            /*!< Right after long part */
00752    3,                            /*!< After third chirp */
00753    2,                            /*!< Second spell */
00754 };
00755 
00756 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00757          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00758 
00759 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00760 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00761 
00762 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00763 {
00764    int res;
00765    if (p->subs[0].owner == ast)
00766       res = 0;
00767    else if (p->subs[1].owner == ast)
00768       res = 1;
00769    else if (p->subs[2].owner == ast)
00770       res = 2;
00771    else {
00772       res = -1;
00773       if (!nullok)
00774          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00775    }
00776    return res;
00777 }
00778 
00779 #ifdef HAVE_PRI
00780 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00781 #else
00782 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00783 #endif
00784 {
00785 #ifdef HAVE_PRI
00786    if (pri)
00787       ast_mutex_unlock(&pri->lock);
00788 #endif         
00789    for (;;) {
00790       if (p->subs[a].owner) {
00791          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00792             ast_mutex_unlock(&p->lock);
00793             usleep(1);
00794             ast_mutex_lock(&p->lock);
00795          } else {
00796             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00797             ast_mutex_unlock(&p->subs[a].owner->lock);
00798             break;
00799          }
00800       } else
00801          break;
00802    }
00803 #ifdef HAVE_PRI
00804    if (pri)
00805       ast_mutex_lock(&pri->lock);
00806 #endif         
00807 }
00808 
00809 #ifdef HAVE_PRI
00810 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00811 #else
00812 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00813 #endif
00814 {
00815    /* We must unlock the PRI to avoid the possibility of a deadlock */
00816 #ifdef HAVE_PRI
00817    if (pri)
00818       ast_mutex_unlock(&pri->lock);
00819 #endif      
00820    for (;;) {
00821       if (p->owner) {
00822          if (ast_mutex_trylock(&p->owner->lock)) {
00823             ast_mutex_unlock(&p->lock);
00824             usleep(1);
00825             ast_mutex_lock(&p->lock);
00826          } else {
00827             ast_queue_frame(p->owner, f);
00828             ast_mutex_unlock(&p->owner->lock);
00829             break;
00830          }
00831       } else
00832          break;
00833    }
00834 #ifdef HAVE_PRI
00835    if (pri)
00836       ast_mutex_lock(&pri->lock);
00837 #endif      
00838 }
00839 
00840 static int restore_gains(struct zt_pvt *p);
00841 
00842 static void swap_subs(struct zt_pvt *p, int a, int b)
00843 {
00844    int tchan;
00845    int tinthreeway;
00846    struct ast_channel *towner;
00847 
00848    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00849 
00850    tchan = p->subs[a].chan;
00851    towner = p->subs[a].owner;
00852    tinthreeway = p->subs[a].inthreeway;
00853 
00854    p->subs[a].chan = p->subs[b].chan;
00855    p->subs[a].owner = p->subs[b].owner;
00856    p->subs[a].inthreeway = p->subs[b].inthreeway;
00857 
00858    p->subs[b].chan = tchan;
00859    p->subs[b].owner = towner;
00860    p->subs[b].inthreeway = tinthreeway;
00861 
00862    if (p->subs[a].owner) 
00863       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00864    if (p->subs[b].owner) 
00865       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00866    wakeup_sub(p, a, NULL);
00867    wakeup_sub(p, b, NULL);
00868 }
00869 
00870 static int zt_open(char *fn)
00871 {
00872    int fd;
00873    int isnum;
00874    int chan = 0;
00875    int bs;
00876    int x;
00877    isnum = 1;
00878    for (x = 0; x < strlen(fn); x++) {
00879       if (!isdigit(fn[x])) {
00880          isnum = 0;
00881          break;
00882       }
00883    }
00884    if (isnum) {
00885       chan = atoi(fn);
00886       if (chan < 1) {
00887          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00888          return -1;
00889       }
00890       fn = "/dev/zap/channel";
00891    }
00892    fd = open(fn, O_RDWR | O_NONBLOCK);
00893    if (fd < 0) {
00894       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00895       return -1;
00896    }
00897    if (chan) {
00898       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00899          x = errno;
00900          close(fd);
00901          errno = x;
00902          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00903          return -1;
00904       }
00905    }
00906    bs = READ_SIZE;
00907    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
00908    return fd;
00909 }
00910 
00911 static void zt_close(int fd)
00912 {
00913    if (fd > 0)
00914       close(fd);
00915 }
00916 
00917 static int zt_setlinear(int zfd, int linear)
00918 {
00919    int res;
00920    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00921    if (res)
00922       return res;
00923    return 0;
00924 }
00925 
00926 
00927 static int alloc_sub(struct zt_pvt *p, int x)
00928 {
00929    ZT_BUFFERINFO bi;
00930    int res;
00931    if (p->subs[x].zfd < 0) {
00932       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00933       if (p->subs[x].zfd > -1) {
00934          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00935          if (!res) {
00936             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00937             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00938             bi.numbufs = numbufs;
00939             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
00940             if (res < 0) {
00941                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
00942             }
00943          } else 
00944             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
00945          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
00946             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
00947             zt_close(p->subs[x].zfd);
00948             p->subs[x].zfd = -1;
00949             return -1;
00950          }
00951          if (option_debug)
00952             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
00953          return 0;
00954       } else
00955          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00956       return -1;
00957    }
00958    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
00959    return -1;
00960 }
00961 
00962 static int unalloc_sub(struct zt_pvt *p, int x)
00963 {
00964    if (!x) {
00965       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
00966       return -1;
00967    }
00968    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
00969    if (p->subs[x].zfd > -1) {
00970       zt_close(p->subs[x].zfd);
00971    }
00972    p->subs[x].zfd = -1;
00973    p->subs[x].linear = 0;
00974    p->subs[x].chan = 0;
00975    p->subs[x].owner = NULL;
00976    p->subs[x].inthreeway = 0;
00977    p->polarity = POLARITY_IDLE;
00978    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
00979    return 0;
00980 }
00981 
00982 static int digit_to_dtmfindex(char digit)
00983 {
00984    if (isdigit(digit))
00985       return ZT_TONE_DTMF_BASE + (digit - '0');
00986    else if (digit >= 'A' && digit <= 'D')
00987       return ZT_TONE_DTMF_A + (digit - 'A');
00988    else if (digit >= 'a' && digit <= 'd')
00989       return ZT_TONE_DTMF_A + (digit - 'a');
00990    else if (digit == '*')
00991       return ZT_TONE_DTMF_s;
00992    else if (digit == '#')
00993       return ZT_TONE_DTMF_p;
00994    else
00995       return -1;
00996 }
00997 
00998 static int zt_digit_begin(struct ast_channel *chan, char digit)
00999 {
01000    struct zt_pvt *pvt;
01001    int index;
01002    int dtmf = -1;
01003    
01004    pvt = chan->tech_pvt;
01005 
01006    ast_mutex_lock(&pvt->lock);
01007 
01008    index = zt_get_index(chan, pvt, 0);
01009 
01010    if ((index != SUB_REAL) || !pvt->owner)
01011       goto out;
01012 
01013 #ifdef HAVE_PRI
01014    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01015       if (pvt->setup_ack) {
01016          if (!pri_grab(pvt, pvt->pri)) {
01017             pri_information(pvt->pri->pri, pvt->call, digit);
01018             pri_rel(pvt->pri);
01019          } else
01020             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01021       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01022          int res;
01023          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01024          res = strlen(pvt->dialdest);
01025          pvt->dialdest[res++] = digit;
01026          pvt->dialdest[res] = '\0';
01027       }
01028       goto out;
01029    }
01030 #endif
01031    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01032       goto out;
01033 
01034    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01035       int res;
01036       ZT_DIAL_OPERATION zo = {
01037          .op = ZT_DIAL_OP_APPEND,
01038          .dialstr[0] = 'T',
01039          .dialstr[1] = digit,
01040          .dialstr[2] = 0,
01041       };
01042       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01043          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01044       else
01045          pvt->dialing = 1;
01046    } else {
01047       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01048       pvt->dialing = 1;
01049       pvt->begindigit = digit;
01050    }
01051 
01052 out:
01053    ast_mutex_unlock(&pvt->lock);
01054 
01055    return 0;
01056 }
01057 
01058 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01059 {
01060    struct zt_pvt *pvt;
01061    int res = 0;
01062    int index;
01063    int x;
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 || pvt->pulse)
01072       goto out;
01073 
01074 #ifdef HAVE_PRI
01075    /* This means that the digit was already sent via PRI signalling */
01076    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01077       goto out;
01078 #endif
01079 
01080    if (pvt->begindigit) {
01081       x = -1;
01082       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01083       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01084       pvt->dialing = 0;
01085       pvt->begindigit = 0;
01086    }
01087 
01088 out:
01089    ast_mutex_unlock(&pvt->lock);
01090 
01091    return res;
01092 }
01093 
01094 static char *events[] = {
01095    "No event",
01096    "On hook",
01097    "Ring/Answered",
01098    "Wink/Flash",
01099    "Alarm",
01100    "No more alarm",
01101    "HDLC Abort",
01102    "HDLC Overrun",
01103    "HDLC Bad FCS",
01104    "Dial Complete",
01105    "Ringer On",
01106    "Ringer Off",
01107    "Hook Transition Complete",
01108    "Bits Changed",
01109    "Pulse Start",
01110    "Timer Expired",
01111    "Timer Ping",
01112    "Polarity Reversal",
01113    "Ring Begin",
01114 };
01115 
01116 static struct {
01117    int alarm;
01118    char *name;
01119 } alarms[] = {
01120    { ZT_ALARM_RED, "Red Alarm" },
01121    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01122    { ZT_ALARM_BLUE, "Blue Alarm" },
01123    { ZT_ALARM_RECOVER, "Recovering" },
01124    { ZT_ALARM_LOOPBACK, "Loopback" },
01125    { ZT_ALARM_NOTOPEN, "Not Open" },
01126    { ZT_ALARM_NONE, "None" },
01127 };
01128 
01129 static char *alarm2str(int alarm)
01130 {
01131    int x;
01132    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01133       if (alarms[x].alarm & alarm)
01134          return alarms[x].name;
01135    }
01136    return alarm ? "Unknown Alarm" : "No Alarm";
01137 }
01138 
01139 static char *event2str(int event)
01140 {
01141    static char buf[256];
01142    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01143       return events[event];
01144    sprintf(buf, "Event %d", event); /* safe */
01145    return buf;
01146 }
01147 
01148 #ifdef HAVE_PRI
01149 static char *dialplan2str(int dialplan)
01150 {
01151    if (dialplan == -1) {
01152       return("Dynamically set dialplan in ISDN");
01153    }
01154    return (pri_plan2str(dialplan));
01155 }
01156 #endif
01157 
01158 static char *zap_sig2str(int sig)
01159 {
01160    static char buf[256];
01161    switch (sig) {
01162    case SIG_EM:
01163       return "E & M Immediate";
01164    case SIG_EMWINK:
01165       return "E & M Wink";
01166    case SIG_EM_E1:
01167       return "E & M E1";
01168    case SIG_FEATD:
01169       return "Feature Group D (DTMF)";
01170    case SIG_FEATDMF:
01171       return "Feature Group D (MF)";
01172    case SIG_FEATDMF_TA:
01173       return "Feature Groud D (MF) Tandem Access";
01174    case SIG_FEATB:
01175       return "Feature Group B (MF)";
01176    case SIG_E911:
01177       return "E911 (MF)";
01178    case SIG_FGC_CAMA:
01179       return "FGC/CAMA (Dialpulse)";
01180    case SIG_FGC_CAMAMF:
01181       return "FGC/CAMA (MF)";
01182    case SIG_FXSLS:
01183       return "FXS Loopstart";
01184    case SIG_FXSGS:
01185       return "FXS Groundstart";
01186    case SIG_FXSKS:
01187       return "FXS Kewlstart";
01188    case SIG_FXOLS:
01189       return "FXO Loopstart";
01190    case SIG_FXOGS:
01191       return "FXO Groundstart";
01192    case SIG_FXOKS:
01193       return "FXO Kewlstart";
01194    case SIG_PRI:
01195       return "PRI Signalling";
01196    case SIG_SF:
01197       return "SF (Tone) Signalling Immediate";
01198    case SIG_SFWINK:
01199       return "SF (Tone) Signalling Wink";
01200    case SIG_SF_FEATD:
01201       return "SF (Tone) Signalling with Feature Group D (DTMF)";
01202    case SIG_SF_FEATDMF:
01203       return "SF (Tone) Signalling with Feature Group D (MF)";
01204    case SIG_SF_FEATB:
01205       return "SF (Tone) Signalling with Feature Group B (MF)";
01206    case SIG_GR303FXOKS:
01207       return "GR-303 Signalling with FXOKS";
01208    case SIG_GR303FXSKS:
01209       return "GR-303 Signalling with FXSKS";
01210    case 0:
01211       return "Pseudo Signalling";
01212    default:
01213       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01214       return buf;
01215    }
01216 }
01217 
01218 #define sig2str zap_sig2str
01219 
01220 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01221 {
01222    /* If the conference already exists, and we're already in it
01223       don't bother doing anything */
01224    ZT_CONFINFO zi;
01225    
01226    memset(&zi, 0, sizeof(zi));
01227    zi.chan = 0;
01228 
01229    if (slavechannel > 0) {
01230       /* If we have only one slave, do a digital mon */
01231       zi.confmode = ZT_CONF_DIGITALMON;
01232       zi.confno = slavechannel;
01233    } else {
01234       if (!index) {
01235          /* Real-side and pseudo-side both participate in conference */
01236          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01237             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01238       } else
01239          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01240       zi.confno = p->confno;
01241    }
01242    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01243       return 0;
01244    if (c->zfd < 0)
01245       return 0;
01246    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01247       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01248       return -1;
01249    }
01250    if (slavechannel < 1) {
01251       p->confno = zi.confno;
01252    }
01253    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01254    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01255    return 0;
01256 }
01257 
01258 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01259 {
01260    /* If they're listening to our channel, they're ours */  
01261    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01262       return 1;
01263    /* If they're a talker on our (allocated) conference, they're ours */
01264    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01265       return 1;
01266    return 0;
01267 }
01268 
01269 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01270 {
01271    ZT_CONFINFO zi;
01272    if (/* Can't delete if there's no zfd */
01273       (c->zfd < 0) ||
01274       /* Don't delete from the conference if it's not our conference */
01275       !isourconf(p, c)
01276       /* Don't delete if we don't think it's conferenced at all (implied) */
01277       ) return 0;
01278    memset(&zi, 0, sizeof(zi));
01279    zi.chan = 0;
01280    zi.confno = 0;
01281    zi.confmode = 0;
01282    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01283       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01284       return -1;
01285    }
01286    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01287    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01288    return 0;
01289 }
01290 
01291 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01292 {
01293    int x;
01294    int useslavenative;
01295    struct zt_pvt *slave = NULL;
01296    /* Start out optimistic */
01297    useslavenative = 1;
01298    /* Update conference state in a stateless fashion */
01299    for (x = 0; x < 3; x++) {
01300       /* Any three-way calling makes slave native mode *definitely* out
01301          of the question */
01302       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01303          useslavenative = 0;
01304    }
01305    /* If we don't have any 3-way calls, check to see if we have
01306       precisely one slave */
01307    if (useslavenative) {
01308       for (x = 0; x < MAX_SLAVES; x++) {
01309          if (p->slaves[x]) {
01310             if (slave) {
01311                /* Whoops already have a slave!  No 
01312                   slave native and stop right away */
01313                slave = NULL;
01314                useslavenative = 0;
01315                break;
01316             } else {
01317                /* We have one slave so far */
01318                slave = p->slaves[x];
01319             }
01320          }
01321       }
01322    }
01323    /* If no slave, slave native definitely out */
01324    if (!slave)
01325       useslavenative = 0;
01326    else if (slave->law != p->law) {
01327       useslavenative = 0;
01328       slave = NULL;
01329    }
01330    if (out)
01331       *out = slave;
01332    return useslavenative;
01333 }
01334 
01335 static int reset_conf(struct zt_pvt *p)
01336 {
01337    ZT_CONFINFO zi;
01338    memset(&zi, 0, sizeof(zi));
01339    p->confno = -1;
01340    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01341    if (p->subs[SUB_REAL].zfd > -1) {
01342       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01343          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01344    }
01345    return 0;
01346 }
01347 
01348 static int update_conf(struct zt_pvt *p)
01349 {
01350    int needconf = 0;
01351    int x;
01352    int useslavenative;
01353    struct zt_pvt *slave = NULL;
01354 
01355    useslavenative = isslavenative(p, &slave);
01356    /* Start with the obvious, general stuff */
01357    for (x = 0; x < 3; x++) {
01358       /* Look for three way calls */
01359       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01360          conf_add(p, &p->subs[x], x, 0);
01361          needconf++;
01362       } else {
01363          conf_del(p, &p->subs[x], x);
01364       }
01365    }
01366    /* If we have a slave, add him to our conference now. or DAX
01367       if this is slave native */
01368    for (x = 0; x < MAX_SLAVES; x++) {
01369       if (p->slaves[x]) {
01370          if (useslavenative)
01371             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01372          else {
01373             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01374             needconf++;
01375          }
01376       }
01377    }
01378    /* If we're supposed to be in there, do so now */
01379    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01380       if (useslavenative)
01381          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01382       else {
01383          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01384          needconf++;
01385       }
01386    }
01387    /* If we have a master, add ourselves to his conference */
01388    if (p->master) {
01389       if (isslavenative(p->master, NULL)) {
01390          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01391       } else {
01392          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01393       }
01394    }
01395    if (!needconf) {
01396       /* Nobody is left (or should be left) in our conference.
01397          Kill it. */
01398       p->confno = -1;
01399    }
01400    if (option_debug)
01401       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01402    return 0;
01403 }
01404 
01405 static void zt_enable_ec(struct zt_pvt *p)
01406 {
01407    int x;
01408    int res;
01409    if (!p)
01410       return;
01411    if (p->echocanon) {
01412       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01413       return;
01414    }
01415    if (p->digital) {
01416       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01417       return;
01418    }
01419    if (p->echocancel) {
01420       if (p->sig == SIG_PRI) {
01421          x = 1;
01422          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01423          if (res)
01424             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01425       }
01426       x = p->echocancel;
01427       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01428       if (res) 
01429          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01430       else {
01431          p->echocanon = 1;
01432          if (option_debug)
01433             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01434       }
01435    } else if (option_debug)
01436       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01437 }
01438 
01439 static void zt_train_ec(struct zt_pvt *p)
01440 {
01441    int x;
01442    int res;
01443    if (p && p->echocancel && p->echotraining) {
01444       x = p->echotraining;
01445       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01446       if (res)
01447          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01448       else {
01449          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01450       }
01451    } else
01452       ast_log(LOG_DEBUG, "No echo training requested\n");
01453 }
01454 
01455 static void zt_disable_ec(struct zt_pvt *p)
01456 {
01457    int x;
01458    int res;
01459    if (p->echocancel) {
01460       x = 0;
01461       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01462       if (res)
01463          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01464       else if (option_debug)
01465          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01466    }
01467    p->echocanon = 0;
01468 }
01469 
01470 static void fill_txgain(struct zt_gains *g, float gain, int law)
01471 {
01472    int j;
01473    int k;
01474    float linear_gain = pow(10.0, gain / 20.0);
01475 
01476    switch (law) {
01477    case ZT_LAW_ALAW:
01478       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01479          if (gain) {
01480             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01481             if (k > 32767) k = 32767;
01482             if (k < -32767) k = -32767;
01483             g->txgain[j] = AST_LIN2A(k);
01484          } else {
01485             g->txgain[j] = j;
01486          }
01487       }
01488       break;
01489    case ZT_LAW_MULAW:
01490       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01491          if (gain) {
01492             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01493             if (k > 32767) k = 32767;
01494             if (k < -32767) k = -32767;
01495             g->txgain[j] = AST_LIN2MU(k);
01496          } else {
01497             g->txgain[j] = j;
01498          }
01499       }
01500       break;
01501    }
01502 }
01503 
01504 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01505 {
01506    int j;
01507    int k;
01508    float linear_gain = pow(10.0, gain / 20.0);
01509 
01510    switch (law) {
01511    case ZT_LAW_ALAW:
01512       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01513          if (gain) {
01514             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01515             if (k > 32767) k = 32767;
01516             if (k < -32767) k = -32767;
01517             g->rxgain[j] = AST_LIN2A(k);
01518          } else {
01519             g->rxgain[j] = j;
01520          }
01521       }
01522       break;
01523    case ZT_LAW_MULAW:
01524       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01525          if (gain) {
01526             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01527             if (k > 32767) k = 32767;
01528             if (k < -32767) k = -32767;
01529             g->rxgain[j] = AST_LIN2MU(k);
01530          } else {
01531             g->rxgain[j] = j;
01532          }
01533       }
01534       break;
01535    }
01536 }
01537 
01538 static int set_actual_txgain(int fd, int chan, float gain, int law)
01539 {
01540    struct zt_gains g;
01541    int res;
01542 
01543    memset(&g, 0, sizeof(g));
01544    g.chan = chan;
01545    res = ioctl(fd, ZT_GETGAINS, &g);
01546    if (res) {
01547       if (option_debug)
01548          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01549       return res;
01550    }
01551 
01552    fill_txgain(&g, gain, law);
01553 
01554    return ioctl(fd, ZT_SETGAINS, &g);
01555 }
01556 
01557 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01558 {
01559    struct zt_gains g;
01560    int res;
01561 
01562    memset(&g, 0, sizeof(g));
01563    g.chan = chan;
01564    res = ioctl(fd, ZT_GETGAINS, &g);
01565    if (res) {
01566       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01567       return res;
01568    }
01569 
01570    fill_rxgain(&g, gain, law);
01571 
01572    return ioctl(fd, ZT_SETGAINS, &g);
01573 }
01574 
01575 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01576 {
01577    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01578 }
01579 
01580 static int bump_gains(struct zt_pvt *p)
01581 {
01582    int res;
01583 
01584    /* Bump receive gain by 5.0db */
01585    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01586    if (res) {
01587       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01588       return -1;
01589    }
01590 
01591    return 0;
01592 }
01593 
01594 static int restore_gains(struct zt_pvt *p)
01595 {
01596    int res;
01597 
01598    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01599    if (res) {
01600       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01601       return -1;
01602    }
01603 
01604    return 0;
01605 }
01606 
01607 static inline int zt_set_hook(int fd, int hs)
01608 {
01609    int x, res;
01610 
01611    x = hs;
01612    res = ioctl(fd, ZT_HOOK, &x);
01613 
01614    if (res < 0) {
01615       if (errno == EINPROGRESS)
01616          return 0;
01617       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01618    }
01619 
01620    return res;
01621 }
01622 
01623 static inline int zt_confmute(struct zt_pvt *p, int muted)
01624 {
01625    int x, y, res;
01626    x = muted;
01627    if (p->sig == SIG_PRI) {
01628       y = 1;
01629       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01630       if (res)
01631          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01632    }
01633    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01634    if (res < 0)
01635       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01636    return res;
01637 }
01638 
01639 static int save_conference(struct zt_pvt *p)
01640 {
01641    struct zt_confinfo c;
01642    int res;
01643    if (p->saveconf.confmode) {
01644       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01645       return -1;
01646    }
01647    p->saveconf.chan = 0;
01648    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01649    if (res) {
01650       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01651       p->saveconf.confmode = 0;
01652       return -1;
01653    }
01654    c.chan = 0;
01655    c.confno = 0;
01656    c.confmode = ZT_CONF_NORMAL;
01657    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01658    if (res) {
01659       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01660       return -1;
01661    }
01662    if (option_debug)
01663       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01664    return 0;
01665 }
01666 
01667 static int restore_conference(struct zt_pvt *p)
01668 {
01669    int res;
01670    if (p->saveconf.confmode) {
01671       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01672       p->saveconf.confmode = 0;
01673       if (res) {
01674          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01675          return -1;
01676       }
01677    }
01678    if (option_debug)
01679       ast_log(LOG_DEBUG, "Restored conferencing\n");
01680    return 0;
01681 }
01682 
01683 static int send_callerid(struct zt_pvt *p);
01684 
01685 static int send_cwcidspill(struct zt_pvt *p)
01686 {
01687    p->callwaitcas = 0;
01688    p->cidcwexpire = 0;
01689    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01690       return -1;
01691    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01692    /* Make sure we account for the end */
01693    p->cidlen += READ_SIZE * 4;
01694    p->cidpos = 0;
01695    send_callerid(p);
01696    if (option_verbose > 2)
01697       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01698    return 0;
01699 }
01700 
01701 static int has_voicemail(struct zt_pvt *p)
01702 {
01703 
01704    return ast_app_has_voicemail(p->mailbox, NULL);
01705 }
01706 
01707 static int send_callerid(struct zt_pvt *p)
01708 {
01709    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01710    int res;
01711    /* Take out of linear mode if necessary */
01712    if (p->subs[SUB_REAL].linear) {
01713       p->subs[SUB_REAL].linear = 0;
01714       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01715    }
01716    while (p->cidpos < p->cidlen) {
01717       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01718       if (res < 0) {
01719          if (errno == EAGAIN)
01720             return 0;
01721          else {
01722             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01723             return -1;
01724          }
01725       }
01726       if (!res)
01727          return 0;
01728       p->cidpos += res;
01729    }
01730    free(p->cidspill);
01731    p->cidspill = NULL;
01732    if (p->callwaitcas) {
01733       /* Wait for CID/CW to expire */
01734       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01735    } else
01736       restore_conference(p);
01737    return 0;
01738 }
01739 
01740 static int zt_callwait(struct ast_channel *ast)
01741 {
01742    struct zt_pvt *p = ast->tech_pvt;
01743    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01744    if (p->cidspill) {
01745       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01746       free(p->cidspill);
01747    }
01748    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01749       return -1;
01750    save_conference(p);
01751    /* Silence */
01752    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01753    if (!p->callwaitrings && p->callwaitingcallerid) {
01754       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01755       p->callwaitcas = 1;
01756       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01757    } else {
01758       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01759       p->callwaitcas = 0;
01760       p->cidlen = 2400 + READ_SIZE * 4;
01761    }
01762    p->cidpos = 0;
01763    send_callerid(p);
01764    
01765    return 0;
01766 }
01767 
01768 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01769 {
01770    struct zt_pvt *p = ast->tech_pvt;
01771    int x, res, index,mysig;
01772    char *c, *n, *l;
01773 #ifdef HAVE_PRI
01774    char *s = NULL;
01775 #endif
01776    char dest[256]; /* must be same length as p->dialdest */
01777    ast_mutex_lock(&p->lock);
01778    ast_copy_string(dest, rdest, sizeof(dest));
01779    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01780    if ((ast->_state == AST_STATE_BUSY)) {
01781       p->subs[SUB_REAL].needbusy = 1;
01782       ast_mutex_unlock(&p->lock);
01783       return 0;
01784    }
01785    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01786       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01787       ast_mutex_unlock(&p->lock);
01788       return -1;
01789    }
01790    p->dialednone = 0;
01791    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01792    {
01793       /* Special pseudo -- automatically up */
01794       ast_setstate(ast, AST_STATE_UP); 
01795       ast_mutex_unlock(&p->lock);
01796       return 0;
01797    }
01798    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01799    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01800    if (res)
01801       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01802    p->outgoing = 1;
01803 
01804    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01805 
01806    mysig = p->sig;
01807    if (p->outsigmod > -1)
01808       mysig = p->outsigmod;
01809 
01810    switch (mysig) {
01811    case SIG_FXOLS:
01812    case SIG_FXOGS:
01813    case SIG_FXOKS:
01814       if (p->owner == ast) {
01815          /* Normal ring, on hook */
01816          
01817          /* Don't send audio while on hook, until the call is answered */
01818          p->dialing = 1;
01819          if (p->use_callerid) {
01820             /* Generate the Caller-ID spill if desired */
01821             if (p->cidspill) {
01822                ast_log(LOG_WARNING, "cidspill already exists??\n");
01823                free(p->cidspill);
01824             }
01825             p->callwaitcas = 0;
01826             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01827                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01828                p->cidpos = 0;
01829                send_callerid(p);
01830             }
01831          }
01832          /* Choose proper cadence */
01833          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01834             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01835                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01836             p->cidrings = cidrings[p->distinctivering - 1];
01837          } else {
01838             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01839                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01840             p->cidrings = p->sendcalleridafter;
01841          }
01842 
01843          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01844          c = strchr(dest, '/');
01845          if (c)
01846             c++;
01847          if (c && (strlen(c) < p->stripmsd)) {
01848             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01849             c = NULL;
01850          }
01851          if (c) {
01852             p->dop.op = ZT_DIAL_OP_REPLACE;
01853             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01854             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01855          } else {
01856             p->dop.dialstr[0] = '\0';
01857          }
01858          x = ZT_RING;
01859          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01860             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01861             ast_mutex_unlock(&p->lock);
01862             return -1;
01863          }
01864          p->dialing = 1;
01865       } else {
01866          /* Call waiting call */
01867          p->callwaitrings = 0;
01868          if (ast->cid.cid_num)
01869             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01870          else
01871             p->callwait_num[0] = '\0';
01872          if (ast->cid.cid_name)
01873             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01874          else
01875             p->callwait_name[0] = '\0';
01876          /* Call waiting tone instead */
01877          if (zt_callwait(ast)) {
01878             ast_mutex_unlock(&p->lock);
01879             return -1;
01880          }
01881          /* Make ring-back */
01882          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01883             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01884             
01885       }
01886       n = ast->cid.cid_name;
01887       l = ast->cid.cid_num;
01888       if (l)
01889          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01890       else
01891          p->lastcid_num[0] = '\0';
01892       if (n)
01893          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01894       else
01895          p->lastcid_name[0] = '\0';
01896       ast_setstate(ast, AST_STATE_RINGING);
01897       index = zt_get_index(ast, p, 0);
01898       if (index > -1) {
01899          p->subs[index].needringing = 1;
01900       }
01901       break;
01902    case SIG_FXSLS:
01903    case SIG_FXSGS:
01904    case SIG_FXSKS:
01905    case SIG_EMWINK:
01906    case SIG_EM:
01907    case SIG_EM_E1:
01908    case SIG_FEATD:
01909    case SIG_FEATDMF:
01910    case SIG_E911:
01911    case SIG_FGC_CAMA:
01912    case SIG_FGC_CAMAMF:
01913    case SIG_FEATB:
01914    case SIG_SFWINK:
01915    case SIG_SF:
01916    case SIG_SF_FEATD:
01917    case SIG_SF_FEATDMF:
01918    case SIG_FEATDMF_TA:
01919    case SIG_SF_FEATB:
01920       c = strchr(dest, '/');
01921       if (c)
01922          c++;
01923       else
01924          c = "";
01925       if (strlen(c) < p->stripmsd) {
01926          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01927          ast_mutex_unlock(&p->lock);
01928          return -1;
01929       }
01930 #ifdef HAVE_PRI
01931       /* Start the trunk, if not GR-303 */
01932       if (!p->pri) {
01933 #endif
01934          x = ZT_START;
01935          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01936          if (res < 0) {
01937             if (errno != EINPROGRESS) {
01938                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01939                ast_mutex_unlock(&p->lock);
01940                return -1;
01941             }
01942          }
01943 #ifdef HAVE_PRI
01944       }
01945 #endif
01946       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01947       p->dop.op = ZT_DIAL_OP_REPLACE;
01948 
01949       c += p->stripmsd;
01950 
01951       switch (mysig) {
01952       case SIG_FEATD:
01953          l = ast->cid.cid_num;
01954          if (l) 
01955             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01956          else
01957             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01958          break;
01959       case SIG_FEATDMF:
01960          l = ast->cid.cid_num;
01961          if (l) 
01962             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01963          else
01964             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01965          break;
01966       case SIG_FEATDMF_TA:
01967       {
01968          const char *cic, *ozz;
01969 
01970          /* If you have to go through a Tandem Access point you need to use this */
01971          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01972          if (!ozz)
01973             ozz = defaultozz;
01974          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01975          if (!cic)
01976             cic = defaultcic;
01977          if (!ozz || !cic) {
01978             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01979             ast_mutex_unlock(&p->lock);
01980             return -1;
01981          }
01982          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01983          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01984          p->whichwink = 0;
01985       }
01986          break;
01987       case SIG_E911:
01988          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01989          break;
01990       case SIG_FGC_CAMA:
01991          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
01992          break;
01993       case SIG_FGC_CAMAMF:
01994       case SIG_FEATB:
01995          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01996          break;
01997       default:
01998          if (p->pulse)
01999             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02000          else
02001             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02002          break;
02003       }
02004 
02005       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02006          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02007          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02008          p->echorest[sizeof(p->echorest) - 1] = '\0';
02009          p->echobreak = 1;
02010          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02011       } else
02012          p->echobreak = 0;
02013       if (!res) {
02014          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02015             x = ZT_ONHOOK;
02016             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02017             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02018             ast_mutex_unlock(&p->lock);
02019             return -1;
02020          }
02021       } else
02022          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02023       p->dialing = 1;
02024       if (ast_strlen_zero(c))
02025          p->dialednone = 1;
02026       ast_setstate(ast, AST_STATE_DIALING);
02027       break;
02028    case 0:
02029       /* Special pseudo -- automatically up*/
02030       ast_setstate(ast, AST_STATE_UP);
02031       break;      
02032    case SIG_PRI:
02033       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02034       p->dialdest[0] = '\0';
02035       break;
02036    default:
02037       ast_log(LOG_DEBUG, "not yet implemented\n");
02038       ast_mutex_unlock(&p->lock);
02039       return -1;
02040    }
02041 #ifdef HAVE_PRI
02042    if (p->pri) {
02043       struct pri_sr *sr;
02044 #ifdef SUPPORT_USERUSER
02045       const char *useruser;
02046 #endif
02047       int pridialplan;
02048       int dp_strip;
02049       int prilocaldialplan;
02050       int ldp_strip;
02051       int exclusive;
02052       const char *rr_str;
02053       int redirect_reason;
02054 
02055       c = strchr(dest, '/');
02056       if (c)
02057          c++;
02058       else
02059          c = dest;
02060       if (!p->hidecalleridname)
02061          n = ast->cid.cid_name;
02062       else
02063          n = NULL;
02064       if (!p->hidecallerid) {
02065          l = ast->cid.cid_num;
02066          n = ast->cid.cid_name;
02067       } else {
02068          l = NULL;
02069          n = NULL;
02070       }
02071       if (strlen(c) < p->stripmsd) {
02072          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02073          ast_mutex_unlock(&p->lock);
02074          return -1;
02075       }
02076       if (mysig != SIG_FXSKS) {
02077          p->dop.op = ZT_DIAL_OP_REPLACE;
02078          s = strchr(c + p->stripmsd, 'w');
02079          if (s) {
02080             if (strlen(s) > 1)
02081                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02082             else
02083                p->dop.dialstr[0] = '\0';
02084             *s = '\0';
02085          } else {
02086             p->dop.dialstr[0] = '\0';
02087          }
02088       }
02089       if (pri_grab(p, p->pri)) {
02090          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02091          ast_mutex_unlock(&p->lock);
02092          return -1;
02093       }
02094       if (!(p->call = pri_new_call(p->pri->pri))) {
02095          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02096          pri_rel(p->pri);
02097          ast_mutex_unlock(&p->lock);
02098          return -1;
02099       }
02100       if (!(sr = pri_sr_new())) {
02101          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02102          pri_rel(p->pri);
02103          ast_mutex_unlock(&p->lock);
02104       }
02105       if (p->bearer || (mysig == SIG_FXSKS)) {
02106          if (p->bearer) {
02107             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);
02108             p->bearer->call = p->call;
02109          } else
02110             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02111          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02112       }
02113       p->digital = IS_DIGITAL(ast->transfercapability);
02114       /* Add support for exclusive override */
02115       if (p->priexclusive)
02116          exclusive = 1;
02117       else {
02118       /* otherwise, traditional behavior */
02119          if (p->pri->nodetype == PRI_NETWORK)
02120             exclusive = 0;
02121          else
02122             exclusive = 1;
02123       }
02124       
02125       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02126       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02127                (p->digital ? -1 : 
02128                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02129       if (p->pri->facilityenable)
02130          pri_facility_enable(p->pri->pri);
02131 
02132       if (option_verbose > 2)
02133          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02134       dp_strip = 0;
02135       pridialplan = p->pri->dialplan - 1;
02136       if (pridialplan == -2) { /* compute dynamically */
02137          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02138             dp_strip = strlen(p->pri->internationalprefix);
02139             pridialplan = PRI_INTERNATIONAL_ISDN;
02140          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02141             dp_strip = strlen(p->pri->nationalprefix);
02142             pridialplan = PRI_NATIONAL_ISDN;
02143          } else {
02144             pridialplan = PRI_LOCAL_ISDN;
02145          }
02146       }
02147       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02148 
02149       ldp_strip = 0;
02150       prilocaldialplan = p->pri->localdialplan - 1;
02151       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02152          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02153             ldp_strip = strlen(p->pri->internationalprefix);
02154             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02155          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02156             ldp_strip = strlen(p->pri->nationalprefix);
02157             prilocaldialplan = PRI_NATIONAL_ISDN;
02158          } else {
02159             prilocaldialplan = PRI_LOCAL_ISDN;
02160          }
02161       }
02162       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02163          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02164       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02165          if (!strcasecmp(rr_str, "UNKNOWN"))
02166             redirect_reason = 0;
02167          else if (!strcasecmp(rr_str, "BUSY"))
02168             redirect_reason = 1;
02169          else if (!strcasecmp(rr_str, "NO_REPLY"))
02170             redirect_reason = 2;
02171          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02172             redirect_reason = 15;
02173          else
02174             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02175       } else
02176          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02177       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02178 
02179 #ifdef SUPPORT_USERUSER
02180       /* User-user info */
02181       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02182 
02183       if (useruser)
02184          pri_sr_set_useruser(sr, useruser);
02185 #endif
02186 
02187       if (pri_setup(p->pri->pri, p->call, sr)) {
02188          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02189             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02190          pri_rel(p->pri);
02191          ast_mutex_unlock(&p->lock);
02192          pri_sr_free(sr);
02193          return -1;
02194       }
02195       pri_sr_free(sr);
02196       ast_setstate(ast, AST_STATE_DIALING);
02197       pri_rel(p->pri);
02198    }
02199 #endif      
02200    ast_mutex_unlock(&p->lock);
02201    return 0;
02202 }
02203 
02204 static void destroy_zt_pvt(struct zt_pvt **pvt)
02205 {
02206    struct zt_pvt *p = *pvt;
02207    /* Remove channel from the list */
02208    if (p->prev)
02209       p->prev->next = p->next;
02210    if (p->next)
02211       p->next->prev = p->prev;
02212    if (p->use_smdi)
02213       ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
02214    ast_mutex_destroy(&p->lock);
02215    free(p);
02216    *pvt = NULL;
02217 }
02218 
02219 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02220 {
02221    int owned = 0;
02222    int i = 0;
02223 
02224    if (!now) {
02225       if (cur->owner) {
02226          owned = 1;
02227       }
02228 
02229       for (i = 0; i < 3; i++) {
02230          if (cur->subs[i].owner) {
02231             owned = 1;
02232          }
02233       }
02234       if (!owned) {
02235          if (prev) {
02236             prev->next = cur->next;
02237             if (prev->next)
02238                prev->next->prev = prev;
02239             else
02240                ifend = prev;
02241          } else {
02242             iflist = cur->next;
02243             if (iflist)
02244                iflist->prev = NULL;
02245             else
02246                ifend = NULL;
02247          }
02248          if (cur->subs[SUB_REAL].zfd > -1) {
02249             zt_close(cur->subs[SUB_REAL].zfd);
02250          }
02251          destroy_zt_pvt(&cur);
02252       }
02253    } else {
02254       if (prev) {
02255          prev->next = cur->next;
02256          if (prev->next)
02257             prev->next->prev = prev;
02258          else
02259             ifend = prev;
02260       } else {
02261          iflist = cur->next;
02262          if (iflist)
02263             iflist->prev = NULL;
02264          else
02265             ifend = NULL;
02266       }
02267       if (cur->subs[SUB_REAL].zfd > -1) {
02268          zt_close(cur->subs[SUB_REAL].zfd);
02269       }
02270       destroy_zt_pvt(&cur);
02271    }
02272    return 0;
02273 }
02274 
02275 #ifdef HAVE_PRI
02276 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02277 
02278 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02279 
02280 static char *zap_send_keypad_facility_descrip = 
02281 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02282 "  IE over the current channel.\n";
02283 
02284 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02285 {
02286    /* Data will be our digit string */
02287    struct zt_pvt *p;
02288    char *digits = (char *) data;
02289 
02290    if (ast_strlen_zero(digits)) {
02291       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02292       return -1;
02293    }
02294 
02295    p = (struct zt_pvt *)chan->tech_pvt;
02296 
02297    if (!p) {
02298       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02299       return -1;
02300    }
02301 
02302    ast_mutex_lock(&p->lock);
02303 
02304    if (!p->pri || !p->call) {
02305       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02306       ast_mutex_unlock(&p->lock);
02307       return -1;
02308    }
02309 
02310    if (!pri_grab(p, p->pri)) {
02311       pri_keypad_facility(p->pri->pri, p->call, digits);
02312       pri_rel(p->pri);
02313    } else {
02314       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02315       ast_mutex_unlock(&p->lock);
02316       return -1;
02317    }
02318 
02319    ast_mutex_unlock(&p->lock);
02320 
02321    return 0;
02322 }
02323 
02324 static int pri_is_up(struct zt_pri *pri)
02325 {
02326    int x;
02327    for (x = 0; x < NUM_DCHANS; x++) {
02328       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02329          return 1;
02330    }
02331    return 0;
02332 }
02333 
02334 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02335 {
02336    bearer->owner = &inuse;
02337    bearer->realcall = crv;
02338    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02339    if (crv->subs[SUB_REAL].owner)
02340       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02341    crv->bearer = bearer;
02342    crv->call = bearer->call;
02343    crv->pri = pri;
02344    return 0;
02345 }
02346 
02347 static char *pri_order(int level)
02348 {
02349    switch (level) {
02350    case 0:
02351       return "Primary";
02352    case 1:
02353       return "Secondary";
02354    case 2:
02355       return "Tertiary";
02356    case 3:
02357       return "Quaternary";
02358    default:
02359       return "<Unknown>";
02360    }     
02361 }
02362 
02363 /* Returns fd of the active dchan */
02364 static int pri_active_dchan_fd(struct zt_pri *pri)
02365 {
02366    int x = -1;
02367 
02368    for (x = 0; x < NUM_DCHANS; x++) {
02369       if ((pri->dchans[x] == pri->pri))
02370          break;
02371    }
02372 
02373    return pri->fds[x];
02374 }
02375 
02376 static int pri_find_dchan(struct zt_pri *pri)
02377 {
02378    int oldslot = -1;
02379    struct pri *old;
02380    int newslot = -1;
02381    int x;
02382    old = pri->pri;
02383    for (x = 0; x < NUM_DCHANS; x++) {
02384       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02385          newslot = x;
02386       if (pri->dchans[x] == old) {
02387          oldslot = x;
02388       }
02389    }
02390    if (newslot < 0) {
02391       newslot = 0;
02392       ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02393          pri->dchannels[newslot]);
02394    }
02395    if (old && (oldslot != newslot))
02396       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02397          pri->dchannels[oldslot], pri->dchannels[newslot]);
02398    pri->pri = pri->dchans[newslot];
02399    return 0;
02400 }
02401 #endif
02402 
02403 static int zt_hangup(struct ast_channel *ast)
02404 {
02405    int res;
02406    int index,x, law;
02407    /*static int restore_gains(struct zt_pvt *p);*/
02408    struct zt_pvt *p = ast->tech_pvt;
02409    struct zt_pvt *tmp = NULL;
02410    struct zt_pvt *prev = NULL;
02411    ZT_PARAMS par;
02412 
02413    if (option_debug)
02414       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02415    if (!ast->tech_pvt) {
02416       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02417       return 0;
02418    }
02419    
02420    ast_mutex_lock(&p->lock);
02421    
02422    index = zt_get_index(ast, p, 1);
02423 
02424    if (p->sig == SIG_PRI) {
02425       x = 1;
02426       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02427    }
02428 
02429    x = 0;
02430    zt_confmute(p, 0);
02431    restore_gains(p);
02432    if (p->origcid_num) {
02433       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02434       free(p->origcid_num);
02435       p->origcid_num = NULL;
02436    }  
02437    if (p->origcid_name) {
02438       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02439       free(p->origcid_name);
02440       p->origcid_name = NULL;
02441    }  
02442    if (p->dsp)
02443       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02444    if (p->exten)
02445       p->exten[0] = '\0';
02446 
02447    if (option_debug)
02448       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02449       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02450    p->ignoredtmf = 0;
02451    
02452    if (index > -1) {
02453       /* Real channel, do some fixup */
02454       p->subs[index].owner = NULL;
02455       p->subs[index].needanswer = 0;
02456       p->subs[index].needflash = 0;
02457       p->subs[index].needringing = 0;
02458       p->subs[index].needbusy = 0;
02459       p->subs[index].needcongestion = 0;
02460       p->subs[index].linear = 0;
02461       p->subs[index].needcallerid = 0;
02462       p->polarity = POLARITY_IDLE;
02463       zt_setlinear(p->subs[index].zfd, 0);
02464       if (index == SUB_REAL) {
02465          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02466             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02467             if (p->subs[SUB_CALLWAIT].inthreeway) {
02468                /* We had flipped over to answer a callwait and now it's gone */
02469                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02470                /* Move to the call-wait, but un-own us until they flip back. */
02471                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02472                unalloc_sub(p, SUB_CALLWAIT);
02473                p->owner = NULL;
02474             } else {
02475                /* The three way hung up, but we still have a call wait */
02476                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02477                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02478                unalloc_sub(p, SUB_THREEWAY);
02479                if (p->subs[SUB_REAL].inthreeway) {
02480                   /* This was part of a three way call.  Immediately make way for
02481                      another call */
02482                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02483                   p->owner = p->subs[SUB_REAL].owner;
02484                } else {
02485                   /* This call hasn't been completed yet...  Set owner to NULL */
02486                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02487                   p->owner = NULL;
02488                }
02489                p->subs[SUB_REAL].inthreeway = 0;
02490             }
02491          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02492             /* Move to the call-wait and switch back to them. */
02493             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02494             unalloc_sub(p, SUB_CALLWAIT);
02495             p->owner = p->subs[SUB_REAL].owner;
02496             if (p->owner->_state != AST_STATE_UP)
02497                p->subs[SUB_REAL].needanswer = 1;
02498             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02499                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02500          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02501             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02502             unalloc_sub(p, SUB_THREEWAY);
02503             if (p->subs[SUB_REAL].inthreeway) {
02504                /* This was part of a three way call.  Immediately make way for
02505                   another call */
02506                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02507                p->owner = p->subs[SUB_REAL].owner;
02508             } else {
02509                /* This call hasn't been completed yet...  Set owner to NULL */
02510                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02511                p->owner = NULL;
02512             }
02513             p->subs[SUB_REAL].inthreeway = 0;
02514          }
02515       } else if (index == SUB_CALLWAIT) {
02516          /* Ditch the holding callwait call, and immediately make it availabe */
02517          if (p->subs[SUB_CALLWAIT].inthreeway) {
02518             /* This is actually part of a three way, placed on hold.  Place the third part
02519                on music on hold now */
02520             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02521                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02522                   S_OR(p->mohsuggest, NULL),
02523                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02524             }
02525             p->subs[SUB_THREEWAY].inthreeway = 0;
02526             /* Make it the call wait now */
02527             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02528             unalloc_sub(p, SUB_THREEWAY);
02529          } else
02530             unalloc_sub(p, SUB_CALLWAIT);
02531       } else if (index == SUB_THREEWAY) {
02532          if (p->subs[SUB_CALLWAIT].inthreeway) {
02533             /* The other party of the three way call is currently in a call-wait state.
02534                Start music on hold for them, and take the main guy out of the third call */
02535             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02536                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02537                   S_OR(p->mohsuggest, NULL),
02538                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02539             }
02540             p->subs[SUB_CALLWAIT].inthreeway = 0;
02541          }
02542          p->subs[SUB_REAL].inthreeway = 0;
02543          /* If this was part of a three way call index, let us make
02544             another three way call */
02545          unalloc_sub(p, SUB_THREEWAY);
02546       } else {
02547          /* This wasn't any sort of call, but how are we an index? */
02548          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02549       }
02550    }
02551 
02552    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02553       p->owner = NULL;
02554       p->ringt = 0;
02555       p->distinctivering = 0;
02556       p->confirmanswer = 0;
02557       p->cidrings = 1;
02558       p->outgoing = 0;
02559       p->digital = 0;
02560       p->faxhandled = 0;
02561       p->pulsedial = 0;
02562       p->onhooktime = time(NULL);
02563 #ifdef HAVE_PRI
02564       p->proceeding = 0;
02565       p->progress = 0;
02566       p->alerting = 0;
02567       p->setup_ack = 0;
02568 #endif      
02569       if (p->dsp) {
02570          ast_dsp_free(p->dsp);
02571          p->dsp = NULL;
02572       }
02573 
02574       law = ZT_LAW_DEFAULT;
02575       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02576       if (res < 0) 
02577          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02578       /* Perform low level hangup if no owner left */
02579 #ifdef HAVE_PRI
02580       if (p->pri) {
02581 #ifdef SUPPORT_USERUSER
02582          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02583 #endif
02584 
02585          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02586          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02587             if (!pri_grab(p, p->pri)) {
02588                if (p->alreadyhungup) {
02589                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02590 
02591 #ifdef SUPPORT_USERUSER
02592                   pri_call_set_useruser(p->call, useruser);
02593 #endif
02594 
02595                   pri_hangup(p->pri->pri, p->call, -1);
02596                   p->call = NULL;
02597                   if (p->bearer) 
02598                      p->bearer->call = NULL;
02599                } else {
02600                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02601                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02602                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02603 
02604 #ifdef SUPPORT_USERUSER
02605                   pri_call_set_useruser(p->call, useruser);
02606 #endif
02607 
02608                   p->alreadyhungup = 1;
02609                   if (p->bearer)
02610                      p->bearer->alreadyhungup = 1;
02611                   if (cause) {
02612                      if (atoi(cause))
02613                         icause = atoi(cause);
02614                   }
02615                   pri_hangup(p->pri->pri, p->call, icause);
02616                }
02617                if (res < 0) 
02618                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02619                pri_rel(p->pri);        
02620             } else {
02621                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02622                res = -1;
02623             }
02624          } else {
02625             if (p->bearer)
02626                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02627             p->call = NULL;
02628             res = 0;
02629          }
02630       }
02631 #endif
02632       if (p->sig && (p->sig != SIG_PRI))
02633          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02634       if (res < 0) {
02635          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02636       }
02637       switch (p->sig) {
02638       case SIG_FXOGS:
02639       case SIG_FXOLS:
02640       case SIG_FXOKS:
02641          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02642          if (!res) {
02643 #if 0
02644             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02645 #endif
02646             /* If they're off hook, try playing congestion */
02647             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02648                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02649             else
02650                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02651          }
02652          break;
02653       case SIG_FXSGS:
02654       case SIG_FXSLS:
02655       case SIG_FXSKS:
02656          /* Make sure we're not made available for at least two seconds assuming
02657             we were actually used for an inbound or outbound call. */
02658          if (ast->_state != AST_STATE_RESERVED) {
02659             time(&p->guardtime);
02660             p->guardtime += 2;
02661          }
02662          break;
02663       default:
02664          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02665       }
02666       if (p->cidspill)
02667          free(p->cidspill);
02668       if (p->sig)
02669          zt_disable_ec(p);
02670       x = 0;
02671       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02672       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02673       p->didtdd = 0;
02674       p->cidspill = NULL;
02675       p->callwaitcas = 0;
02676       p->callwaiting = p->permcallwaiting;
02677       p->hidecallerid = p->permhidecallerid;
02678       p->dialing = 0;
02679       p->rdnis[0] = '\0';
02680       update_conf(p);
02681       reset_conf(p);
02682       /* Restore data mode */
02683       if (p->sig == SIG_PRI) {
02684          x = 0;
02685          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02686       }
02687 #ifdef HAVE_PRI
02688       if (p->bearer) {
02689          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02690          /* Free up the bearer channel as well, and
02691             don't use its file descriptor anymore */
02692          update_conf(p->bearer);
02693          reset_conf(p->bearer);
02694          p->bearer->owner = NULL;
02695          p->bearer->realcall = NULL;
02696          p->bearer = NULL;
02697          p->subs[SUB_REAL].zfd = -1;
02698          p->pri = NULL;
02699       }
02700 #endif
02701       restart_monitor();
02702    }
02703 
02704    p->callwaitingrepeat = 0;
02705    p->cidcwexpire = 0;
02706    p->oprmode = 0;
02707    ast->tech_pvt = NULL;
02708    ast_mutex_unlock(&p->lock);
02709    ast_module_unref(ast_module_info->self);
02710    if (option_verbose > 2) 
02711       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02712 
02713    ast_mutex_lock(&iflock);
02714    tmp = iflist;
02715    prev = NULL;
02716    if (p->destroy) {
02717       while (tmp) {
02718          if (tmp == p) {
02719             destroy_channel(prev, tmp, 0);
02720             break;
02721          } else {
02722             prev = tmp;
02723             tmp = tmp->next;
02724          }
02725       }
02726    }
02727    ast_mutex_unlock(&iflock);
02728    return 0;
02729 }
02730 
02731 static int zt_answer(struct ast_channel *ast)
02732 {
02733    struct zt_pvt *p = ast->tech_pvt;
02734    int res = 0;
02735    int index;
02736    int oldstate = ast->_state;
02737    ast_setstate(ast, AST_STATE_UP);
02738    ast_mutex_lock(&p->lock);
02739    index = zt_get_index(ast, p, 0);
02740    if (index < 0)
02741       index = SUB_REAL;
02742    /* nothing to do if a radio channel */
02743    if ((p->radio || (p->oprmode < 0))) {
02744       ast_mutex_unlock(&p->lock);
02745       return 0;
02746    }
02747    switch (p->sig) {
02748    case SIG_FXSLS:
02749    case SIG_FXSGS:
02750    case SIG_FXSKS:
02751       p->ringt = 0;
02752       /* Fall through */
02753    case SIG_EM:
02754    case SIG_EM_E1:
02755    case SIG_EMWINK:
02756    case SIG_FEATD:
02757    case SIG_FEATDMF:
02758    case SIG_FEATDMF_TA:
02759    case SIG_E911:
02760    case SIG_FGC_CAMA:
02761    case SIG_FGC_CAMAMF:
02762    case SIG_FEATB:
02763    case SIG_SF:
02764    case SIG_SFWINK:
02765    case SIG_SF_FEATD:
02766    case SIG_SF_FEATDMF:
02767    case SIG_SF_FEATB:
02768    case SIG_FXOLS:
02769    case SIG_FXOGS:
02770    case SIG_FXOKS:
02771       /* Pick up the line */
02772       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02773       if (p->hanguponpolarityswitch) {
02774          gettimeofday(&p->polaritydelaytv, NULL);
02775       }
02776       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02777       tone_zone_play_tone(p->subs[index].zfd, -1);
02778       p->dialing = 0;
02779       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02780          if (oldstate == AST_STATE_RINGING) {
02781             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02782             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02783             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02784             p->owner = p->subs[SUB_REAL].owner;
02785          }
02786       }
02787       if (p->sig & __ZT_SIG_FXS) {
02788          zt_enable_ec(p);
02789          zt_train_ec(p);
02790       }
02791       break;
02792 #ifdef HAVE_PRI
02793    case SIG_PRI:
02794       /* Send a pri acknowledge */
02795       if (!pri_grab(p, p->pri)) {
02796          p->proceeding = 1;
02797          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02798          pri_rel(p->pri);
02799       } else {
02800          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02801          res = -1;
02802       }
02803       break;
02804 #endif
02805    case 0:
02806       ast_mutex_unlock(&p->lock);
02807       return 0;
02808    default:
02809       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02810       res = -1;
02811    }
02812    ast_mutex_unlock(&p->lock);
02813    return res;
02814 }
02815 
02816 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02817 {
02818    char *cp;
02819    signed char *scp;
02820    int x;
02821    int index;
02822    struct zt_pvt *p = chan->tech_pvt, *pp;
02823    struct oprmode *oprmode;
02824    
02825 
02826    /* all supported options require data */
02827    if (!data || (datalen < 1)) {
02828       errno = EINVAL;
02829       return -1;
02830    }
02831 
02832    switch (option) {
02833    case AST_OPTION_TXGAIN:
02834       scp = (signed char *) data;
02835       index = zt_get_index(chan, p, 0);
02836       if (index < 0) {
02837          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02838          return -1;
02839       }
02840       if (option_debug)
02841          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02842       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02843    case AST_OPTION_RXGAIN:
02844       scp = (signed char *) data;
02845       index = zt_get_index(chan, p, 0);
02846       if (index < 0) {
02847          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02848          return -1;
02849       }
02850       if (option_debug)
02851          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02852       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02853    case AST_OPTION_TONE_VERIFY:
02854       if (!p->dsp)
02855          break;
02856       cp = (char *) data;
02857       switch (*cp) {
02858       case 1:
02859          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02860          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02861          break;
02862       case 2:
02863          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02864          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02865          break;
02866       default:
02867          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02868          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02869          break;
02870       }
02871       break;
02872    case AST_OPTION_TDD:
02873       /* turn on or off TDD */
02874       cp = (char *) data;
02875       p->mate = 0;
02876       if (!*cp) { /* turn it off */
02877          if (option_debug)
02878             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02879          if (p->tdd)
02880             tdd_free(p->tdd);
02881          p->tdd = 0;
02882          break;
02883       }
02884       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02885          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02886       zt_disable_ec(p);
02887       /* otherwise, turn it on */
02888       if (!p->didtdd) { /* if havent done it yet */
02889          unsigned char mybuf[41000], *buf;
02890          int size, res, fd, len;
02891          struct pollfd fds[1];
02892 
02893          buf = mybuf;
02894          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02895          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02896          len = 40000;
02897          index = zt_get_index(chan, p, 0);
02898          if (index < 0) {
02899             ast_log(LOG_WARNING, "No index in TDD?\n");
02900             return -1;
02901          }
02902          fd = p->subs[index].zfd;
02903          while (len) {
02904             if (ast_check_hangup(chan))
02905                return -1;
02906             size = len;
02907             if (size > READ_SIZE)
02908                size = READ_SIZE;
02909             fds[0].fd = fd;
02910             fds[0].events = POLLPRI | POLLOUT;
02911             fds[0].revents = 0;
02912             res = poll(fds, 1, -1);
02913             if (!res) {
02914                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02915                continue;
02916             }
02917             /* if got exception */
02918             if (fds[0].revents & POLLPRI)
02919                return -1;
02920             if (!(fds[0].revents & POLLOUT)) {
02921                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02922                continue;
02923             }
02924             res = write(fd, buf, size);
02925             if (res != size) {
02926                if (res == -1) return -1;
02927                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02928                break;
02929             }
02930             len -= size;
02931             buf += size;
02932          }
02933          p->didtdd = 1; /* set to have done it now */    
02934       }
02935       if (*cp == 2) { /* Mate mode */
02936          if (p->tdd)
02937             tdd_free(p->tdd);
02938          p->tdd = 0;
02939          p->mate = 1;
02940          break;
02941       }     
02942       if (!p->tdd) { /* if we dont have one yet */
02943          p->tdd = tdd_new(); /* allocate one */
02944       }     
02945       break;
02946    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02947       if (!p->dsp)
02948          break;
02949       cp = (char *) data;
02950       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02951          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02952                 p->dtmfrelax = 0;
02953                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
02954                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
02955       break;
02956    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02957       cp = (char *) data;
02958       if (!*cp) {    
02959          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02960          x = 0;
02961          zt_disable_ec(p);
02962       } else {    
02963          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02964          x = 1;
02965       }
02966       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02967          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02968       break;
02969    case AST_OPTION_OPRMODE:  /* Operator services mode */
02970       oprmode = (struct oprmode *) data;
02971       pp = oprmode->peer->tech_pvt;
02972       p->oprmode = pp->oprmode = 0;
02973       /* setup peers */
02974       p->oprpeer = pp;
02975       pp->oprpeer = p;
02976       /* setup modes, if any */
02977       if (oprmode->mode) 
02978       {
02979          pp->oprmode = oprmode->mode;
02980          p->oprmode = -oprmode->mode;
02981       }
02982       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
02983          oprmode->mode, chan->name,oprmode->peer->name);;
02984       break;
02985    case AST_OPTION_ECHOCAN:
02986       cp = (char *) data;
02987       if (*cp) {
02988          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
02989          zt_enable_ec(p);
02990       } else {
02991          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
02992          zt_disable_ec(p);
02993       }
02994       break;
02995    }
02996    errno = 0;
02997 
02998    return 0;
02999 }
03000 
03001 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03002 {
03003    struct zt_pvt *p = chan->tech_pvt;
03004    
03005    if (!strcasecmp(data, "rxgain")) {
03006       ast_mutex_lock(&p->lock);
03007       snprintf(buf, len, "%f", p->rxgain);
03008       ast_mutex_unlock(&p->lock);   
03009    } else if (!strcasecmp(data, "txgain")) {
03010       ast_mutex_lock(&p->lock);
03011       snprintf(buf, len, "%f", p->txgain);
03012       ast_mutex_unlock(&p->lock);   
03013    } else {
03014       ast_copy_string(buf, "", len);
03015    }
03016    return 0;
03017 }
03018 
03019 
03020 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03021 {
03022    /* Unlink a specific slave or all slaves/masters from a given master */
03023    int x;
03024    int hasslaves;
03025    if (!master)
03026       return;
03027    if (needlock) {
03028       ast_mutex_lock(&master->lock);
03029       if (slave) {
03030          while (ast_mutex_trylock(&slave->lock)) {
03031             ast_mutex_unlock(&master->lock);
03032             usleep(1);
03033             ast_mutex_lock(&master->lock);
03034          }
03035       }
03036    }
03037    hasslaves = 0;
03038    for (x = 0; x < MAX_SLAVES; x++) {
03039       if (master->slaves[x]) {
03040          if (!slave || (master->slaves[x] == slave)) {
03041             /* Take slave out of the conference */
03042             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03043             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03044             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03045             master->slaves[x]->master = NULL;
03046             master->slaves[x] = NULL;
03047          } else
03048             hasslaves = 1;
03049       }
03050       if (!hasslaves)
03051          master->inconference = 0;
03052    }
03053    if (!slave) {
03054       if (master->master) {
03055          /* Take master out of the conference */
03056          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03057          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03058          hasslaves = 0;
03059          for (x = 0; x < MAX_SLAVES; x++) {
03060             if (master->master->slaves[x] == master)
03061                master->master->slaves[x] = NULL;
03062             else if (master->master->slaves[x])
03063                hasslaves = 1;
03064          }
03065          if (!hasslaves)
03066             master->master->inconference = 0;
03067       }
03068       master->master = NULL;
03069    }
03070    update_conf(master);
03071    if (needlock) {
03072       if (slave)
03073          ast_mutex_unlock(&slave->lock);
03074       ast_mutex_unlock(&master->lock);
03075    }
03076 }
03077 
03078 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03079    int x;
03080    if (!slave || !master) {
03081       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03082       return;
03083    }
03084    for (x = 0; x < MAX_SLAVES; x++) {
03085       if (!master->slaves[x]) {
03086          master->slaves[x] = slave;
03087          break;
03088       }
03089    }
03090    if (x >= MAX_SLAVES) {
03091       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03092       master->slaves[MAX_SLAVES - 1] = slave;
03093    }
03094    if (slave->master) 
03095       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03096    slave->master = master;
03097    
03098    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03099 }
03100 
03101 static void disable_dtmf_detect(struct zt_pvt *p)
03102 {
03103 #ifdef ZT_TONEDETECT
03104    int val;
03105 #endif
03106 
03107    p->ignoredtmf = 1;
03108 
03109 #ifdef ZT_TONEDETECT
03110    val = 0;
03111    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03112 #endif      
03113    if (!p->hardwaredtmf && p->dsp) {
03114       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03115       ast_dsp_set_features(p->dsp, p->dsp_features);
03116    }
03117 }
03118 
03119 static void enable_dtmf_detect(struct zt_pvt *p)
03120 {
03121 #ifdef ZT_TONEDETECT
03122    int val;
03123 #endif
03124 
03125    if (p->channel == CHAN_PSEUDO)
03126       return;
03127 
03128    p->ignoredtmf = 0;
03129 
03130 #ifdef ZT_TONEDETECT
03131    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03132    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03133 #endif      
03134    if (!p->hardwaredtmf && p->dsp) {
03135       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03136       ast_dsp_set_features(p->dsp, p->dsp_features);
03137    }
03138 }
03139 
03140 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)
03141 {
03142    struct ast_channel *who;
03143    struct zt_pvt *p0, *p1, *op0, *op1;
03144    struct zt_pvt *master = NULL, *slave = NULL;
03145    struct ast_frame *f;
03146    int inconf = 0;
03147    int nothingok = 1;
03148    int ofd0, ofd1;
03149    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03150    int os0 = -1, os1 = -1;
03151    int priority = 0;
03152    struct ast_channel *oc0, *oc1;
03153    enum ast_bridge_result res;
03154 
03155 #ifdef PRI_2BCT
03156    int triedtopribridge = 0;
03157    q931_call *q931c0 = NULL, *q931c1 = NULL;
03158 #endif
03159 
03160    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03161       There is code below to handle it properly until DTMF is actually seen,
03162       but due to currently unresolved issues it's ignored...
03163    */
03164 
03165    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03166       return AST_BRIDGE_FAILED_NOWARN;
03167 
03168    ast_mutex_lock(&c0->lock);
03169    ast_mutex_lock(&c1->lock);
03170 
03171    p0 = c0->tech_pvt;
03172    p1 = c1->tech_pvt;
03173    /* cant do pseudo-channels here */
03174    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03175       ast_mutex_unlock(&c0->lock);
03176       ast_mutex_unlock(&c1->lock);
03177       return AST_BRIDGE_FAILED_NOWARN;
03178    }
03179 
03180    oi0 = zt_get_index(c0, p0, 0);
03181    oi1 = zt_get_index(c1, p1, 0);
03182    if ((oi0 < 0) || (oi1 < 0)) {
03183       ast_mutex_unlock(&c0->lock);
03184       ast_mutex_unlock(&c1->lock);
03185       return AST_BRIDGE_FAILED;
03186    }
03187 
03188    op0 = p0 = c0->tech_pvt;
03189    op1 = p1 = c1->tech_pvt;
03190    ofd0 = c0->fds[0];
03191    ofd1 = c1->fds[0];
03192    oc0 = p0->owner;
03193    oc1 = p1->owner;
03194 
03195    if (ast_mutex_trylock(&p0->lock)) {
03196       /* Don't block, due to potential for deadlock */
03197       ast_mutex_unlock(&c0->lock);
03198       ast_mutex_unlock(&c1->lock);
03199       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03200       return AST_BRIDGE_RETRY;
03201    }
03202    if (ast_mutex_trylock(&p1->lock)) {
03203       /* Don't block, due to potential for deadlock */
03204       ast_mutex_unlock(&p0->lock);
03205       ast_mutex_unlock(&c0->lock);
03206       ast_mutex_unlock(&c1->lock);
03207       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03208       return AST_BRIDGE_RETRY;
03209    }
03210 
03211    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03212       if (p0->owner && p1->owner) {
03213          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03214          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03215             master = p0;
03216             slave = p1;
03217             inconf = 1;
03218          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03219             master = p1;
03220             slave = p0;
03221             inconf = 1;
03222          } else {
03223             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03224             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03225                p0->channel,
03226                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03227                p0->subs[SUB_REAL].inthreeway, p0->channel,
03228                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03229                p1->subs[SUB_REAL].inthreeway);
03230          }
03231          nothingok = 0;
03232       }
03233    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03234       if (p1->subs[SUB_THREEWAY].inthreeway) {
03235          master = p1;
03236          slave = p0;
03237          nothingok = 0;
03238       }
03239    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03240       if (p0->subs[SUB_THREEWAY].inthreeway) {
03241          master = p0;
03242          slave = p1;
03243          nothingok = 0;
03244       }
03245    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03246       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03247          don't put us in anything */
03248       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03249          master = p1;
03250          slave = p0;
03251          nothingok = 0;
03252       }
03253    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03254       /* Same as previous */
03255       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03256          master = p0;
03257          slave = p1;
03258          nothingok = 0;
03259       }
03260    }
03261    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03262       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03263    if (master && slave) {
03264       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03265          in an active threeway call with a channel that is ringing, we should
03266          indicate ringing. */
03267       if ((oi1 == SUB_THREEWAY) && 
03268           p1->subs[SUB_THREEWAY].inthreeway && 
03269           p1->subs[SUB_REAL].owner && 
03270           p1->subs[SUB_REAL].inthreeway && 
03271           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03272          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03273          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03274          os1 = p1->subs[SUB_REAL].owner->_state;
03275       } else {
03276          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03277          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03278       }
03279       if ((oi0 == SUB_THREEWAY) && 
03280           p0->subs[SUB_THREEWAY].inthreeway && 
03281           p0->subs[SUB_REAL].owner && 
03282           p0->subs[SUB_REAL].inthreeway && 
03283           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03284          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03285          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03286          os0 = p0->subs[SUB_REAL].owner->_state;
03287       } else {
03288          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03289          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03290       }
03291       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03292          if (!p0->echocanbridged || !p1->echocanbridged) {
03293             /* Disable echo cancellation if appropriate */
03294             zt_disable_ec(p0);
03295             zt_disable_ec(p1);
03296          }
03297       }
03298       zt_link(slave, master);
03299       master->inconference = inconf;
03300    } else if (!nothingok)
03301       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03302 
03303    update_conf(p0);
03304    update_conf(p1);
03305    t0 = p0->subs[SUB_REAL].inthreeway;
03306    t1 = p1->subs[SUB_REAL].inthreeway;
03307 
03308    ast_mutex_unlock(&p0->lock);
03309    ast_mutex_unlock(&p1->lock);
03310 
03311    ast_mutex_unlock(&c0->lock);
03312    ast_mutex_unlock(&c1->lock);
03313 
03314    /* Native bridge failed */
03315    if ((!master || !slave) && !nothingok) {
03316       zt_enable_ec(p0);
03317       zt_enable_ec(p1);
03318       return AST_BRIDGE_FAILED;
03319    }
03320    
03321    if (option_verbose > 2) 
03322       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03323 
03324    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03325       disable_dtmf_detect(op0);
03326 
03327    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03328       disable_dtmf_detect(op1);
03329 
03330    for (;;) {
03331       struct ast_channel *c0_priority[2] = {c0, c1};
03332       struct ast_channel *c1_priority[2] = {c1, c0};
03333 
03334       /* Here's our main loop...  Start by locking things, looking for private parts, 
03335          and then balking if anything is wrong */
03336       ast_mutex_lock(&c0->lock);
03337       ast_mutex_lock(&c1->lock);
03338       p0 = c0->tech_pvt;
03339       p1 = c1->tech_pvt;
03340 
03341       if (op0 == p0)
03342          i0 = zt_get_index(c0, p0, 1);
03343       if (op1 == p1)
03344          i1 = zt_get_index(c1, p1, 1);
03345       ast_mutex_unlock(&c0->lock);
03346       ast_mutex_unlock(&c1->lock);
03347 
03348       if (!timeoutms || 
03349           (op0 != p0) ||
03350           (op1 != p1) || 
03351           (ofd0 != c0->fds[0]) || 
03352           (ofd1 != c1->fds[0]) ||
03353           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03354           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03355           (oc0 != p0->owner) || 
03356           (oc1 != p1->owner) ||
03357           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03358           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03359           (oi0 != i0) ||
03360           (oi1 != i1)) {
03361          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03362             op0->channel, oi0, op1->channel, oi1);
03363          res = AST_BRIDGE_RETRY;
03364          goto return_from_bridge;
03365       }
03366 
03367 #ifdef PRI_2BCT
03368       q931c0 = p0->call;
03369       q931c1 = p1->call;
03370       if (p0->transfer && p1->transfer 
03371           && q931c0 && q931c1 
03372           && !triedtopribridge) {
03373          pri_channel_bridge(q931c0, q931c1);
03374          triedtopribridge = 1;
03375       }
03376 #endif
03377 
03378       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03379       if (!who) {
03380          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03381          continue;
03382       }
03383       f = ast_read(who);
03384       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03385          *fo = f;
03386          *rc = who;
03387          res = AST_BRIDGE_COMPLETE;
03388          goto return_from_bridge;
03389       }
03390       if (f->frametype == AST_FRAME_DTMF) {
03391          if ((who == c0) && p0->pulsedial) {
03392             ast_write(c1, f);
03393          } else if ((who == c1) && p1->pulsedial) {
03394             ast_write(c0, f);
03395          } else {
03396             *fo = f;
03397             *rc = who;
03398             res = AST_BRIDGE_COMPLETE;
03399             goto return_from_bridge;
03400          }
03401       }
03402       ast_frfree(f);
03403       
03404       /* Swap who gets priority */
03405       priority = !priority;
03406    }
03407 
03408 return_from_bridge:
03409    if (op0 == p0)
03410       zt_enable_ec(p0);
03411 
03412    if (op1 == p1)
03413       zt_enable_ec(p1);
03414 
03415    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03416       enable_dtmf_detect(op0);
03417 
03418    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03419       enable_dtmf_detect(op1);
03420 
03421    zt_unlink(slave, master, 1);
03422 
03423    return res;
03424 }
03425 
03426 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03427 {
03428    struct zt_pvt *p = newchan->tech_pvt;
03429    int x;
03430    ast_mutex_lock(&p->lock);
03431    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03432    if (p->owner == oldchan) {
03433       p->owner = newchan;
03434    }
03435    for (x = 0; x < 3; x++)
03436       if (p->subs[x].owner == oldchan) {
03437          if (!x)
03438             zt_unlink(NULL, p, 0);
03439          p->subs[x].owner = newchan;
03440       }
03441    if (newchan->_state == AST_STATE_RINGING) 
03442       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03443    update_conf(p);
03444    ast_mutex_unlock(&p->lock);
03445    return 0;
03446 }
03447 
03448 static int zt_ring_phone(struct zt_pvt *p)
03449 {
03450    int x;
03451    int res;
03452    /* Make sure our transmit state is on hook */
03453    x = 0;
03454    x = ZT_ONHOOK;
03455    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03456    do {
03457       x = ZT_RING;
03458       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03459       if (res) {
03460          switch (errno) {
03461          case EBUSY:
03462          case EINTR:
03463             /* Wait just in case */
03464             usleep(10000);
03465             continue;
03466          case EINPROGRESS:
03467             res = 0;
03468             break;
03469          default:
03470             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03471             res = 0;
03472          }
03473       }
03474    } while (res);
03475    return res;
03476 }
03477 
03478 static void *ss_thread(void *data);
03479 
03480 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03481 
03482 static int attempt_transfer(struct zt_pvt *p)
03483 {
03484    /* In order to transfer, we need at least one of the channels to
03485       actually be in a call bridge.  We can't conference two applications
03486       together (but then, why would we want to?) */
03487    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03488       /* The three-way person we're about to transfer to could still be in MOH, so
03489          stop if now if appropriate */
03490       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03491          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03492       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03493          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03494       }
03495       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03496          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03497       }
03498       if (p->subs[SUB_REAL].owner->cdr) {
03499          /* Move CDR from second channel to current one */
03500          p->subs[SUB_THREEWAY].owner->cdr =
03501             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03502          p->subs[SUB_REAL].owner->cdr = NULL;
03503       }
03504       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03505          /* Move CDR from second channel's bridge to current one */
03506          p->subs[SUB_THREEWAY].owner->cdr =
03507             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03508          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03509       }
03510        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03511          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03512                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03513          return -1;
03514       }
03515       /* Orphan the channel after releasing the lock */
03516       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03517       unalloc_sub(p, SUB_THREEWAY);
03518    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03519       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03520       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03521          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03522       }
03523       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03524          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03525       }
03526       if (p->subs[SUB_THREEWAY].owner->cdr) {
03527          /* Move CDR from second channel to current one */
03528          p->subs[SUB_REAL].owner->cdr = 
03529             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03530          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03531       }
03532       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03533          /* Move CDR from second channel's bridge to current one */
03534          p->subs[SUB_REAL].owner->cdr = 
03535             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03536          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03537       }
03538       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03539          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03540                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03541          return -1;
03542       }
03543       /* Three-way is now the REAL */
03544       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03545       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03546       unalloc_sub(p, SUB_THREEWAY);
03547       /* Tell the caller not to hangup */
03548       return 1;
03549    } else {
03550       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03551                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03552       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03553       return -1;
03554    }
03555    return 0;
03556 }
03557 
03558 static int check_for_conference(struct zt_pvt *p)
03559 {
03560    ZT_CONFINFO ci;
03561    /* Fine if we already have a master, etc */
03562    if (p->master || (p->confno > -1))
03563       return 0;
03564    memset(&ci, 0, sizeof(ci));
03565    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03566       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03567       return 0;
03568    }
03569    /* If we have no master and don't have a confno, then 
03570       if we're in a conference, it's probably a MeetMe room or
03571       some such, so don't let us 3-way out! */
03572    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03573       if (option_verbose > 2) 
03574          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03575       return 1;
03576    }
03577    return 0;
03578 }
03579 
03580 static int get_alarms(struct zt_pvt *p)
03581 {
03582    int res;
03583    ZT_SPANINFO zi;
03584    memset(&zi, 0, sizeof(zi));
03585    zi.spanno = p->span;
03586    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03587    if (res < 0) {
03588       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03589       return 0;
03590    }
03591    return zi.alarms;
03592 }
03593 
03594 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03595 {
03596    struct zt_pvt *p = ast->tech_pvt;
03597    struct ast_frame *f = *dest;
03598 
03599    if (option_debug)
03600       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03601 
03602    if (p->confirmanswer) {
03603       if (option_debug)
03604          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03605       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03606          of a DTMF digit */
03607       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03608       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03609       *dest = &p->subs[index].f;
03610       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03611       p->confirmanswer = 0;
03612    } else if (p->callwaitcas) {
03613       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03614          if (option_debug)
03615             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03616          if (p->cidspill)
03617             free(p->cidspill);
03618          send_cwcidspill(p);
03619       }
03620       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03621          p->callwaitcas = 0;
03622       p->subs[index].f.frametype = AST_FRAME_NULL;
03623       p->subs[index].f.subclass = 0;
03624       *dest = &p->subs[index].f;
03625    } else if (f->subclass == 'f') {
03626       /* Fax tone -- Handle and return NULL */
03627       if ((p->callprogress & 0x6) && !p->faxhandled) {
03628          p->faxhandled++;
03629          if (strcmp(ast->exten, "fax")) {
03630             const char *target_context = S_OR(ast->macrocontext, ast->context);
03631 
03632             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03633                if (option_verbose > 2)
03634                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03635                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03636                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03637                if (ast_async_goto(ast, target_context, "fax", 1))
03638                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03639             } else
03640                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03641          } else if (option_debug)
03642             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03643       } else if (option_debug)
03644             ast_log(LOG_DEBUG, "Fax already handled\n");
03645       zt_confmute(p, 0);
03646       p->subs[index].f.frametype = AST_FRAME_NULL;
03647       p->subs[index].f.subclass = 0;
03648       *dest = &p->subs[index].f;
03649    } else if (f->subclass == 'm') {
03650       /* Confmute request */
03651       zt_confmute(p, 1);
03652       p->subs[index].f.frametype = AST_FRAME_NULL;
03653       p->subs[index].f.subclass = 0;
03654       *dest = &p->subs[index].f;    
03655    } else if (f->subclass == 'u') {
03656       /* Unmute */
03657       zt_confmute(p, 0);
03658       p->subs[index].f.frametype = AST_FRAME_NULL;
03659       p->subs[index].f.subclass = 0;
03660       *dest = &p->subs[index].f;    
03661    } else
03662       zt_confmute(p, 0);
03663 }
03664          
03665 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03666 {
03667    int res, x;
03668    int index, mysig;
03669    char *c;
03670    struct zt_pvt *p = ast->tech_pvt;
03671    pthread_t threadid;
03672    pthread_attr_t attr;
03673    struct ast_channel *chan;
03674    struct ast_frame *f;
03675 
03676    index = zt_get_index(ast, p, 0);
03677    mysig = p->sig;
03678    if (p->outsigmod > -1)
03679       mysig = p->outsigmod;
03680    p->subs[index].f.frametype = AST_FRAME_NULL;
03681    p->subs[index].f.subclass = 0;
03682    p->subs[index].f.datalen = 0;
03683    p->subs[index].f.samples = 0;
03684    p->subs[index].f.mallocd = 0;
03685    p->subs[index].f.offset = 0;
03686    p->subs[index].f.src = "zt_handle_event";
03687    p->subs[index].f.data = NULL;
03688    f = &p->subs[index].f;
03689 
03690    if (index < 0)
03691       return &p->subs[index].f;
03692    if (p->fake_event) {
03693       res = p->fake_event;
03694       p->fake_event = 0;
03695    } else
03696       res = zt_get_event(p->subs[index].zfd);
03697 
03698    if (option_debug)
03699       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03700 
03701    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03702       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03703 
03704       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03705 #ifdef HAVE_PRI
03706       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03707          /* absorb event */
03708       } else {
03709 #endif
03710          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03711          p->subs[index].f.subclass = res & 0xff;
03712 #ifdef HAVE_PRI
03713       }
03714 #endif
03715       zt_handle_dtmfup(ast, index, &f);
03716       return f;
03717    }
03718 
03719    if (res & ZT_EVENT_DTMFDOWN) {
03720       if (option_debug)
03721          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03722       /* Mute conference */
03723       zt_confmute(p, 1);
03724       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03725       p->subs[index].f.subclass = res & 0xff;
03726       return &p->subs[index].f;
03727    }
03728 
03729    switch (res) {
03730 #ifdef ZT_EVENT_EC_DISABLED
03731       case ZT_EVENT_EC_DISABLED:
03732          if (option_verbose > 2) 
03733             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03734          p->echocanon = 0;
03735          break;
03736 #endif
03737       case ZT_EVENT_BITSCHANGED:
03738          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03739       case ZT_EVENT_PULSE_START:
03740          /* Stop tone if there's a pulse start and the PBX isn't started */
03741          if (!ast->pbx)
03742             tone_zone_play_tone(p->subs[index].zfd, -1);
03743          break;   
03744       case ZT_EVENT_DIALCOMPLETE:
03745          if (p->inalarm) break;
03746          if ((p->radio || (p->oprmode < 0))) break;
03747          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03748             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03749             return NULL;
03750          }
03751          if (!x) { /* if not still dialing in driver */
03752             zt_enable_ec(p);
03753             if (p->echobreak) {
03754                zt_train_ec(p);
03755                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03756                p->dop.op = ZT_DIAL_OP_REPLACE;
03757                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03758                p->echobreak = 0;
03759             } else {
03760                p->dialing = 0;
03761                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03762                   /* if thru with dialing after offhook */
03763                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03764                      ast_setstate(ast, AST_STATE_UP);
03765                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03766                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03767                      break;
03768                   } else { /* if to state wait for offhook to dial rest */
03769                      /* we now wait for off hook */
03770                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03771                   }
03772                }
03773                if (ast->_state == AST_STATE_DIALING) {
03774                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03775                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03776                   } 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)))) {
03777                      ast_setstate(ast, AST_STATE_RINGING);
03778                   } else if (!p->answeronpolarityswitch) {
03779                      ast_setstate(ast, AST_STATE_UP);
03780                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03781                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03782                   }
03783                }
03784             }
03785          }
03786          break;
03787       case ZT_EVENT_ALARM:
03788 #ifdef HAVE_PRI
03789          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03790             /* T309 is not enabled : hangup calls when alarm occurs */
03791             if (p->call) {
03792                if (p->pri && p->pri->pri) {
03793                   if (!pri_grab(p, p->pri)) {
03794                      pri_hangup(p->pri->pri, p->call, -1);
03795                      pri_destroycall(p->pri->pri, p->call);
03796                      p->call = NULL;
03797                      pri_rel(p->pri);
03798                   } else
03799                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03800                } else
03801                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03802             }
03803             if (p->owner)
03804                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03805          }
03806          if (p->bearer)
03807             p->bearer->inalarm = 1;
03808          else
03809 #endif
03810          p->inalarm = 1;
03811          res = get_alarms(p);
03812          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
03813          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03814                         "Alarm: %s\r\n"
03815                         "Channel: %d\r\n",
03816                         alarm2str(res), p->channel);
03817 #ifdef HAVE_LIBPRI
03818          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
03819             /* fall through intentionally */
03820          } else {
03821             break;
03822          }
03823 #endif
03824       case ZT_EVENT_ONHOOK:
03825          if (p->radio) {
03826             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03827             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03828             break;
03829          }
03830          if (p->oprmode < 0)
03831          {
03832             if (p->oprmode != -1) break;
03833             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03834             {
03835                /* Make sure it starts ringing */
03836                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03837                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
03838                save_conference(p->oprpeer);
03839                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03840             }
03841             break;
03842          }
03843          switch (p->sig) {
03844          case SIG_FXOLS:
03845          case SIG_FXOGS:
03846          case SIG_FXOKS:
03847             p->onhooktime = time(NULL);
03848             p->msgstate = -1;
03849             /* Check for some special conditions regarding call waiting */
03850             if (index == SUB_REAL) {
03851                /* The normal line was hung up */
03852                if (p->subs[SUB_CALLWAIT].owner) {
03853                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03854                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03855                   if (option_verbose > 2) 
03856                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03857                   unalloc_sub(p, SUB_CALLWAIT); 
03858 #if 0
03859                   p->subs[index].needanswer = 0;
03860                   p->subs[index].needringing = 0;
03861 #endif                  
03862                   p->callwaitingrepeat = 0;
03863                   p->cidcwexpire = 0;
03864                   p->owner = NULL;
03865                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03866                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03867                      p->dialing = 1;
03868                   zt_ring_phone(p);
03869                } else if (p->subs[SUB_THREEWAY].owner) {
03870                   unsigned int mssinceflash;
03871                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03872                      the private structure -- not especially easy or clean */
03873                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03874                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03875                      ast_mutex_unlock(&p->lock);
03876                      ast_mutex_unlock(&ast->lock);
03877                      usleep(1);
03878                      /* We can grab ast and p in that order, without worry.  We should make sure
03879                         nothing seriously bad has happened though like some sort of bizarre double
03880                         masquerade! */
03881                      ast_mutex_lock(&ast->lock);
03882                      ast_mutex_lock(&p->lock);
03883                      if (p->owner != ast) {
03884                         ast_log(LOG_WARNING, "This isn't good...\n");
03885                         return NULL;
03886                      }
03887                   }
03888                   if (!p->subs[SUB_THREEWAY].owner) {
03889                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03890                      return NULL;
03891                   }
03892                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03893                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03894                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03895                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03896                         hanging up.  Hangup both channels now */
03897                      if (p->subs[SUB_THREEWAY].owner)
03898                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03899                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03900                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03901                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03902                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03903                      if (p->transfer) {
03904                         /* In any case this isn't a threeway call anymore */
03905                         p->subs[SUB_REAL].inthreeway = 0;
03906                         p->subs[SUB_THREEWAY].inthreeway = 0;
03907                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03908                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03909                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03910                            /* Swap subs and dis-own channel */
03911                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03912                            p->owner = NULL;
03913                            /* Ring the phone */
03914                            zt_ring_phone(p);
03915                         } else {
03916                            if ((res = attempt_transfer(p)) < 0) {
03917                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03918                               if (p->subs[SUB_THREEWAY].owner)
03919                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03920                            } else if (res) {
03921                               /* Don't actually hang up at this point */
03922                               if (p->subs[SUB_THREEWAY].owner)
03923                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03924                               break;
03925                            }
03926                         }
03927                      } else {
03928                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03929                         if (p->subs[SUB_THREEWAY].owner)
03930                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03931                      }
03932                   } else {
03933                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03934                      /* Swap subs and dis-own channel */
03935                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03936                      p->owner = NULL;
03937                      /* Ring the phone */
03938                      zt_ring_phone(p);
03939                   }
03940                }
03941             } else {
03942                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03943             }
03944             /* Fall through */
03945          default:
03946             zt_disable_ec(p);
03947             return NULL;
03948          }
03949          break;
03950       case ZT_EVENT_RINGOFFHOOK:
03951          if (p->inalarm) break;
03952          if (p->oprmode < 0)
03953          {
03954             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03955             {
03956                /* Make sure it stops ringing */
03957                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03958                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
03959                restore_conference(p->oprpeer);
03960             }
03961             break;
03962          }
03963          if (p->radio)
03964          {
03965             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03966             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
03967             break;
03968          }
03969          /* for E911, its supposed to wait for offhook then dial
03970             the second half of the dial string */
03971          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
03972             c = strchr(p->dialdest, '/');
03973             if (c)
03974                c++;
03975             else
03976                c = p->dialdest;
03977             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
03978             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
03979             if (strlen(p->dop.dialstr) > 4) {
03980                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
03981                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
03982                p->echorest[sizeof(p->echorest) - 1] = '\0';
03983                p->echobreak = 1;
03984                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
03985             } else
03986                p->echobreak = 0;
03987             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
03988                x = ZT_ONHOOK;
03989                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03990                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
03991                return NULL;
03992                }
03993             p->dialing = 1;
03994             return &p->subs[index].f;
03995          }
03996          switch (p->sig) {
03997          case SIG_FXOLS:
03998          case SIG_FXOGS:
03999          case SIG_FXOKS:
04000             switch (ast->_state) {
04001             case AST_STATE_RINGING:
04002                zt_enable_ec(p);
04003                zt_train_ec(p);
04004                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04005                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04006                /* Make sure it stops ringing */
04007                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04008                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04009                if (p->cidspill) {
04010                   /* Cancel any running CallerID spill */
04011                   free(p->cidspill);
04012                   p->cidspill = NULL;
04013                }
04014                p->dialing = 0;
04015                p->callwaitcas = 0;
04016                if (p->confirmanswer) {
04017                   /* Ignore answer if "confirm answer" is enabled */
04018                   p->subs[index].f.frametype = AST_FRAME_NULL;
04019                   p->subs[index].f.subclass = 0;
04020                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04021                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04022                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04023                   if (res < 0) {
04024                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04025                      p->dop.dialstr[0] = '\0';
04026                      return NULL;
04027                   } else {
04028                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04029                      p->subs[index].f.frametype = AST_FRAME_NULL;
04030                      p->subs[index].f.subclass = 0;
04031                      p->dialing = 1;
04032                   }
04033                   p->dop.dialstr[0] = '\0';
04034                   ast_setstate(ast, AST_STATE_DIALING);
04035                } else
04036                   ast_setstate(ast, AST_STATE_UP);
04037                return &p->subs[index].f;
04038             case AST_STATE_DOWN:
04039                ast_setstate(ast, AST_STATE_RING);
04040                ast->rings = 1;
04041                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04042                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04043                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04044                return &p->subs[index].f;
04045             case AST_STATE_UP:
04046                /* Make sure it stops ringing */
04047                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04048                /* Okay -- probably call waiting*/
04049                if (ast_bridged_channel(p->owner))
04050                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04051                p->subs[index].needunhold = 1;
04052                break;
04053             case AST_STATE_RESERVED:
04054                /* Start up dialtone */
04055                if (has_voicemail(p))
04056                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04057                else
04058                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04059                break;
04060             default:
04061                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04062             }
04063             break;
04064          case SIG_FXSLS:
04065          case SIG_FXSGS:
04066          case SIG_FXSKS:
04067             if (ast->_state == AST_STATE_RING) {
04068                p->ringt = p->ringt_base;
04069             }
04070 
04071             /* If we get a ring then we cannot be in 
04072              * reversed polarity. So we reset to idle */
04073             if (option_debug)
04074                ast_log(LOG_DEBUG, "Setting IDLE polarity due "
04075                   "to ring. Old polarity was %d\n", 
04076                   p->polarity);
04077             p->polarity = POLARITY_IDLE;
04078 
04079             /* Fall through */
04080          case SIG_EM:
04081          case SIG_EM_E1:
04082          case SIG_EMWINK:
04083          case SIG_FEATD:
04084          case SIG_FEATDMF:
04085          case SIG_FEATDMF_TA:
04086          case SIG_E911:
04087          case SIG_FGC_CAMA:
04088          case SIG_FGC_CAMAMF:
04089          case SIG_FEATB:
04090          case SIG_SF:
04091          case SIG_SFWINK:
04092          case SIG_SF_FEATD:
04093          case SIG_SF_FEATDMF:
04094          case SIG_SF_FEATB:
04095             if (ast->_state == AST_STATE_PRERING)
04096                ast_setstate(ast, AST_STATE_RING);
04097             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04098                if (option_debug)
04099                   ast_log(LOG_DEBUG, "Ring detected\n");
04100                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04101                p->subs[index].f.subclass = AST_CONTROL_RING;
04102             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04103                if (option_debug)
04104                   ast_log(LOG_DEBUG, "Line answered\n");
04105                if (p->confirmanswer) {
04106                   p->subs[index].f.frametype = AST_FRAME_NULL;
04107                   p->subs[index].f.subclass = 0;
04108                } else {
04109                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04110                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04111                   ast_setstate(ast, AST_STATE_UP);
04112                }
04113             } else if (ast->_state != AST_STATE_RING)
04114                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04115             break;
04116          default:
04117             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04118          }
04119          break;
04120 #ifdef ZT_EVENT_RINGBEGIN
04121       case ZT_EVENT_RINGBEGIN:
04122          switch (p->sig) {
04123          case SIG_FXSLS:
04124          case SIG_FXSGS:
04125          case SIG_FXSKS:
04126             if (ast->_state == AST_STATE_RING) {
04127                p->ringt = p->ringt_base;
04128             }
04129             break;
04130          }
04131          break;
04132 #endif         
04133       case ZT_EVENT_RINGEROFF:
04134          if (p->inalarm) break;
04135          if ((p->radio || (p->oprmode < 0))) break;
04136          ast->rings++;
04137          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04138             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04139             free(p->cidspill);
04140             p->cidspill = NULL;
04141             p->callwaitcas = 0;
04142          }
04143          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04144          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04145          break;
04146       case ZT_EVENT_RINGERON:
04147          break;
04148       case ZT_EVENT_NOALARM:
04149          p->inalarm = 0;
04150 #ifdef HAVE_PRI
04151          /* Extremely unlikely but just in case */
04152          if (p->bearer)
04153             p->bearer->inalarm = 0;
04154 #endif            
04155          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04156          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04157                         "Channel: %d\r\n", p->channel);
04158          break;
04159       case ZT_EVENT_WINKFLASH:
04160          if (p->inalarm) break;
04161          if (p->radio) break;
04162          if (p->oprmode < 0) break;
04163          if (p->oprmode > 1)
04164          {
04165             struct zt_params par;
04166 
04167             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04168             {
04169                if (!par.rxisoffhook)
04170                {
04171                   /* Make sure it stops ringing */
04172                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04173                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04174                   save_conference(p);
04175                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04176                }
04177             }
04178             break;
04179          }
04180          /* Remember last time we got a flash-hook */
04181          gettimeofday(&p->flashtime, NULL);
04182          switch (mysig) {
04183          case SIG_FXOLS:
04184          case SIG_FXOGS:
04185          case SIG_FXOKS:
04186             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04187                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04188             p->callwaitcas = 0;
04189 
04190             if (index != SUB_REAL) {
04191                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04192                goto winkflashdone;
04193             }
04194             
04195             if (p->subs[SUB_CALLWAIT].owner) {
04196                /* Swap to call-wait */
04197                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04198                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04199                p->owner = p->subs[SUB_REAL].owner;
04200                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04201                if (p->owner->_state == AST_STATE_RINGING) {
04202                   ast_setstate(p->owner, AST_STATE_UP);
04203                   p->subs[SUB_REAL].needanswer = 1;
04204                }
04205                p->callwaitingrepeat = 0;
04206                p->cidcwexpire = 0;
04207                /* Start music on hold if appropriate */
04208                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04209                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04210                      S_OR(p->mohsuggest, NULL),
04211                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04212                }
04213                p->subs[SUB_CALLWAIT].needhold = 1;
04214                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04215                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04216                      S_OR(p->mohsuggest, NULL),
04217                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04218                }
04219                p->subs[SUB_REAL].needunhold = 1;
04220             } else if (!p->subs[SUB_THREEWAY].owner) {
04221                char cid_num[256];
04222                char cid_name[256];
04223 
04224                if (!p->threewaycalling) {
04225                   /* Just send a flash if no 3-way calling */
04226                   p->subs[SUB_REAL].needflash = 1;
04227                   goto winkflashdone;
04228                } else if (!check_for_conference(p)) {
04229                   if (p->zaptrcallerid && p->owner) {
04230                      if (p->owner->cid.cid_num)
04231                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04232                      if (p->owner->cid.cid_name)
04233                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04234                   }
04235                   /* XXX This section needs much more error checking!!! XXX */
04236                   /* Start a 3-way call if feasible */
04237                   if (!((ast->pbx) ||
04238                         (ast->_state == AST_STATE_UP) ||
04239                         (ast->_state == AST_STATE_RING))) {
04240                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04241                         goto winkflashdone;
04242                   }
04243                   if (alloc_sub(p, SUB_THREEWAY)) {
04244                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04245                      goto winkflashdone;
04246                   }
04247                   /* Make new channel */
04248                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04249                   if (p->zaptrcallerid) {
04250                      if (!p->origcid_num)
04251                         p->origcid_num = ast_strdup(p->cid_num);
04252                      if (!p->origcid_name)
04253                         p->origcid_name = ast_strdup(p->cid_name);
04254                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04255                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04256                   }
04257                   /* Swap things around between the three-way and real call */
04258                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04259                   /* Disable echo canceller for better dialing */
04260                   zt_disable_ec(p);
04261                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04262                   if (res)
04263                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04264                   p->owner = chan;
04265                   pthread_attr_init(&attr);
04266                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04267                   if (!chan) {
04268                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04269                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04270                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04271                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04272                      zt_enable_ec(p);
04273                      ast_hangup(chan);
04274                   } else {
04275                      if (option_verbose > 2) 
04276                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04277                      /* Start music on hold if appropriate */
04278                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04279                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04280                            S_OR(p->mohsuggest, NULL),
04281                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04282                      }
04283                      p->subs[SUB_THREEWAY].needhold = 1;
04284                   }
04285                   pthread_attr_destroy(&attr);
04286                }
04287             } else {
04288                /* Already have a 3 way call */
04289                if (p->subs[SUB_THREEWAY].inthreeway) {
04290                   /* Call is already up, drop the last person */
04291                   if (option_debug)
04292                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04293                   /* If the primary call isn't answered yet, use it */
04294                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04295                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04296                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04297                      p->owner = p->subs[SUB_REAL].owner;
04298                   }
04299                   /* Drop the last call and stop the conference */
04300                   if (option_verbose > 2)
04301                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04302                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04303                   p->subs[SUB_REAL].inthreeway = 0;
04304                   p->subs[SUB_THREEWAY].inthreeway = 0;
04305                } else {
04306                   /* Lets see what we're up to */
04307                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04308                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04309                      int otherindex = SUB_THREEWAY;
04310 
04311                      if (option_verbose > 2)
04312                         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);
04313                      /* Put them in the threeway, and flip */
04314                      p->subs[SUB_THREEWAY].inthreeway = 1;
04315                      p->subs[SUB_REAL].inthreeway = 1;
04316                      if (ast->_state == AST_STATE_UP) {
04317                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04318                         otherindex = SUB_REAL;
04319                      }
04320                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04321                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04322                      p->subs[otherindex].needunhold = 1;
04323                      p->owner = p->subs[SUB_REAL].owner;
04324                      if (ast->_state == AST_STATE_RINGING) {
04325                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04326                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04327                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04328                      }
04329                   } else {
04330                      if (option_verbose > 2)
04331                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04332                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04333                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04334                      p->owner = p->subs[SUB_REAL].owner;
04335                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04336                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04337                      p->subs[SUB_REAL].needunhold = 1;
04338                      zt_enable_ec(p);
04339                   }
04340                      
04341                }
04342             }
04343          winkflashdone:              
04344             update_conf(p);
04345             break;
04346          case SIG_EM:
04347          case SIG_EM_E1:
04348          case SIG_EMWINK:
04349          case SIG_FEATD:
04350          case SIG_SF:
04351          case SIG_SFWINK:
04352          case SIG_SF_FEATD:
04353          case SIG_FXSLS:
04354          case SIG_FXSGS:
04355             if (p->dialing)
04356                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04357             else
04358                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04359             break;
04360          case SIG_FEATDMF_TA:
04361             switch (p->whichwink) {
04362             case 0:
04363                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04364                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04365                break;
04366             case 1:
04367                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04368                break;
04369             case 2:
04370                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04371                return NULL;
04372             }
04373             p->whichwink++;
04374             /* Fall through */
04375          case SIG_FEATDMF:
04376          case SIG_E911:
04377          case SIG_FGC_CAMAMF:
04378          case SIG_FGC_CAMA:
04379          case SIG_FEATB:
04380          case SIG_SF_FEATDMF:
04381          case SIG_SF_FEATB:
04382             /* FGD MF *Must* wait for wink */
04383             if (!ast_strlen_zero(p->dop.dialstr))
04384                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04385             else if (res < 0) {
04386                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04387                p->dop.dialstr[0] = '\0';
04388                return NULL;
04389             } else 
04390                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04391             p->dop.dialstr[0] = '\0';
04392             break;
04393          default:
04394             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04395          }
04396          break;
04397       case ZT_EVENT_HOOKCOMPLETE:
04398          if (p->inalarm) break;
04399          if ((p->radio || (p->oprmode < 0))) break;
04400          switch (mysig) {
04401          case SIG_FXSLS:  /* only interesting for FXS */
04402          case SIG_FXSGS:
04403          case SIG_FXSKS:
04404          case SIG_EM:
04405          case SIG_EM_E1:
04406          case SIG_EMWINK:
04407          case SIG_FEATD:
04408          case SIG_SF:
04409          case SIG_SFWINK:
04410          case SIG_SF_FEATD:
04411             if (!ast_strlen_zero(p->dop.dialstr)) 
04412                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04413             else if (res < 0) {
04414                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04415                p->dop.dialstr[0] = '\0';
04416                return NULL;
04417             } else 
04418                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04419             p->dop.dialstr[0] = '\0';
04420             p->dop.op = ZT_DIAL_OP_REPLACE;
04421             break;
04422          case SIG_FEATDMF:
04423          case SIG_FEATDMF_TA:
04424          case SIG_E911:
04425          case SIG_FGC_CAMA:
04426          case SIG_FGC_CAMAMF:
04427          case SIG_FEATB:
04428          case SIG_SF_FEATDMF:
04429          case SIG_SF_FEATB:
04430             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04431             break;
04432          default:
04433             break;
04434          }
04435          break;
04436       case ZT_EVENT_POLARITY:
04437          /*
04438           * If we get a Polarity Switch event, check to see
04439           * if we should change the polarity state and
04440           * mark the channel as UP or if this is an indication
04441           * of remote end disconnect.
04442           */
04443          if (p->polarity == POLARITY_IDLE) {
04444             p->polarity = POLARITY_REV;
04445             if (p->answeronpolarityswitch &&
04446                 ((ast->_state == AST_STATE_DIALING) ||
04447                 (ast->_state == AST_STATE_RINGING))) {
04448                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04449                ast_setstate(p->owner, AST_STATE_UP);
04450                if (p->hanguponpolarityswitch) {
04451                   gettimeofday(&p->polaritydelaytv, NULL);
04452                }
04453             } else
04454                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04455          } 
04456          /* Removed else statement from here as it was preventing hangups from ever happening*/
04457          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04458          if (p->hanguponpolarityswitch &&
04459             (p->polarityonanswerdelay > 0) &&
04460                 (p->polarity == POLARITY_REV) &&
04461             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04462                                 /* Added log_debug information below to provide a better indication of what is going on */
04463             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) );
04464          
04465             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04466                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04467                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04468                p->polarity = POLARITY_IDLE;
04469             } else {
04470                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);
04471             }
04472          } else {
04473             p->polarity = POLARITY_IDLE;
04474             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04475          }
04476                         /* Added more log_debug information below to provide a better indication of what is going on */
04477          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) );
04478          break;
04479       default:
04480          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04481    }
04482    return &p->subs[index].f;
04483 }
04484 
04485 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04486 {
04487    struct zt_pvt *p = ast->tech_pvt;
04488    int res;
04489    int usedindex=-1;
04490    int index;
04491    struct ast_frame *f;
04492 
04493 
04494    index = zt_get_index(ast, p, 1);
04495    
04496    p->subs[index].f.frametype = AST_FRAME_NULL;
04497    p->subs[index].f.datalen = 0;
04498    p->subs[index].f.samples = 0;
04499    p->subs[index].f.mallocd = 0;
04500    p->subs[index].f.offset = 0;
04501    p->subs[index].f.subclass = 0;
04502    p->subs[index].f.delivery = ast_tv(0,0);
04503    p->subs[index].f.src = "zt_exception";
04504    p->subs[index].f.data = NULL;
04505    
04506    
04507    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04508       /* If nobody owns us, absorb the event appropriately, otherwise
04509          we loop indefinitely.  This occurs when, during call waiting, the
04510          other end hangs up our channel so that it no longer exists, but we
04511          have neither FLASH'd nor ONHOOK'd to signify our desire to
04512          change to the other channel. */
04513       if (p->fake_event) {
04514          res = p->fake_event;
04515          p->fake_event = 0;
04516       } else
04517          res = zt_get_event(p->subs[SUB_REAL].zfd);
04518       /* Switch to real if there is one and this isn't something really silly... */
04519       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04520          (res != ZT_EVENT_HOOKCOMPLETE)) {
04521          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04522          p->owner = p->subs[SUB_REAL].owner;
04523          if (p->owner && ast_bridged_channel(p->owner))
04524             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04525          p->subs[SUB_REAL].needunhold = 1;
04526       }
04527       switch (res) {
04528       case ZT_EVENT_ONHOOK:
04529          zt_disable_ec(p);
04530          if (p->owner) {
04531             if (option_verbose > 2) 
04532                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04533             zt_ring_phone(p);
04534             p->callwaitingrepeat = 0;
04535             p->cidcwexpire = 0;
04536          } else
04537             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04538          update_conf(p);
04539          break;
04540       case ZT_EVENT_RINGOFFHOOK:
04541          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04542          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04543             p->subs[SUB_REAL].needanswer = 1;
04544             p->dialing = 0;
04545          }
04546          break;
04547       case ZT_EVENT_HOOKCOMPLETE:
04548       case ZT_EVENT_RINGERON:
04549       case ZT_EVENT_RINGEROFF:
04550          /* Do nothing */
04551          break;
04552       case ZT_EVENT_WINKFLASH:
04553          gettimeofday(&p->flashtime, NULL);
04554          if (p->owner) {
04555             if (option_verbose > 2) 
04556                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04557             if (p->owner->_state != AST_STATE_UP) {
04558                /* Answer if necessary */
04559                usedindex = zt_get_index(p->owner, p, 0);
04560                if (usedindex > -1) {
04561                   p->subs[usedindex].needanswer = 1;
04562                }
04563                ast_setstate(p->owner, AST_STATE_UP);
04564             }
04565             p->callwaitingrepeat = 0;
04566             p->cidcwexpire = 0;
04567             if (ast_bridged_channel(p->owner))
04568                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04569             p->subs[SUB_REAL].needunhold = 1;
04570          } else
04571             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04572          update_conf(p);
04573          break;
04574       default:
04575          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04576       }
04577       f = &p->subs[index].f;
04578       return f;
04579    }
04580    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04581       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04582    /* If it's not us, return NULL immediately */
04583    if (ast != p->owner) {
04584       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04585       f = &p->subs[index].f;
04586       return f;
04587    }
04588    f = zt_handle_event(ast);
04589    return f;
04590 }
04591 
04592 static struct ast_frame *zt_exception(struct ast_channel *ast)
04593 {
04594    struct zt_pvt *p = ast->tech_pvt;
04595    struct ast_frame *f;
04596    ast_mutex_lock(&p->lock);
04597    f = __zt_exception(ast);
04598    ast_mutex_unlock(&p->lock);
04599    return f;
04600 }
04601 
04602 static struct ast_frame  *zt_read(struct ast_channel *ast)
04603 {
04604    struct zt_pvt *p = ast->tech_pvt;
04605    int res;
04606    int index;
04607    void *readbuf;
04608    struct ast_frame *f;
04609    
04610 
04611    ast_mutex_lock(&p->lock);
04612    
04613    index = zt_get_index(ast, p, 0);
04614    
04615    /* Hang up if we don't really exist */
04616    if (index < 0) {
04617       ast_log(LOG_WARNING, "We dont exist?\n");
04618       ast_mutex_unlock(&p->lock);
04619       return NULL;
04620    }
04621    
04622    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04623 
04624    p->subs[index].f.frametype = AST_FRAME_NULL;
04625    p->subs[index].f.datalen = 0;
04626    p->subs[index].f.samples = 0;
04627    p->subs[index].f.mallocd = 0;
04628    p->subs[index].f.offset = 0;
04629    p->subs[index].f.subclass = 0;
04630    p->subs[index].f.delivery = ast_tv(0,0);
04631    p->subs[index].f.src = "zt_read";
04632    p->subs[index].f.data = NULL;
04633    
04634    /* make sure it sends initial key state as first frame */
04635    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04636    {
04637       ZT_PARAMS ps;
04638 
04639       ps.channo = p->channel;
04640       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04641          ast_mutex_unlock(&p->lock);
04642          return NULL;
04643       }
04644       p->firstradio = 1;
04645       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04646       if (ps.rxisoffhook)
04647       {
04648          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04649       }
04650       else
04651       {
04652          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04653       }
04654       ast_mutex_unlock(&p->lock);
04655       return &p->subs[index].f;
04656    }
04657    if (p->ringt == 1) {
04658       ast_mutex_unlock(&p->lock);
04659       return NULL;
04660    }
04661    else if (p->ringt > 0) 
04662       p->ringt--;
04663 
04664    if (p->subs[index].needringing) {
04665       /* Send ringing frame if requested */
04666       p->subs[index].needringing = 0;
04667       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04668       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04669       ast_setstate(ast, AST_STATE_RINGING);
04670       ast_mutex_unlock(&p->lock);
04671       return &p->subs[index].f;
04672    }
04673 
04674    if (p->subs[index].needbusy) {
04675       /* Send busy frame if requested */
04676       p->subs[index].needbusy = 0;
04677       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04678       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04679       ast_mutex_unlock(&p->lock);
04680       return &p->subs[index].f;
04681    }
04682 
04683    if (p->subs[index].needcongestion) {
04684       /* Send congestion frame if requested */
04685       p->subs[index].needcongestion = 0;
04686       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04687       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04688       ast_mutex_unlock(&p->lock);
04689       return &p->subs[index].f;
04690    }
04691 
04692    if (p->subs[index].needcallerid) {
04693       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04694                      S_OR(p->lastcid_name, NULL),
04695                      S_OR(p->lastcid_num, NULL)
04696                      );
04697       p->subs[index].needcallerid = 0;
04698    }
04699    
04700    if (p->subs[index].needanswer) {
04701       /* Send answer frame if requested */
04702       p->subs[index].needanswer = 0;
04703       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04704       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04705       ast_mutex_unlock(&p->lock);
04706       return &p->subs[index].f;
04707    }  
04708    
04709    if (p->subs[index].needflash) {
04710       /* Send answer frame if requested */
04711       p->subs[index].needflash = 0;
04712       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04713       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04714       ast_mutex_unlock(&p->lock);
04715       return &p->subs[index].f;
04716    }  
04717    
04718    if (p->subs[index].needhold) {
04719       /* Send answer frame if requested */
04720       p->subs[index].needhold = 0;
04721       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04722       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04723       ast_mutex_unlock(&p->lock);
04724       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04725       return &p->subs[index].f;
04726    }  
04727    
04728    if (p->subs[index].needunhold) {
04729       /* Send answer frame if requested */
04730       p->subs[index].needunhold = 0;
04731       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04732       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04733       ast_mutex_unlock(&p->lock);
04734       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04735       return &p->subs[index].f;
04736    }  
04737    
04738    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04739       if (!p->subs[index].linear) {
04740          p->subs[index].linear = 1;
04741          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04742          if (res) 
04743             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04744       }
04745    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04746          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04747       if (p->subs[index].linear) {
04748          p->subs[index].linear = 0;
04749          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04750          if (res) 
04751             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04752       }
04753    } else {
04754       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04755       ast_mutex_unlock(&p->lock);
04756       return NULL;
04757    }
04758    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04759    CHECK_BLOCKING(ast);
04760    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04761    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04762    /* Check for hangup */
04763    if (res < 0) {
04764       f = NULL;
04765       if (res == -1)  {
04766          if (errno == EAGAIN) {
04767             /* Return "NULL" frame if there is nobody there */
04768             ast_mutex_unlock(&p->lock);
04769             return &p->subs[index].f;
04770          } else if (errno == ELAST) {
04771             f = __zt_exception(ast);
04772          } else
04773             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04774       }
04775       ast_mutex_unlock(&p->lock);
04776       return f;
04777    }
04778    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04779       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04780       f = __zt_exception(ast);
04781       ast_mutex_unlock(&p->lock);
04782       return f;
04783    }
04784    if (p->tdd) { /* if in TDD mode, see if we receive that */
04785       int c;
04786 
04787       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04788       if (c < 0) {
04789          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04790          ast_mutex_unlock(&p->lock);
04791          return NULL;
04792       }
04793       if (c) { /* if a char to return */
04794          p->subs[index].f.subclass = 0;
04795          p->subs[index].f.frametype = AST_FRAME_TEXT;
04796          p->subs[index].f.mallocd = 0;
04797          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04798          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04799          p->subs[index].f.datalen = 1;
04800          *((char *) p->subs[index].f.data) = c;
04801          ast_mutex_unlock(&p->lock);
04802          return &p->subs[index].f;
04803       }
04804    }
04805    if (p->callwaitingrepeat)
04806       p->callwaitingrepeat--;
04807    if (p->cidcwexpire)
04808       p->cidcwexpire--;
04809    /* Repeat callwaiting */
04810    if (p->callwaitingrepeat == 1) {
04811       p->callwaitrings++;
04812       zt_callwait(ast);
04813    }
04814    /* Expire CID/CW */
04815    if (p->cidcwexpire == 1) {
04816       if (option_verbose > 2)
04817          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04818       restore_conference(p);
04819    }
04820    if (p->subs[index].linear) {
04821       p->subs[index].f.datalen = READ_SIZE * 2;
04822    } else 
04823       p->subs[index].f.datalen = READ_SIZE;
04824 
04825    /* Handle CallerID Transmission */
04826    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04827       send_callerid(p);
04828    }
04829 
04830    p->subs[index].f.frametype = AST_FRAME_VOICE;
04831    p->subs[index].f.subclass = ast->rawreadformat;
04832    p->subs[index].f.samples = READ_SIZE;
04833    p->subs[index].f.mallocd = 0;
04834    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04835    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
04836 #if 0
04837    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04838 #endif   
04839    if (p->dialing || /* Transmitting something */
04840       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04841       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04842       ) {
04843       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04844          don't send anything */
04845       p->subs[index].f.frametype = AST_FRAME_NULL;
04846       p->subs[index].f.subclass = 0;
04847       p->subs[index].f.samples = 0;
04848       p->subs[index].f.mallocd = 0;
04849       p->subs[index].f.offset = 0;
04850       p->subs[index].f.data = NULL;
04851       p->subs[index].f.datalen= 0;
04852    }
04853    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04854       /* Perform busy detection. etc on the zap line */
04855       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04856       if (f) {
04857          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04858             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04859                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04860                   a busy  */
04861                f = NULL;
04862             }
04863          } else if (f->frametype == AST_FRAME_DTMF) {
04864 #ifdef HAVE_PRI
04865             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04866                /* Don't accept in-band DTMF when in overlap dial mode */
04867                f->frametype = AST_FRAME_NULL;
04868                f->subclass = 0;
04869             }
04870 #endif            
04871             /* DSP clears us of being pulse */
04872             p->pulsedial = 0;
04873          }
04874       }
04875    } else 
04876       f = &p->subs[index].f; 
04877 
04878    if (f && (f->frametype == AST_FRAME_DTMF))
04879       zt_handle_dtmfup(ast, index, &f);
04880 
04881    /* If we have a fake_event, trigger exception to handle it */
04882    if (p->fake_event)
04883       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04884 
04885    ast_mutex_unlock(&p->lock);
04886    return f;
04887 }
04888 
04889 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
04890 {
04891    int sent=0;
04892    int size;
04893    int res;
04894    int fd;
04895    fd = p->subs[index].zfd;
04896    while (len) {
04897       size = len;
04898       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04899          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04900       res = write(fd, buf, size);
04901       if (res != size) {
04902          if (option_debug)
04903             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04904          return sent;
04905       }
04906       len -= size;
04907       buf += size;
04908    }
04909    return sent;
04910 }
04911 
04912 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
04913 {
04914    struct zt_pvt *p = ast->tech_pvt;
04915    int res;
04916    unsigned char outbuf[4096];
04917    int index;
04918    index = zt_get_index(ast, p, 0);
04919    if (index < 0) {
04920       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04921       return -1;
04922    }
04923 
04924 #if 0
04925 #ifdef HAVE_PRI
04926    ast_mutex_lock(&p->lock);
04927    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04928       if (p->pri->pri) {      
04929          if (!pri_grab(p, p->pri)) {
04930                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04931                pri_rel(p->pri);
04932          } else
04933                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04934       }
04935       p->proceeding=1;
04936    }
04937    ast_mutex_unlock(&p->lock);
04938 #endif
04939 #endif
04940    /* Write a frame of (presumably voice) data */
04941    if (frame->frametype != AST_FRAME_VOICE) {
04942       if (frame->frametype != AST_FRAME_IMAGE)
04943          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04944       return 0;
04945    }
04946    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04947        (frame->subclass != AST_FORMAT_ULAW) &&
04948        (frame->subclass != AST_FORMAT_ALAW)) {
04949       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04950       return -1;
04951    }
04952    if (p->dialing) {
04953       if (option_debug)
04954          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
04955       return 0;
04956    }
04957    if (!p->owner) {
04958       if (option_debug)
04959          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
04960       return 0;
04961    }
04962    if (p->cidspill) {
04963       if (option_debug)
04964          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
04965       return 0;
04966    }
04967    /* Return if it's not valid data */
04968    if (!frame->data || !frame->datalen)
04969       return 0;
04970    if (frame->datalen > sizeof(outbuf) * 2) {
04971       ast_log(LOG_WARNING, "Frame too large\n");
04972       return 0;
04973    }
04974 
04975    if (frame->subclass == AST_FORMAT_SLINEAR) {
04976       if (!p->subs[index].linear) {
04977          p->subs[index].linear = 1;
04978          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04979          if (res)
04980             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
04981       }
04982       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
04983    } else {
04984       /* x-law already */
04985       if (p->subs[index].linear) {
04986          p->subs[index].linear = 0;
04987          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04988          if (res)
04989             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
04990       }
04991       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
04992    }
04993    if (res < 0) {
04994       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
04995       return -1;
04996    } 
04997    return 0;
04998 }
04999 
05000 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05001 {
05002    struct zt_pvt *p = chan->tech_pvt;
05003    int res=-1;
05004    int index;
05005    int func = ZT_FLASH;
05006    ast_mutex_lock(&p->lock);
05007    index = zt_get_index(chan, p, 0);
05008    if (option_debug)
05009       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05010    if (index == SUB_REAL) {
05011       switch (condition) {
05012       case AST_CONTROL_BUSY:
05013 #ifdef HAVE_PRI
05014          if (p->priindication_oob && p->sig == SIG_PRI) {
05015             chan->hangupcause = AST_CAUSE_USER_BUSY;
05016             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05017             res = 0;
05018          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05019             if (p->pri->pri) {      
05020                if (!pri_grab(p, p->pri)) {
05021                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05022                   pri_rel(p->pri);
05023                }
05024                else
05025                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05026             }
05027             p->progress = 1;
05028             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05029          } else
05030 #endif
05031             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05032          break;
05033       case AST_CONTROL_RINGING:
05034 #ifdef HAVE_PRI
05035          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05036             if (p->pri->pri) {      
05037                if (!pri_grab(p, p->pri)) {
05038                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05039                   pri_rel(p->pri);
05040                }
05041                else
05042                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05043             }
05044             p->alerting = 1;
05045          }
05046 #endif
05047          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05048          if (chan->_state != AST_STATE_UP) {
05049             if ((chan->_state != AST_STATE_RING) ||
05050                ((p->sig != SIG_FXSKS) &&
05051                 (p->sig != SIG_FXSLS) &&
05052                 (p->sig != SIG_FXSGS)))
05053                ast_setstate(chan, AST_STATE_RINGING);
05054          }
05055          break;
05056       case AST_CONTROL_PROCEEDING:
05057          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05058 #ifdef HAVE_PRI
05059          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05060             if (p->pri->pri) {      
05061                if (!pri_grab(p, p->pri)) {
05062                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05063                   pri_rel(p->pri);
05064                }
05065                else
05066                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05067             }
05068             p->proceeding = 1;
05069          }
05070 #endif
05071          /* don't continue in ast_indicate */
05072          res = 0;
05073          break;
05074       case AST_CONTROL_PROGRESS:
05075          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05076 #ifdef HAVE_PRI
05077          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05078          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05079             if (p->pri->pri) {      
05080                if (!pri_grab(p, p->pri)) {
05081                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05082                   pri_rel(p->pri);
05083                }
05084                else
05085                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05086             }
05087             p->progress = 1;
05088          }
05089 #endif
05090          /* don't continue in ast_indicate */
05091          res = 0;
05092          break;
05093       case AST_CONTROL_CONGESTION:
05094          chan->hangupcause = AST_CAUSE_CONGESTION;
05095 #ifdef HAVE_PRI
05096          if (p->priindication_oob && p->sig == SIG_PRI) {
05097             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05098             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05099             res = 0;
05100          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05101             if (p->pri) {     
05102                if (!pri_grab(p, p->pri)) {
05103                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05104                   pri_rel(p->pri);
05105                } else
05106                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05107             }
05108             p->progress = 1;
05109             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05110          } else
05111 #endif
05112             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05113          break;
05114       case AST_CONTROL_HOLD:
05115 #ifdef HAVE_PRI
05116          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05117             if (!pri_grab(p, p->pri)) {
05118                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05119                pri_rel(p->pri);
05120             } else
05121                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05122          } else
05123 #endif
05124             ast_moh_start(chan, data, p->mohinterpret);
05125          break;
05126       case AST_CONTROL_UNHOLD:
05127 #ifdef HAVE_PRI
05128          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05129             if (!pri_grab(p, p->pri)) {
05130                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05131                pri_rel(p->pri);
05132             } else
05133                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05134          } else
05135 #endif
05136             ast_moh_stop(chan);
05137          break;
05138       case AST_CONTROL_RADIO_KEY:
05139          if (p->radio) 
05140              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05141          res = 0;
05142          break;
05143       case AST_CONTROL_RADIO_UNKEY:
05144          if (p->radio)
05145              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05146          res = 0;
05147          break;
05148       case AST_CONTROL_FLASH:
05149          /* flash hookswitch */
05150          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05151             /* Clear out the dial buffer */
05152             p->dop.dialstr[0] = '\0';
05153             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05154                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05155                   chan->name, strerror(errno));
05156             } else
05157                res = 0;
05158          } else
05159             res = 0;
05160          break;
05161       case -1:
05162          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05163          break;
05164       }
05165    } else
05166       res = 0;
05167    ast_mutex_unlock(&p->lock);
05168    return res;
05169 }
05170 
05171 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05172 {
05173    struct ast_channel *tmp;
05174    int deflaw;
05175    int res;
05176    int x,y;
05177    int features;
05178    char *b2 = NULL;
05179    ZT_PARAMS ps;
05180    if (i->subs[index].owner) {
05181       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05182       return NULL;
05183    }
05184    y = 1;
05185    do {
05186       if (b2)
05187          free(b2);
05188 #ifdef HAVE_PRI
05189       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05190          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05191       else
05192 #endif
05193       if (i->channel == CHAN_PSEUDO)
05194          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05195       else  
05196          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05197       for (x = 0; x < 3; x++) {
05198          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05199             break;
05200       }
05201       y++;
05202    } while (x < 3);
05203    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05204    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05205       free(b2);
05206    if (!tmp)
05207       return NULL;
05208    tmp->tech = &zap_tech;
05209    ps.channo = i->channel;
05210    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05211    if (res) {
05212       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05213       ps.curlaw = ZT_LAW_MULAW;
05214    }
05215    if (ps.curlaw == ZT_LAW_ALAW)
05216       deflaw = AST_FORMAT_ALAW;
05217    else
05218       deflaw = AST_FORMAT_ULAW;
05219    if (law) {
05220       if (law == ZT_LAW_ALAW)
05221          deflaw = AST_FORMAT_ALAW;
05222       else
05223          deflaw = AST_FORMAT_ULAW;
05224    }
05225    tmp->fds[0] = i->subs[index].zfd;
05226    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05227    /* Start out assuming ulaw since it's smaller :) */
05228    tmp->rawreadformat = deflaw;
05229    tmp->readformat = deflaw;
05230    tmp->rawwriteformat = deflaw;
05231    tmp->writeformat = deflaw;
05232    i->subs[index].linear = 0;
05233    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05234    features = 0;
05235    if (index == SUB_REAL) {
05236       if (i->busydetect && CANBUSYDETECT(i))
05237          features |= DSP_FEATURE_BUSY_DETECT;
05238       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05239          features |= DSP_FEATURE_CALL_PROGRESS;
05240       if ((!i->outgoing && (i->callprogress & 4)) || 
05241           (i->outgoing && (i->callprogress & 2))) {
05242          features |= DSP_FEATURE_FAX_DETECT;
05243       }
05244 #ifdef ZT_TONEDETECT
05245       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05246       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05247 #endif      
05248          i->hardwaredtmf = 0;
05249          features |= DSP_FEATURE_DTMF_DETECT;
05250 #ifdef ZT_TONEDETECT
05251       } else if (NEED_MFDETECT(i)) {
05252          i->hardwaredtmf = 1;
05253          features |= DSP_FEATURE_DTMF_DETECT;
05254       }
05255 #endif
05256    }
05257    if (features) {
05258       if (i->dsp) {
05259          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05260       } else {
05261          if (i->channel != CHAN_PSEUDO)
05262             i->dsp = ast_dsp_new();
05263          else
05264             i->dsp = NULL;
05265          if (i->dsp) {
05266             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05267 #ifdef HAVE_PRI
05268             /* We cannot do progress detection until receives PROGRESS message */
05269             if (i->outgoing && (i->sig == SIG_PRI)) {
05270                /* Remember requested DSP features, don't treat
05271                   talking as ANSWER */
05272                features = 0;
05273             }
05274 #endif
05275             ast_dsp_set_features(i->dsp, features);
05276             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05277             if (!ast_strlen_zero(progzone))
05278                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05279             if (i->busydetect && CANBUSYDETECT(i)) {
05280                ast_dsp_set_busy_count(i->dsp, i->busycount);
05281                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05282             }
05283          }
05284       }
05285    }
05286       
05287    if (state == AST_STATE_RING)
05288       tmp->rings = 1;
05289    tmp->tech_pvt = i;
05290    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05291       /* Only FXO signalled stuff can be picked up */
05292       tmp->callgroup = i->callgroup;
05293       tmp->pickupgroup = i->pickupgroup;
05294    }
05295    if (!ast_strlen_zero(i->language))
05296       ast_string_field_set(tmp, language, i->language);
05297    if (!i->owner)
05298       i->owner = tmp;
05299    if (!ast_strlen_zero(i->accountcode))
05300       ast_string_field_set(tmp, accountcode, i->accountcode);
05301    if (i->amaflags)
05302       tmp->amaflags = i->amaflags;
05303    i->subs[index].owner = tmp;
05304    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05305    ast_string_field_set(tmp, call_forward, i->call_forward);
05306    /* If we've been told "no ADSI" then enforce it */
05307    if (!i->adsi)
05308       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05309    if (!ast_strlen_zero(i->exten))
05310       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05311    if (!ast_strlen_zero(i->rdnis))
05312       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05313    if (!ast_strlen_zero(i->dnid))
05314       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05315 
05316    /* Don't use ast_set_callerid() here because it will
05317     * generate a needless NewCallerID event */
05318 #ifdef PRI_ANI
05319    if (!ast_strlen_zero(i->cid_ani))
05320       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05321    else  
05322       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05323 #else
05324    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05325 #endif
05326    tmp->cid.cid_pres = i->callingpres;
05327    tmp->cid.cid_ton = i->cid_ton;
05328 #ifdef HAVE_PRI
05329    tmp->transfercapability = transfercapability;
05330    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05331    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05332       i->digital = 1;
05333    /* Assume calls are not idle calls unless we're told differently */
05334    i->isidlecall = 0;
05335    i->alreadyhungup = 0;
05336 #endif
05337    /* clear the fake event in case we posted one before we had ast_channel */
05338    i->fake_event = 0;
05339    /* Assure there is no confmute on this channel */
05340    zt_confmute(i, 0);
05341    /* Configure the new channel jb */
05342    ast_jb_configure(tmp, &global_jbconf);
05343    if (startpbx) {
05344       if (ast_pbx_start(tmp)) {
05345          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05346          ast_hangup(tmp);
05347          i->owner = NULL;
05348          return NULL;
05349       }
05350    }
05351 
05352    ast_module_ref(ast_module_info->self);
05353    
05354    return tmp;
05355 }
05356 
05357 
05358 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05359 {
05360    char c;
05361 
05362    *str = 0; /* start with empty output buffer */
05363    for (;;)
05364    {
05365       /* Wait for the first digit (up to specified ms). */
05366       c = ast_waitfordigit(chan, ms);
05367       /* if timeout, hangup or error, return as such */
05368       if (c < 1)
05369          return c;
05370       *str++ = c;
05371       *str = 0;
05372       if (strchr(term, c))
05373          return 1;
05374    }
05375 }
05376 
05377 static int zt_wink(struct zt_pvt *p, int index)
05378 {
05379    int j;
05380    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05381    for (;;)
05382    {
05383          /* set bits of interest */
05384       j = ZT_IOMUX_SIGEVENT;
05385           /* wait for some happening */
05386       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05387          /* exit loop if we have it */
05388       if (j & ZT_IOMUX_SIGEVENT) break;
05389    }
05390      /* get the event info */
05391    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05392    return 0;
05393 }
05394 
05395 static void *ss_thread(void *data)
05396 {
05397    struct ast_channel *chan = data;
05398    struct zt_pvt *p = chan->tech_pvt;
05399    char exten[AST_MAX_EXTENSION] = "";
05400    char exten2[AST_MAX_EXTENSION] = "";
05401    unsigned char buf[256];
05402    char dtmfcid[300];
05403    char dtmfbuf[300];
05404    struct callerid_state *cs = NULL;
05405    char *name = NULL, *number = NULL;
05406    int distMatches;
05407    int curRingData[3];
05408    int receivedRingT;
05409    int counter1;
05410    int counter;
05411    int samples = 0;
05412    struct ast_smdi_md_message *smdi_msg = NULL;
05413    int flags;
05414    int i;
05415    int timeout;
05416    int getforward = 0;
05417    char *s1, *s2;
05418    int len = 0;
05419    int res;
05420    int index;
05421 
05422    /* in the bizarre case where the channel has become a zombie before we
05423       even get started here, abort safely
05424    */
05425    if (!p) {
05426       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05427       ast_hangup(chan);
05428       return NULL;
05429    }
05430 
05431    if (option_verbose > 2) 
05432       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05433    index = zt_get_index(chan, p, 1);
05434    if (index < 0) {
05435       ast_log(LOG_WARNING, "Huh?\n");
05436       ast_hangup(chan);
05437       return NULL;
05438    }
05439    if (p->dsp)
05440       ast_dsp_digitreset(p->dsp);
05441    switch (p->sig) {
05442 #ifdef HAVE_PRI
05443    case SIG_PRI:
05444       /* Now loop looking for an extension */
05445       ast_copy_string(exten, p->exten, sizeof(exten));
05446       len = strlen(exten);
05447       res = 0;
05448       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05449          if (len && !ast_ignore_pattern(chan->context, exten))
05450             tone_zone_play_tone(p->subs[index].zfd, -1);
05451          else
05452             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05453          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05454             timeout = matchdigittimeout;
05455          else
05456             timeout = gendigittimeout;
05457          res = ast_waitfordigit(chan, timeout);
05458          if (res < 0) {
05459             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05460             ast_hangup(chan);
05461             return NULL;
05462          } else if (res) {
05463             exten[len++] = res;
05464             exten[len] = '\0';
05465          } else
05466             break;
05467       }
05468       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05469       if (ast_strlen_zero(exten)) {
05470          if (option_verbose > 2)
05471             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05472          exten[0] = 's';
05473          exten[1] = '\0';
05474       }
05475       tone_zone_play_tone(p->subs[index].zfd, -1);
05476       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05477          /* Start the real PBX */
05478          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05479          if (p->dsp) ast_dsp_digitreset(p->dsp);
05480          zt_enable_ec(p);
05481          ast_setstate(chan, AST_STATE_RING);
05482          res = ast_pbx_run(chan);
05483          if (res) {
05484             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05485          }
05486       } else {
05487          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05488          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05489          ast_hangup(chan);
05490          p->exten[0] = '\0';
05491          /* Since we send release complete here, we won't get one */
05492          p->call = NULL;
05493       }
05494       return NULL;
05495       break;
05496 #endif
05497    case SIG_FEATD:
05498    case SIG_FEATDMF:
05499    case SIG_FEATDMF_TA:
05500    case SIG_E911:
05501    case SIG_FGC_CAMAMF:
05502    case SIG_FEATB:
05503    case SIG_EMWINK:
05504    case SIG_SF_FEATD:
05505    case SIG_SF_FEATDMF:
05506    case SIG_SF_FEATB:
05507    case SIG_SFWINK:
05508       if (zt_wink(p, index))  
05509          return NULL;
05510       /* Fall through */
05511    case SIG_EM:
05512    case SIG_EM_E1:
05513    case SIG_SF:
05514    case SIG_FGC_CAMA:
05515       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05516       if (p->dsp)
05517          ast_dsp_digitreset(p->dsp);
05518       /* set digit mode appropriately */
05519       if (p->dsp) {
05520          if (NEED_MFDETECT(p))
05521             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05522          else 
05523             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05524       }
05525       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05526       /* Wait for the first digit only if immediate=no */
05527       if (!p->immediate)
05528          /* Wait for the first digit (up to 5 seconds). */
05529          res = ast_waitfordigit(chan, 5000);
05530       else
05531          res = 0;
05532       if (res > 0) {
05533          /* save first char */
05534          dtmfbuf[0] = res;
05535          switch (p->sig) {
05536          case SIG_FEATD:
05537          case SIG_SF_FEATD:
05538             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05539             if (res > 0)
05540                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05541             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05542             break;
05543          case SIG_FEATDMF_TA:
05544             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05545             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05546             if (zt_wink(p, index)) return NULL;
05547             dtmfbuf[0] = 0;
05548             /* Wait for the first digit (up to 5 seconds). */
05549             res = ast_waitfordigit(chan, 5000);
05550             if (res <= 0) break;
05551             dtmfbuf[0] = res;
05552             /* fall through intentionally */
05553          case SIG_FEATDMF:
05554          case SIG_E911:
05555          case SIG_FGC_CAMAMF:
05556          case SIG_SF_FEATDMF:
05557             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05558             /* if international caca, do it again to get real ANO */
05559             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05560             {
05561                if (zt_wink(p, index)) return NULL;
05562                dtmfbuf[0] = 0;
05563                /* Wait for the first digit (up to 5 seconds). */
05564                res = ast_waitfordigit(chan, 5000);
05565                if (res <= 0) break;
05566                dtmfbuf[0] = res;
05567                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05568             }
05569             if (res > 0) {
05570                /* if E911, take off hook */
05571                if (p->sig == SIG_E911)
05572                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05573                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05574             }
05575             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05576             break;
05577          case SIG_FEATB:
05578          case SIG_SF_FEATB:
05579             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05580             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05581             break;
05582          case SIG_EMWINK:
05583             /* if we received a '*', we are actually receiving Feature Group D
05584                dial syntax, so use that mode; otherwise, fall through to normal
05585                mode
05586             */
05587             if (res == '*') {
05588                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05589                if (res > 0)
05590                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05591                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05592                break;
05593             }
05594          default:
05595             /* If we got the first digit, get the rest */
05596             len = 1;
05597             dtmfbuf[len] = '\0';
05598             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05599                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05600                   timeout = matchdigittimeout;
05601                } else {
05602                   timeout = gendigittimeout;
05603                }
05604                res = ast_waitfordigit(chan, timeout);
05605                if (res < 0) {
05606                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05607                   ast_hangup(chan);
05608                   return NULL;
05609                } else if (res) {
05610                   dtmfbuf[len++] = res;
05611                   dtmfbuf[len] = '\0';
05612                } else {
05613                   break;
05614                }
05615             }
05616             break;
05617          }
05618       }
05619       if (res == -1) {
05620          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05621          ast_hangup(chan);
05622          return NULL;
05623       } else if (res < 0) {
05624          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05625          ast_hangup(chan);
05626          return NULL;
05627       }
05628 
05629       if (p->sig == SIG_FGC_CAMA) {
05630          char anibuf[100];
05631 
05632          if (ast_safe_sleep(chan,1000) == -1) {
05633                            ast_hangup(chan);
05634                            return NULL;
05635          }
05636                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05637                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05638                         res = my_getsigstr(chan, anibuf, "#", 10000);
05639                         if ((res > 0) && (strlen(anibuf) > 2)) {
05640             if (anibuf[strlen(anibuf) - 1] == '#')
05641                anibuf[strlen(anibuf) - 1] = 0;
05642             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05643          }
05644                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05645       }
05646 
05647       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05648       if (ast_strlen_zero(exten))
05649          ast_copy_string(exten, "s", sizeof(exten));
05650       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05651          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05652          if (exten[0] == '*') {
05653             char *stringp=NULL;
05654             ast_copy_string(exten2, exten, sizeof(exten2));
05655             /* Parse out extension and callerid */
05656             stringp=exten2 +1;
05657             s1 = strsep(&stringp, "*");
05658             s2 = strsep(&stringp, "*");
05659             if (s2) {
05660                if (!ast_strlen_zero(p->cid_num))
05661                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05662                else
05663                   ast_set_callerid(chan, s1, NULL, s1);
05664                ast_copy_string(exten, s2, sizeof(exten));
05665             } else
05666                ast_copy_string(exten, s1, sizeof(exten));
05667          } else if (p->sig == SIG_FEATD)
05668             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05669       }
05670       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05671          if (exten[0] == '*') {
05672             char *stringp=NULL;
05673             ast_copy_string(exten2, exten, sizeof(exten2));
05674             /* Parse out extension and callerid */
05675             stringp=exten2 +1;
05676             s1 = strsep(&stringp, "#");
05677             s2 = strsep(&stringp, "#");
05678             if (s2) {
05679                if (!ast_strlen_zero(p->cid_num))
05680                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05681                else
05682                   if (*(s1 + 2))
05683                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05684                ast_copy_string(exten, s2 + 1, sizeof(exten));
05685             } else
05686                ast_copy_string(exten, s1 + 2, sizeof(exten));
05687          } else
05688             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05689       }
05690       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05691          if (exten[0] == '*') {
05692             char *stringp=NULL;
05693             ast_copy_string(exten2, exten, sizeof(exten2));
05694             /* Parse out extension and callerid */
05695             stringp=exten2 +1;
05696             s1 = strsep(&stringp, "#");
05697             s2 = strsep(&stringp, "#");
05698             if (s2 && (*(s2 + 1) == '0')) {
05699                if (*(s2 + 2))
05700                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05701             }
05702             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05703             else ast_copy_string(exten, "911", sizeof(exten));
05704          } else
05705             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05706       }
05707       if (p->sig == SIG_FEATB) {
05708          if (exten[0] == '*') {
05709             char *stringp=NULL;
05710             ast_copy_string(exten2, exten, sizeof(exten2));
05711             /* Parse out extension and callerid */
05712             stringp=exten2 +1;
05713             s1 = strsep(&stringp, "#");
05714             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05715          } else
05716             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05717       }
05718       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05719          zt_wink(p, index);
05720                         /* some switches require a minimum guard time between
05721                            the last FGD wink and something that answers
05722                            immediately. This ensures it */
05723                         if (ast_safe_sleep(chan,100)) return NULL;
05724       }
05725       zt_enable_ec(p);
05726       if (NEED_MFDETECT(p)) {
05727          if (p->dsp) {
05728             if (!p->hardwaredtmf)
05729                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05730             else {
05731                ast_dsp_free(p->dsp);
05732                p->dsp = NULL;
05733             }
05734          }
05735       }
05736 
05737       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05738          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05739          if (p->dsp) ast_dsp_digitreset(p->dsp);
05740          res = ast_pbx_run(chan);
05741          if (res) {
05742             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05743             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05744          }
05745          return NULL;
05746       } else {
05747          if (option_verbose > 2)
05748             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05749          sleep(2);
05750          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05751          if (res < 0)
05752             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05753          else
05754             sleep(1);
05755          res = ast_streamfile(chan, "ss-noservice", chan->language);
05756          if (res >= 0)
05757             ast_waitstream(chan, "");
05758          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05759          ast_hangup(chan);
05760          return NULL;
05761       }
05762       break;
05763    case SIG_FXOLS:
05764    case SIG_FXOGS:
05765    case SIG_FXOKS:
05766       /* Read the first digit */
05767       timeout = firstdigittimeout;
05768       /* If starting a threeway call, never timeout on the first digit so someone
05769          can use flash-hook as a "hold" feature */
05770       if (p->subs[SUB_THREEWAY].owner) 
05771          timeout = 999999;
05772       while (len < AST_MAX_EXTENSION-1) {
05773          /* Read digit unless it's supposed to be immediate, in which case the
05774             only answer is 's' */
05775          if (p->immediate) 
05776             res = 's';
05777          else
05778             res = ast_waitfordigit(chan, timeout);
05779          timeout = 0;
05780          if (res < 0) {
05781             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05782             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05783             ast_hangup(chan);
05784             return NULL;
05785          } else if (res)  {
05786             exten[len++]=res;
05787             exten[len] = '\0';
05788          }
05789          if (!ast_ignore_pattern(chan->context, exten))
05790             tone_zone_play_tone(p->subs[index].zfd, -1);
05791          else
05792             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05793          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05794             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05795                if (getforward) {
05796                   /* Record this as the forwarding extension */
05797                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05798                   if (option_verbose > 2)
05799                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05800                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05801                   if (res)
05802                      break;
05803                   usleep(500000);
05804                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05805                   sleep(1);
05806                   memset(exten, 0, sizeof(exten));
05807                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05808                   len = 0;
05809                   getforward = 0;
05810                } else  {
05811                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05812                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05813                   if (!ast_strlen_zero(p->cid_num)) {
05814                      if (!p->hidecallerid)
05815                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05816                      else
05817                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05818                   }
05819                   if (!ast_strlen_zero(p->cid_name)) {
05820                      if (!p->hidecallerid)
05821                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05822                   }
05823                   ast_setstate(chan, AST_STATE_RING);
05824                   zt_enable_ec(p);
05825                   res = ast_pbx_run(chan);
05826                   if (res) {
05827                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05828                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05829                   }
05830                   return NULL;
05831                }
05832             } else {
05833                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05834                   so just set the timeout to matchdigittimeout and wait some more */
05835                timeout = matchdigittimeout;
05836             }
05837          } else if (res == 0) {
05838             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05839             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05840             zt_wait_event(p->subs[index].zfd);
05841             ast_hangup(chan);
05842             return NULL;
05843          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05844             if (option_verbose > 2) 
05845                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05846             /* Disable call waiting if enabled */
05847             p->callwaiting = 0;
05848             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05849             if (res) {
05850                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05851                   chan->name, strerror(errno));
05852             }
05853             len = 0;
05854             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05855             memset(exten, 0, sizeof(exten));
05856             timeout = firstdigittimeout;
05857                
05858          } else if (!strcmp(exten,ast_pickup_ext())) {
05859             /* Scan all channels and see if any there
05860              * ringing channqels with that have call groups
05861              * that equal this channels pickup group  
05862              */
05863             if (index == SUB_REAL) {
05864                /* Switch us from Third call to Call Wait */
05865                if (p->subs[SUB_THREEWAY].owner) {
05866                   /* If you make a threeway call and the *8# a call, it should actually 
05867                      look like a callwait */
05868                   alloc_sub(p, SUB_CALLWAIT);   
05869                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05870                   unalloc_sub(p, SUB_THREEWAY);
05871                }
05872                zt_enable_ec(p);
05873                if (ast_pickup_call(chan)) {
05874                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05875                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05876                   zt_wait_event(p->subs[index].zfd);
05877                }
05878                ast_hangup(chan);
05879                return NULL;
05880             } else {
05881                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05882                ast_hangup(chan);
05883                return NULL;
05884             }
05885             
05886          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05887             if (option_verbose > 2) 
05888                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05889             /* Disable Caller*ID if enabled */
05890             p->hidecallerid = 1;
05891             if (chan->cid.cid_num)
05892                free(chan->cid.cid_num);
05893             chan->cid.cid_num = NULL;
05894             if (chan->cid.cid_name)
05895                free(chan->cid.cid_name);
05896             chan->cid.cid_name = NULL;
05897             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05898             if (res) {
05899                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05900                   chan->name, strerror(errno));
05901             }
05902             len = 0;
05903             memset(exten, 0, sizeof(exten));
05904             timeout = firstdigittimeout;
05905          } else if (p->callreturn && !strcmp(exten, "*69")) {
05906             res = 0;
05907             if (!ast_strlen_zero(p->lastcid_num)) {
05908                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05909             }
05910             if (!res)
05911                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05912             break;
05913          } else if (!strcmp(exten, "*78")) {
05914             /* Do not disturb */
05915             if (option_verbose > 2)
05916                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05917             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05918                      "Channel: Zap/%d\r\n"
05919                      "Status: enabled\r\n", p->channel);
05920             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05921             p->dnd = 1;
05922             getforward = 0;
05923             memset(exten, 0, sizeof(exten));
05924             len = 0;
05925          } else if (!strcmp(exten, "*79")) {
05926             /* Do not disturb */
05927             if (option_verbose > 2)
05928                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05929             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05930                      "Channel: Zap/%d\r\n"
05931                      "Status: disabled\r\n", p->channel);
05932             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05933             p->dnd = 0;
05934             getforward = 0;
05935             memset(exten, 0, sizeof(exten));
05936             len = 0;
05937          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05938             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05939             getforward = 1;
05940             memset(exten, 0, sizeof(exten));
05941             len = 0;
05942          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05943             if (option_verbose > 2)
05944                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05945             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05946             memset(p->call_forward, 0, sizeof(p->call_forward));
05947             getforward = 0;
05948             memset(exten, 0, sizeof(exten));
05949             len = 0;
05950          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
05951                   p->subs[SUB_THREEWAY].owner &&
05952                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05953             /* This is a three way call, the main call being a real channel, 
05954                and we're parking the first call. */
05955             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
05956             if (option_verbose > 2)
05957                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
05958             break;
05959          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
05960             if (option_verbose > 2)
05961                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
05962             res = ast_db_put("blacklist", p->lastcid_num, "1");
05963             if (!res) {
05964                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05965                memset(exten, 0, sizeof(exten));
05966                len = 0;
05967             }
05968          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
05969             if (option_verbose > 2) 
05970                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
05971             /* Enable Caller*ID if enabled */
05972             p->hidecallerid = 0;
05973             if (chan->cid.cid_num)
05974                free(chan->cid.cid_num);
05975             chan->cid.cid_num = NULL;
05976             if (chan->cid.cid_name)
05977                free(chan->cid.cid_name);
05978             chan->cid.cid_name = NULL;
05979             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
05980             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05981             if (res) {
05982                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05983                   chan->name, strerror(errno));
05984             }
05985             len = 0;
05986             memset(exten, 0, sizeof(exten));
05987             timeout = firstdigittimeout;
05988          } else if (!strcmp(exten, "*0")) {
05989             struct ast_channel *nbridge = 
05990                p->subs[SUB_THREEWAY].owner;
05991             struct zt_pvt *pbridge = NULL;
05992               /* set up the private struct of the bridged one, if any */
05993             if (nbridge && ast_bridged_channel(nbridge)) 
05994                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
05995             if (nbridge && pbridge && 
05996                 (nbridge->tech == &zap_tech) && 
05997                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
05998                 ISTRUNK(pbridge)) {
05999                int func = ZT_FLASH;
06000                /* Clear out the dial buffer */
06001                p->dop.dialstr[0] = '\0';
06002                /* flash hookswitch */
06003                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06004                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06005                      nbridge->name, strerror(errno));
06006                }
06007                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06008                unalloc_sub(p, SUB_THREEWAY);
06009                p->owner = p->subs[SUB_REAL].owner;
06010                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06011                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06012                ast_hangup(chan);
06013                return NULL;
06014             } else {
06015                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06016                zt_wait_event(p->subs[index].zfd);
06017                tone_zone_play_tone(p->subs[index].zfd, -1);
06018                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06019                unalloc_sub(p, SUB_THREEWAY);
06020                p->owner = p->subs[SUB_REAL].owner;
06021                ast_hangup(chan);
06022                return NULL;
06023             }              
06024          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06025                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06026             if (option_debug)
06027                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);
06028             break;
06029          }
06030          if (!timeout)
06031             timeout = gendigittimeout;
06032          if (len && !ast_ignore_pattern(chan->context, exten))
06033             tone_zone_play_tone(p->subs[index].zfd, -1);
06034       }
06035       break;
06036    case SIG_FXSLS:
06037    case SIG_FXSGS:
06038    case SIG_FXSKS:
06039 #ifdef HAVE_PRI
06040       if (p->pri) {
06041          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06042          struct ast_frame *f;
06043          int res;
06044          time_t start;
06045 
06046          time(&start);
06047          ast_setstate(chan, AST_STATE_RING);
06048          while (time(NULL) < start + 3) {
06049             res = ast_waitfor(chan, 1000);
06050             if (res) {
06051                f = ast_read(chan);
06052                if (!f) {
06053                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06054                   ast_hangup(chan);
06055                   return NULL;
06056                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06057                   res = 1;
06058                } else
06059                   res = 0;
06060                ast_frfree(f);
06061                if (res) {
06062                   ast_log(LOG_DEBUG, "Got ring!\n");
06063                   res = 0;
06064                   break;
06065                }
06066             }
06067          }
06068       }
06069 #endif
06070       /* check for SMDI messages */
06071       if (p->use_smdi && p->smdi_iface) {
06072          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06073 
06074          if (smdi_msg != NULL) {
06075             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06076 
06077             if (smdi_msg->type == 'B')
06078                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06079             else if (smdi_msg->type == 'N')
06080                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06081 
06082             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06083          } else {
06084             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06085          }
06086       }
06087 
06088       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06089             number = smdi_msg->calling_st;
06090 
06091       /* If we want caller id, we're in a prering state due to a polarity reversal
06092        * and we're set to use a polarity reversal to trigger the start of caller id,
06093        * grab the caller id and wait for ringing to start... */
06094       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06095          /* If set to use DTMF CID signalling, listen for DTMF */
06096          if (p->cid_signalling == CID_SIG_DTMF) {
06097             int i = 0;
06098             cs = NULL;
06099             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06100                "channel %s\n", chan->name);
06101             zt_setlinear(p->subs[index].zfd, 0);
06102             res = 2000;
06103             for (;;) {
06104                struct ast_frame *f;
06105                res = ast_waitfor(chan, res);
06106                if (res <= 0) {
06107                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06108                      "Exiting simple switch\n");
06109                   ast_hangup(chan);
06110                   return NULL;
06111                } 
06112                f = ast_read(chan);
06113                if (!f)
06114                   break;
06115                if (f->frametype == AST_FRAME_DTMF) {
06116                   dtmfbuf[i++] = f->subclass;
06117                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06118                   res = 2000;
06119                }
06120                ast_frfree(f);
06121                if (chan->_state == AST_STATE_RING ||
06122                    chan->_state == AST_STATE_RINGING) 
06123                   break; /* Got ring */
06124             }
06125             dtmfbuf[i] = '\0';
06126             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06127             /* Got cid and ring. */
06128             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06129             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06130             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06131                dtmfcid, flags);
06132             /* If first byte is NULL, we have no cid */
06133             if (!ast_strlen_zero(dtmfcid)) 
06134                number = dtmfcid;
06135             else
06136                number = NULL;
06137          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06138          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06139             cs = callerid_new(p->cid_signalling);
06140             if (cs) {
06141                samples = 0;
06142 #if 1
06143                bump_gains(p);
06144 #endif            
06145                /* Take out of linear mode for Caller*ID processing */
06146                zt_setlinear(p->subs[index].zfd, 0);
06147                
06148                /* First we wait and listen for the Caller*ID */
06149                for (;;) {  
06150                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06151                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06152                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06153                      callerid_free(cs);
06154                      ast_hangup(chan);
06155                      return NULL;
06156                   }
06157                   if (i & ZT_IOMUX_SIGEVENT) {
06158                      res = zt_get_event(p->subs[index].zfd);
06159                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06160 
06161                      if (p->cid_signalling == CID_SIG_V23_JP) {
06162 #ifdef ZT_EVENT_RINGBEGIN
06163                         if (res == ZT_EVENT_RINGBEGIN) {
06164                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06165                            usleep(1);
06166                         }
06167 #endif
06168                      } else {
06169                         res = 0;
06170                         break;
06171                      }
06172                   } else if (i & ZT_IOMUX_READ) {
06173                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06174                      if (res < 0) {
06175                         if (errno != ELAST) {
06176                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06177                            callerid_free(cs);
06178                            ast_hangup(chan);
06179                            return NULL;
06180                         }
06181                         break;
06182                      }
06183                      samples += res;
06184 
06185                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06186                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06187                      } else {
06188                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06189                      }
06190 
06191                      if (res < 0) {
06192                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06193                         break;
06194                      } else if (res)
06195                         break;
06196                      else if (samples > (8000 * 10))
06197                         break;
06198                   }
06199                }
06200                if (res == 1) {
06201                   callerid_get(cs, &name, &number, &flags);
06202                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06203                }
06204                if (res < 0) {
06205                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06206                }
06207 
06208                if (p->cid_signalling == CID_SIG_V23_JP) {
06209                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06210                   usleep(1);
06211                   res = 4000;
06212                } else {
06213 
06214                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06215                   res = 2000;
06216                }
06217 
06218                for (;;) {
06219                   struct ast_frame *f;
06220                   res = ast_waitfor(chan, res);
06221                   if (res <= 0) {
06222                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06223                         "Exiting simple switch\n");
06224                      ast_hangup(chan);
06225                      return NULL;
06226                   } 
06227                   f = ast_read(chan);
06228                   ast_frfree(f);
06229                   if (chan->_state == AST_STATE_RING ||
06230                       chan->_state == AST_STATE_RINGING) 
06231                      break; /* Got ring */
06232                }
06233    
06234                /* We must have a ring by now, so, if configured, lets try to listen for
06235                 * distinctive ringing */ 
06236                if (p->usedistinctiveringdetection == 1) {
06237                   len = 0;
06238                   distMatches = 0;
06239                   /* Clear the current ring data array so we dont have old data in it. */
06240                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06241                      curRingData[receivedRingT] = 0;
06242                   receivedRingT = 0;
06243                   counter = 0;
06244                   counter1 = 0;
06245                   /* Check to see if context is what it should be, if not set to be. */
06246                   if (strcmp(p->context,p->defcontext) != 0) {
06247                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06248                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06249                   }
06250       
06251                   for (;;) {  
06252                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06253                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06254                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06255                         callerid_free(cs);
06256                         ast_hangup(chan);
06257                         return NULL;
06258                      }
06259                      if (i & ZT_IOMUX_SIGEVENT) {
06260                         res = zt_get_event(p->subs[index].zfd);
06261                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06262                         res = 0;
06263                         /* Let us detect distinctive ring */
06264       
06265                         curRingData[receivedRingT] = p->ringt;
06266       
06267                         if (p->ringt < p->ringt_base/2)
06268                            break;
06269                         /* Increment the ringT counter so we can match it against
06270                            values in zapata.conf for distinctive ring */
06271                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06272                            break;
06273                      } else if (i & ZT_IOMUX_READ) {
06274                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06275                         if (res < 0) {
06276                            if (errno != ELAST) {
06277                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06278                               callerid_free(cs);
06279                               ast_hangup(chan);
06280                               return NULL;
06281                            }
06282                            break;
06283                         }
06284                         if (p->ringt) 
06285                            p->ringt--;
06286                         if (p->ringt == 1) {
06287                            res = -1;
06288                            break;
06289                         }
06290                      }
06291                   }
06292                   if (option_verbose > 2)
06293                      /* this only shows up if you have n of the dring patterns filled in */
06294                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06295    
06296                   for (counter = 0; counter < 3; counter++) {
06297                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06298                      channel */
06299                      distMatches = 0;
06300                      for (counter1 = 0; counter1 < 3; counter1++) {
06301                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06302                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06303                            distMatches++;
06304                         }
06305                      }
06306                      if (distMatches == 3) {
06307                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06308                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06309                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06310                         if (option_verbose > 2)
06311                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06312                         break;
06313                      }
06314                   }
06315                }
06316                /* Restore linear mode (if appropriate) for Caller*ID processing */
06317                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06318 #if 1
06319                restore_gains(p);
06320 #endif            
06321             } else
06322                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06323          } else {
06324             ast_log(LOG_WARNING, "Channel %s in prering "
06325                "state, but I have nothing to do. "
06326                "Terminating simple switch, should be "
06327                "restarted by the actual ring.\n", 
06328                chan->name);
06329             ast_hangup(chan);
06330             return NULL;
06331          }
06332       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06333          /* FSK Bell202 callerID */
06334          cs = callerid_new(p->cid_signalling);
06335          if (cs) {
06336 #if 1
06337             bump_gains(p);
06338 #endif            
06339             samples = 0;
06340             len = 0;
06341             distMatches = 0;
06342             /* Clear the current ring data array so we dont have old data in it. */
06343             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06344                curRingData[receivedRingT] = 0;
06345             receivedRingT = 0;
06346             counter = 0;
06347             counter1 = 0;
06348             /* Check to see if context is what it should be, if not set to be. */
06349             if (strcmp(p->context,p->defcontext) != 0) {
06350                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06351                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06352             }
06353 
06354             /* Take out of linear mode for Caller*ID processing */
06355             zt_setlinear(p->subs[index].zfd, 0);
06356             for (;;) {  
06357                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06358                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06359                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06360                   callerid_free(cs);
06361                   ast_hangup(chan);
06362                   return NULL;
06363                }
06364                if (i & ZT_IOMUX_SIGEVENT) {
06365                   res = zt_get_event(p->subs[index].zfd);
06366                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06367                   res = 0;
06368                   /* Let us detect callerid when the telco uses distinctive ring */
06369 
06370                   curRingData[receivedRingT] = p->ringt;
06371 
06372                   if (p->ringt < p->ringt_base/2)
06373                      break;
06374                   /* Increment the ringT counter so we can match it against
06375                      values in zapata.conf for distinctive ring */
06376                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06377                      break;
06378                } else if (i & ZT_IOMUX_READ) {
06379                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06380                   if (res < 0) {
06381                      if (errno != ELAST) {
06382                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06383                         callerid_free(cs);
06384                         ast_hangup(chan);
06385                         return NULL;
06386                      }
06387                      break;
06388                   }
06389                   if (p->ringt) 
06390                      p->ringt--;
06391                   if (p->ringt == 1) {
06392                      res = -1;
06393                      break;
06394                   }
06395                   samples += res;
06396                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06397                   if (res < 0) {
06398                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06399                      break;
06400                   } else if (res)
06401                      break;
06402                   else if (samples > (8000 * 10))
06403                      break;
06404                }
06405             }
06406             if (res == 1) {
06407                callerid_get(cs, &name, &number, &flags);
06408                if (option_debug)
06409                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06410             }
06411             if (distinctiveringaftercid == 1) {
06412                /* Clear the current ring data array so we dont have old data in it. */
06413                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06414                   curRingData[receivedRingT] = 0;
06415                }
06416                receivedRingT = 0;
06417                if (option_verbose > 2)
06418                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06419                for (;;) {
06420                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06421                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06422                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06423                      callerid_free(cs);
06424                      ast_hangup(chan);
06425                      return NULL;
06426                   }
06427                   if (i & ZT_IOMUX_SIGEVENT) {
06428                      res = zt_get_event(p->subs[index].zfd);
06429                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06430                      res = 0;
06431                      /* Let us detect callerid when the telco uses distinctive ring */
06432 
06433                      curRingData[receivedRingT] = p->ringt;
06434 
06435                      if (p->ringt < p->ringt_base/2)
06436                         break;
06437                      /* Increment the ringT counter so we can match it against
06438                         values in zapata.conf for distinctive ring */
06439                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06440                         break;
06441                   } else if (i & ZT_IOMUX_READ) {
06442                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06443                      if (res < 0) {
06444                         if (errno != ELAST) {
06445                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06446                            callerid_free(cs);
06447                            ast_hangup(chan);
06448                            return NULL;
06449                         }
06450                         break;
06451                      }
06452                   if (p->ringt)
06453                      p->ringt--;
06454                      if (p->ringt == 1) {
06455                         res = -1;
06456                         break;
06457                      }
06458                   }
06459                }
06460             }
06461             if (p->usedistinctiveringdetection == 1) {
06462                if (option_verbose > 2)
06463                   /* this only shows up if you have n of the dring patterns filled in */
06464                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06465 
06466                for (counter = 0; counter < 3; counter++) {
06467                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06468                   channel */
06469                   if (option_verbose > 2)
06470                      /* this only shows up if you have n of the dring patterns filled in */
06471                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06472                         p->drings.ringnum[counter].ring[0],
06473                         p->drings.ringnum[counter].ring[1],
06474                         p->drings.ringnum[counter].ring[2]);
06475                   distMatches = 0;
06476                   for (counter1 = 0; counter1 < 3; counter1++) {
06477                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06478                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06479                         distMatches++;
06480                      }
06481                   }
06482                   if (distMatches == 3) {
06483                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06484                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06485                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06486                      if (option_verbose > 2)
06487                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06488                      break;
06489                   }
06490                }
06491             }
06492             /* Restore linear mode (if appropriate) for Caller*ID processing */
06493             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06494 #if 1
06495             restore_gains(p);
06496 #endif            
06497             if (res < 0) {
06498                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06499             }
06500          } else
06501             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06502       }
06503       else
06504          cs = NULL;
06505 
06506       if (number)
06507          ast_shrink_phone_number(number);
06508       ast_set_callerid(chan, number, name, number);
06509 
06510       if (smdi_msg)
06511          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06512 
06513       if (cs)
06514          callerid_free(cs);
06515 
06516       ast_setstate(chan, AST_STATE_RING);
06517       chan->rings = 1;
06518       p->ringt = p->ringt_base;
06519       res = ast_pbx_run(chan);
06520       if (res) {
06521          ast_hangup(chan);
06522          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06523       }
06524       return NULL;
06525    default:
06526       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06527       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06528       if (res < 0)
06529             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06530    }
06531    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06532    if (res < 0)
06533          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06534    ast_hangup(chan);
06535    return NULL;
06536 }
06537 
06538 /* destroy a zaptel channel, identified by its number */
06539 static int zap_destroy_channel_bynum(int channel)
06540 {
06541    struct zt_pvt *tmp = NULL;
06542    struct zt_pvt *prev = NULL;
06543 
06544    tmp = iflist;
06545    while (tmp) {
06546       if (tmp->channel == channel) {
06547          destroy_channel(prev, tmp, 1);
06548          return RESULT_SUCCESS;
06549       }
06550       prev = tmp;
06551       tmp = tmp->next;
06552    }
06553    return RESULT_FAILURE;
06554 }
06555 
06556 static int handle_init_event(struct zt_pvt *i, int event)
06557 {
06558    int res;
06559    pthread_t threadid;
06560    pthread_attr_t attr;
06561    struct ast_channel *chan;
06562    pthread_attr_init(&attr);
06563    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06564    /* Handle an event on a given channel for the monitor thread. */
06565    switch (event) {
06566    case ZT_EVENT_NONE:
06567    case ZT_EVENT_BITSCHANGED:
06568       break;
06569    case ZT_EVENT_WINKFLASH:
06570    case ZT_EVENT_RINGOFFHOOK:
06571       if (i->inalarm) break;
06572       if (i->radio) break;
06573       /* Got a ring/answer.  What kind of channel are we? */
06574       switch (i->sig) {
06575       case SIG_FXOLS:
06576       case SIG_FXOGS:
06577       case SIG_FXOKS:
06578          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06579          if (res && (errno == EBUSY))
06580             break;
06581          if (i->cidspill) {
06582             /* Cancel VMWI spill */
06583             free(i->cidspill);
06584             i->cidspill = NULL;
06585          }
06586          if (i->immediate) {
06587             zt_enable_ec(i);
06588             /* The channel is immediately up.  Start right away */
06589             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06590             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06591             if (!chan) {
06592                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06593                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06594                if (res < 0)
06595                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06596             }
06597          } else {
06598             /* Check for callerid, digits, etc */
06599             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06600             if (chan) {
06601                if (has_voicemail(i))
06602                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06603                else
06604                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06605                if (res < 0) 
06606                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06607                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06608                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06609                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06610                   if (res < 0)
06611                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06612                   ast_hangup(chan);
06613                }
06614             } else
06615                ast_log(LOG_WARNING, "Unable to create channel\n");
06616          }
06617          break;
06618       case SIG_FXSLS:
06619       case SIG_FXSGS:
06620       case SIG_FXSKS:
06621             i->ringt = i->ringt_base;
06622             /* Fall through */
06623       case SIG_EMWINK:
06624       case SIG_FEATD:
06625       case SIG_FEATDMF:
06626       case SIG_FEATDMF_TA:
06627       case SIG_E911:
06628       case SIG_FGC_CAMA:
06629       case SIG_FGC_CAMAMF:
06630       case SIG_FEATB:
06631       case SIG_EM:
06632       case SIG_EM_E1:
06633       case SIG_SFWINK:
06634       case SIG_SF_FEATD:
06635       case SIG_SF_FEATDMF:
06636       case SIG_SF_FEATB:
06637       case SIG_SF:
06638             /* Check for callerid, digits, etc */
06639             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06640             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06641                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06642                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06643                if (res < 0)
06644                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06645                ast_hangup(chan);
06646             } else if (!chan) {
06647                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06648             }
06649             break;
06650       default:
06651          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06652          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06653          if (res < 0)
06654                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06655          return -1;
06656       }
06657       break;
06658    case ZT_EVENT_NOALARM:
06659       i->inalarm = 0;
06660       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06661       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06662          "Channel: %d\r\n", i->channel);
06663       break;
06664    case ZT_EVENT_ALARM:
06665       i->inalarm = 1;
06666       res = get_alarms(i);
06667       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06668       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06669          "Alarm: %s\r\n"
06670          "Channel: %d\r\n",
06671          alarm2str(res), i->channel);
06672       /* fall thru intentionally */
06673    case ZT_EVENT_ONHOOK:
06674       if (i->radio)
06675          break;
06676       /* Back on hook.  Hang up. */
06677       switch (i->sig) {
06678       case SIG_FXOLS:
06679       case SIG_FXOGS:
06680       case SIG_FEATD:
06681       case SIG_FEATDMF:
06682       case SIG_FEATDMF_TA:
06683       case SIG_E911:
06684       case SIG_FGC_CAMA:
06685       case SIG_FGC_CAMAMF:
06686       case SIG_FEATB:
06687       case SIG_EM:
06688       case SIG_EM_E1:
06689       case SIG_EMWINK:
06690       case SIG_SF_FEATD:
06691       case SIG_SF_FEATDMF:
06692       case SIG_SF_FEATB:
06693       case SIG_SF:
06694       case SIG_SFWINK:
06695       case SIG_FXSLS:
06696       case SIG_FXSGS:
06697       case SIG_FXSKS:
06698       case SIG_GR303FXSKS:
06699          zt_disable_ec(i);
06700          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06701          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06702          break;
06703       case SIG_GR303FXOKS:
06704       case SIG_FXOKS:
06705          zt_disable_ec(i);
06706          /* Diddle the battery for the zhone */
06707 #ifdef ZHONE_HACK
06708          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06709          usleep(1);
06710 #endif         
06711          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06712          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06713          break;
06714       case SIG_PRI:
06715          zt_disable_ec(i);
06716          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06717          break;
06718       default:
06719          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06720          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06721          return -1;
06722       }
06723       break;
06724    case ZT_EVENT_POLARITY:
06725       switch (i->sig) {
06726       case SIG_FXSLS:
06727       case SIG_FXSKS:
06728       case SIG_FXSGS:
06729          if (i->cid_start == CID_START_POLARITY) {
06730             i->polarity = POLARITY_REV;
06731             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06732                    "CID detection on channel %d\n",
06733                    i->channel);
06734             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06735             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06736                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06737             }
06738          }
06739          break;
06740       default:
06741          ast_log(LOG_WARNING, "handle_init_event detected "
06742             "polarity reversal on non-FXO (SIG_FXS) "
06743             "interface %d\n", i->channel);
06744       }
06745       break;
06746    case ZT_EVENT_REMOVED: /* destroy channel */
06747       ast_log(LOG_NOTICE, 
06748             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
06749             i->channel);
06750       zap_destroy_channel_bynum(i->channel);
06751       break;
06752    }
06753    pthread_attr_destroy(&attr);
06754    return 0;
06755 }
06756 
06757 static void *do_monitor(void *data)
06758 {
06759    int count, res, res2, spoint, pollres=0;
06760    struct zt_pvt *i;
06761    struct zt_pvt *last = NULL;
06762    time_t thispass = 0, lastpass = 0;
06763    int found;
06764    char buf[1024];
06765    struct pollfd *pfds=NULL;
06766    int lastalloc = -1;
06767    /* This thread monitors all the frame relay interfaces which are not yet in use
06768       (and thus do not have a separate thread) indefinitely */
06769    /* From here on out, we die whenever asked */
06770 #if 0
06771    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06772       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06773       return NULL;
06774    }
06775    ast_log(LOG_DEBUG, "Monitor starting...\n");
06776 #endif
06777    for (;;) {
06778       /* Lock the interface list */
06779       ast_mutex_lock(&iflock);
06780       if (!pfds || (lastalloc != ifcount)) {
06781          if (pfds)
06782             free(pfds);
06783          if (ifcount) {
06784             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
06785                ast_mutex_unlock(&iflock);
06786                return NULL;
06787             }
06788          }
06789          lastalloc = ifcount;
06790       }
06791       /* Build the stuff we're going to poll on, that is the socket of every
06792          zt_pvt that does not have an associated owner channel */
06793       count = 0;
06794       i = iflist;
06795       while (i) {
06796          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06797             if (!i->owner && !i->subs[SUB_REAL].owner) {
06798                /* This needs to be watched, as it lacks an owner */
06799                pfds[count].fd = i->subs[SUB_REAL].zfd;
06800                pfds[count].events = POLLPRI;
06801                pfds[count].revents = 0;
06802                /* Message waiting or r2 channels also get watched for reading */
06803                if (i->cidspill)
06804                   pfds[count].events |= POLLIN;
06805                count++;
06806             }
06807          }
06808          i = i->next;
06809       }
06810       /* Okay, now that we know what to do, release the interface lock */
06811       ast_mutex_unlock(&iflock);
06812       
06813       pthread_testcancel();
06814       /* Wait at least a second for something to happen */
06815       res = poll(pfds, count, 1000);
06816       pthread_testcancel();
06817       /* Okay, poll has finished.  Let's see what happened.  */
06818       if (res < 0) {
06819          if ((errno != EAGAIN) && (errno != EINTR))
06820             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06821          continue;
06822       }
06823       /* Alright, lock the interface list again, and let's look and see what has
06824          happened */
06825       ast_mutex_lock(&iflock);
06826       found = 0;
06827       spoint = 0;
06828       lastpass = thispass;
06829       thispass = time(NULL);
06830       i = iflist;
06831       while (i) {
06832          if (thispass != lastpass) {
06833             if (!found && ((i == last) || ((i == iflist) && !last))) {
06834                last = i;
06835                if (last) {
06836                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06837                      (last->sig & __ZT_SIG_FXO)) {
06838                      res = ast_app_has_voicemail(last->mailbox, NULL);
06839                      if (last->msgstate != res) {
06840                         int x;
06841                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06842                         x = ZT_FLUSH_BOTH;
06843                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06844                         if (res2)
06845                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06846                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
06847                            /* Turn on on hook transfer for 4 seconds */
06848                            x = 4000;
06849                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06850                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06851                            last->cidpos = 0;
06852                            last->msgstate = res;
06853                            last->onhooktime = thispass;
06854                         }
06855                         found ++;
06856                      }
06857                   }
06858                   last = last->next;
06859                }
06860             }
06861          }
06862          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06863             if (i->radio && !i->owner)
06864             {
06865                res = zt_get_event(i->subs[SUB_REAL].zfd);
06866                if (res)
06867                {
06868                   if (option_debug)
06869                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06870                   /* Don't hold iflock while handling init events */
06871                   ast_mutex_unlock(&iflock);
06872                   handle_init_event(i, res);
06873                   ast_mutex_lock(&iflock);   
06874                }
06875                i = i->next;
06876                continue;
06877             }              
06878             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06879             if (pollres & POLLIN) {
06880                if (i->owner || i->subs[SUB_REAL].owner) {
06881 #ifdef HAVE_PRI
06882                   if (!i->pri)
06883 #endif                  
06884                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06885                   i = i->next;
06886                   continue;
06887                }
06888                if (!i->cidspill) {
06889                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06890                   i = i->next;
06891                   continue;
06892                }
06893                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06894                if (res > 0) {
06895                   /* We read some number of bytes.  Write an equal amount of data */
06896                   if (res > i->cidlen - i->cidpos) 
06897                      res = i->cidlen - i->cidpos;
06898                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06899                   if (res2 > 0) {
06900                      i->cidpos += res2;
06901                      if (i->cidpos >= i->cidlen) {
06902                         free(i->cidspill);
06903                         i->cidspill = 0;
06904                         i->cidpos = 0;
06905                         i->cidlen = 0;
06906                      }
06907                   } else {
06908                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06909                      i->msgstate = -1;
06910                   }
06911                } else {
06912                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06913                }
06914                if (option_debug)
06915                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06916                /* Don't hold iflock while handling init events -- race with chlock */
06917                ast_mutex_unlock(&iflock);
06918                handle_init_event(i, res);
06919                ast_mutex_lock(&iflock);   
06920             }
06921             if (pollres & POLLPRI) {
06922                if (i->owner || i->subs[SUB_REAL].owner) {
06923 #ifdef HAVE_PRI
06924                   if (!i->pri)
06925 #endif                  
06926                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06927                   i = i->next;
06928                   continue;
06929                }
06930                res = zt_get_event(i->subs[SUB_REAL].zfd);
06931                if (option_debug)
06932                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06933                /* Don't hold iflock while handling init events */
06934                ast_mutex_unlock(&iflock);
06935                handle_init_event(i, res);
06936                ast_mutex_lock(&iflock);   
06937             }
06938          }
06939          i=i->next;
06940       }
06941       ast_mutex_unlock(&iflock);
06942    }
06943    /* Never reached */
06944    return NULL;
06945    
06946 }
06947 
06948 static int restart_monitor(void)
06949 {
06950    pthread_attr_t attr;
06951    pthread_attr_init(&attr);
06952    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06953    /* If we're supposed to be stopped -- stay stopped */
06954    if (monitor_thread == AST_PTHREADT_STOP)
06955       return 0;
06956    ast_mutex_lock(&monlock);
06957    if (monitor_thread == pthread_self()) {
06958       ast_mutex_unlock(&monlock);
06959       ast_log(LOG_WARNING, "Cannot kill myself\n");
06960       return -1;
06961    }
06962    if (monitor_thread != AST_PTHREADT_NULL) {
06963       /* Wake up the thread */
06964       pthread_kill(monitor_thread, SIGURG);
06965    } else {
06966       /* Start a new monitor */
06967       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06968          ast_mutex_unlock(&monlock);
06969          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06970          pthread_attr_destroy(&attr);
06971          return -1;
06972       }
06973    }
06974    ast_mutex_unlock(&monlock);
06975    pthread_attr_destroy(&attr);
06976    return 0;
06977 }
06978 
06979 #ifdef HAVE_PRI
06980 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
06981 {
06982    int x;
06983    int trunkgroup;
06984    /* Get appropriate trunk group if there is one */
06985    trunkgroup = pris[*span].mastertrunkgroup;
06986    if (trunkgroup) {
06987       /* Select a specific trunk group */
06988       for (x = 0; x < NUM_SPANS; x++) {
06989          if (pris[x].trunkgroup == trunkgroup) {
06990             *span = x;
06991             return 0;
06992          }
06993       }
06994       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
06995       *span = -1;
06996    } else {
06997       if (pris[*span].trunkgroup) {
06998          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
06999          *span = -1;
07000       } else if (pris[*span].mastertrunkgroup) {
07001          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07002          *span = -1;
07003       } else {
07004          if (si->totalchans == 31) { /* if it's an E1 */
07005             pris[*span].dchannels[0] = 16 + offset;
07006          } else {
07007             pris[*span].dchannels[0] = 24 + offset;
07008          }
07009          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07010          pris[*span].offset = offset;
07011          pris[*span].span = *span + 1;
07012       }
07013    }
07014    return 0;
07015 }
07016 
07017 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07018 {
07019    struct zt_spaninfo si;
07020    ZT_PARAMS p;
07021    int fd;
07022    int span;
07023    int ospan=0;
07024    int x,y;
07025    for (x = 0; x < NUM_SPANS; x++) {
07026       if (pris[x].trunkgroup == trunkgroup) {
07027          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07028          return -1;
07029       }
07030    }
07031    for (y = 0; y < NUM_DCHANS; y++) {
07032       if (!channels[y]) 
07033          break;
07034       memset(&si, 0, sizeof(si));
07035       memset(&p, 0, sizeof(p));
07036       fd = open("/dev/zap/channel", O_RDWR);
07037       if (fd < 0) {
07038          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07039          return -1;
07040       }
07041       x = channels[y];
07042       if (ioctl(fd, ZT_SPECIFY, &x)) {
07043          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07044          zt_close(fd);
07045          return -1;
07046       }
07047       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07048          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07049          return -1;
07050       }
07051       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07052          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07053          zt_close(fd);
07054          return -1;
07055       }
07056       span = p.spanno - 1;
07057       if (pris[span].trunkgroup) {
07058          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07059          zt_close(fd);
07060          return -1;
07061       }
07062       if (pris[span].pvts[0]) {
07063          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07064          zt_close(fd);
07065          return -1;
07066       }
07067       if (!y) {
07068          pris[span].trunkgroup = trunkgroup;
07069          pris[span].offset = channels[y] - p.chanpos;
07070          ospan = span;
07071       }
07072       pris[ospan].dchannels[y] = channels[y];
07073       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07074       pris[span].span = span + 1;
07075       zt_close(fd);
07076    }
07077    return 0;   
07078 }
07079 
07080 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07081 {
07082    if (pris[span].mastertrunkgroup) {
07083       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);
07084       return -1;
07085    }
07086    pris[span].mastertrunkgroup = trunkgroup;
07087    pris[span].prilogicalspan = logicalspan;
07088    return 0;
07089 }
07090 
07091 #endif
07092 
07093 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
07094 {
07095    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07096    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07097    char fn[80];
07098 #if 1
07099    struct zt_bufferinfo bi;
07100 #endif
07101    struct zt_spaninfo si;
07102    int res;
07103    int span=0;
07104    int here = 0;
07105    int x;
07106    struct zt_pvt **wlist;
07107    struct zt_pvt **wend;
07108    ZT_PARAMS p;
07109 
07110    wlist = &iflist;
07111    wend = &ifend;
07112 
07113 #ifdef HAVE_PRI
07114    if (pri) {
07115       wlist = &pri->crvs;
07116       wend = &pri->crvend;
07117    }
07118 #endif
07119 
07120    tmp2 = *wlist;
07121    prev = NULL;
07122 
07123    while (tmp2) {
07124       if (!tmp2->destroy) {
07125          if (tmp2->channel == channel) {
07126             tmp = tmp2;
07127             here = 1;
07128             break;
07129          }
07130          if (tmp2->channel > channel) {
07131             break;
07132          }
07133       }
07134       prev = tmp2;
07135       tmp2 = tmp2->next;
07136    }
07137 
07138    if (!here && !reloading) {
07139       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07140          destroy_zt_pvt(&tmp);
07141          return NULL;
07142       }
07143       ast_mutex_init(&tmp->lock);
07144       ifcount++;
07145       for (x = 0; x < 3; x++)
07146          tmp->subs[x].zfd = -1;
07147       tmp->channel = channel;
07148    }
07149 
07150    if (tmp) {
07151       if (!here) {
07152          if ((channel != CHAN_PSEUDO) && !pri) {
07153             snprintf(fn, sizeof(fn), "%d", channel);
07154             /* Open non-blocking */
07155             if (!here)
07156                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07157             /* Allocate a zapata structure */
07158             if (tmp->subs[SUB_REAL].zfd < 0) {
07159                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);
07160                destroy_zt_pvt(&tmp);
07161                return NULL;
07162             }
07163             memset(&p, 0, sizeof(p));
07164             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07165             if (res < 0) {
07166                ast_log(LOG_ERROR, "Unable to get parameters\n");
07167                destroy_zt_pvt(&tmp);
07168                return NULL;
07169             }
07170             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07171                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));
07172                destroy_zt_pvt(&tmp);
07173                return NULL;
07174             }
07175             tmp->law = p.curlaw;
07176             tmp->span = p.spanno;
07177             span = p.spanno - 1;
07178          } else {
07179             if (channel == CHAN_PSEUDO)
07180                conf.chan.sig = 0;
07181             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07182                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07183                return NULL;
07184             }
07185          }
07186 #ifdef HAVE_PRI
07187          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07188             int offset;
07189             int myswitchtype;
07190             int matchesdchan;
07191             int x,y;
07192             offset = 0;
07193             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07194                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07195                destroy_zt_pvt(&tmp);
07196                return NULL;
07197             }
07198             if (span >= NUM_SPANS) {
07199                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07200                destroy_zt_pvt(&tmp);
07201                return NULL;
07202             } else {
07203                si.spanno = 0;
07204                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07205                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07206                   destroy_zt_pvt(&tmp);
07207                   return NULL;
07208                }
07209                /* Store the logical span first based upon the real span */
07210                tmp->logicalspan = pris[span].prilogicalspan;
07211                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07212                if (span < 0) {
07213                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07214                   destroy_zt_pvt(&tmp);
07215                   return NULL;
07216                }
07217                if (conf.chan.sig == SIG_PRI)
07218                   myswitchtype = conf.pri.switchtype;
07219                else
07220                   myswitchtype = PRI_SWITCH_GR303_TMC;
07221                /* Make sure this isn't a d-channel */
07222                matchesdchan=0;
07223                for (x = 0; x < NUM_SPANS; x++) {
07224                   for (y = 0; y < NUM_DCHANS; y++) {
07225                      if (pris[x].dchannels[y] == tmp->channel) {
07226                         matchesdchan = 1;
07227                         break;
07228                      }
07229                   }
07230                }
07231                offset = p.chanpos;
07232                if (!matchesdchan) {
07233                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07234                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07235                      destroy_zt_pvt(&tmp);
07236                      return NULL;
07237                   }
07238                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07239                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07240                      destroy_zt_pvt(&tmp);
07241                      return NULL;
07242                   }
07243                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07244                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07245                      destroy_zt_pvt(&tmp);
07246                      return NULL;
07247                   }
07248                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07249                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07250                      destroy_zt_pvt(&tmp);
07251                      return NULL;
07252                   }
07253                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07254                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07255                      destroy_zt_pvt(&tmp);
07256                      return NULL;
07257                   }
07258                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07259                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07260                      destroy_zt_pvt(&tmp);
07261                      return NULL;
07262                   }
07263                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07264                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07265                      destroy_zt_pvt(&tmp);
07266                      return NULL;
07267                   }
07268                   if (pris[span].numchans >= MAX_CHANNELS) {
07269                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07270                         pris[span].trunkgroup);
07271                      destroy_zt_pvt(&tmp);
07272                      return NULL;
07273                   }
07274                   pris[span].nodetype = conf.pri.nodetype;
07275                   pris[span].switchtype = myswitchtype;
07276                   pris[span].nsf = conf.pri.nsf;
07277                   pris[span].dialplan = conf.pri.dialplan;
07278                   pris[span].localdialplan = conf.pri.localdialplan;
07279                   pris[span].pvts[pris[span].numchans++] = tmp;
07280                   pris[span].minunused = conf.pri.minunused;
07281                   pris[span].minidle = conf.pri.minidle;
07282                   pris[span].overlapdial = conf.pri.overlapdial;
07283                   pris[span].facilityenable = conf.pri.facilityenable;
07284                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07285                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07286                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07287                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07288                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07289                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07290                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07291                   pris[span].resetinterval = conf.pri.resetinterval;
07292                   
07293                   tmp->pri = &pris[span];
07294                   tmp->prioffset = offset;
07295                   tmp->call = NULL;
07296                } else {
07297                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07298                   destroy_zt_pvt(&tmp);
07299                   return NULL;
07300                }
07301             }
07302          } else {
07303             tmp->prioffset = 0;
07304          }
07305 #endif
07306       } else {
07307          conf.chan.sig = tmp->sig;
07308          conf.chan.radio = tmp->radio;
07309          memset(&p, 0, sizeof(p));
07310          if (tmp->subs[SUB_REAL].zfd > -1)
07311             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07312       }
07313       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07314       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07315           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07316          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07317            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07318           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07319          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07320            (conf.chan.sig == SIG_SF_FEATB)) {
07321          p.starttime = 250;
07322       }
07323       if (conf.chan.radio) {
07324          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07325          p.channo = channel;
07326          p.rxwinktime = 1;
07327          p.rxflashtime = 1;
07328          p.starttime = 1;
07329          p.debouncetime = 5;
07330       }
07331       if (!conf.chan.radio) {
07332          p.channo = channel;
07333          /* Override timing settings based on config file */
07334          if (conf.timing.prewinktime >= 0)
07335             p.prewinktime = conf.timing.prewinktime;
07336          if (conf.timing.preflashtime >= 0)
07337             p.preflashtime = conf.timing.preflashtime;
07338          if (conf.timing.winktime >= 0)
07339             p.winktime = conf.timing.winktime;
07340          if (conf.timing.flashtime >= 0)
07341             p.flashtime = conf.timing.flashtime;
07342          if (conf.timing.starttime >= 0)
07343             p.starttime = conf.timing.starttime;
07344          if (conf.timing.rxwinktime >= 0)
07345             p.rxwinktime = conf.timing.rxwinktime;
07346          if (conf.timing.rxflashtime >= 0)
07347             p.rxflashtime = conf.timing.rxflashtime;
07348          if (conf.timing.debouncetime >= 0)
07349             p.debouncetime = conf.timing.debouncetime;
07350       }
07351       
07352       /* dont set parms on a pseudo-channel (or CRV) */
07353       if (tmp->subs[SUB_REAL].zfd >= 0)
07354       {
07355          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07356          if (res < 0) {
07357             ast_log(LOG_ERROR, "Unable to set parameters\n");
07358             destroy_zt_pvt(&tmp);
07359             return NULL;
07360          }
07361       }
07362 #if 1
07363       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07364          memset(&bi, 0, sizeof(bi));
07365          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07366          if (!res) {
07367             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07368             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07369             bi.numbufs = numbufs;
07370             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07371             if (res < 0) {
07372                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07373             }
07374          } else
07375             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07376       }
07377 #endif
07378       tmp->immediate = conf.chan.immediate;
07379       tmp->transfertobusy = conf.chan.transfertobusy;
07380       tmp->sig = conf.chan.sig;
07381       tmp->outsigmod = conf.chan.outsigmod;
07382       tmp->radio = conf.chan.radio;
07383       tmp->ringt_base = ringt_base;
07384       tmp->firstradio = 0;
07385       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07386          tmp->permcallwaiting = conf.chan.callwaiting;
07387       else
07388          tmp->permcallwaiting = 0;
07389       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07390       tmp->destroy = 0;
07391       tmp->drings = drings;
07392       tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection;
07393       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07394       tmp->threewaycalling = conf.chan.threewaycalling;
07395       tmp->adsi = conf.chan.adsi;
07396       tmp->use_smdi = conf.chan.use_smdi;
07397       tmp->permhidecallerid = conf.chan.hidecallerid;
07398       tmp->callreturn = conf.chan.callreturn;
07399       tmp->echocancel = conf.chan.echocancel;
07400       tmp->echotraining = conf.chan.echotraining;
07401       tmp->pulse = conf.chan.pulse;
07402       tmp->echocanbridged = conf.chan.echocanbridged;
07403       tmp->busydetect = conf.chan.busydetect;
07404       tmp->busycount = conf.chan.busycount;
07405       tmp->busy_tonelength = conf.chan.busy_tonelength;
07406       tmp->busy_quietlength = conf.chan.busy_quietlength;
07407       tmp->callprogress = conf.chan.callprogress;
07408       tmp->cancallforward = conf.chan.cancallforward;
07409       tmp->dtmfrelax = conf.chan.dtmfrelax;
07410       tmp->callwaiting = tmp->permcallwaiting;
07411       tmp->hidecallerid = tmp->permhidecallerid;
07412       tmp->channel = channel;
07413       tmp->stripmsd = conf.chan.stripmsd;
07414       tmp->use_callerid = conf.chan.use_callerid;
07415       tmp->cid_signalling = conf.chan.cid_signalling;
07416       tmp->cid_start = conf.chan.cid_start;
07417       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07418       tmp->restrictcid = conf.chan.restrictcid;
07419       tmp->use_callingpres = conf.chan.use_callingpres;
07420       tmp->priindication_oob = conf.chan.priindication_oob;
07421       tmp->priexclusive = conf.chan.priexclusive;
07422       if (tmp->usedistinctiveringdetection) {
07423          if (!tmp->use_callerid) {
07424             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07425             tmp->use_callerid = 1;
07426          }
07427       }
07428 
07429       if (tmp->cid_signalling == CID_SIG_SMDI) {
07430          if (!tmp->use_smdi) {
07431             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07432             tmp->use_smdi = 1;
07433          }
07434       }
07435       if (tmp->use_smdi) {
07436          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07437          if (!(tmp->smdi_iface)) {
07438             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07439             tmp->use_smdi = 0;
07440          }
07441       }
07442 
07443       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07444       tmp->amaflags = conf.chan.amaflags;
07445       if (!here) {
07446          tmp->confno = -1;
07447          tmp->propconfno = -1;
07448       }
07449       tmp->canpark = conf.chan.canpark;
07450       tmp->transfer = conf.chan.transfer;
07451       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07452       ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
07453       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07454       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07455       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07456       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07457       tmp->cid_ton = 0;
07458       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07459       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07460       tmp->msgstate = -1;
07461       tmp->group = conf.chan.group;
07462       tmp->callgroup = conf.chan.callgroup;
07463       tmp->pickupgroup= conf.chan.pickupgroup;
07464       tmp->rxgain = conf.chan.rxgain;
07465       tmp->txgain = conf.chan.txgain;
07466       tmp->tonezone = conf.chan.tonezone;
07467       tmp->onhooktime = time(NULL);
07468       if (tmp->subs[SUB_REAL].zfd > -1) {
07469          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07470          if (tmp->dsp)
07471             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07472          update_conf(tmp);
07473          if (!here) {
07474             if (conf.chan.sig != SIG_PRI)
07475                /* Hang it up to be sure it's good */
07476                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07477          }
07478          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07479 #ifdef HAVE_PRI
07480          /* the dchannel is down so put the channel in alarm */
07481          if (tmp->pri && !pri_is_up(tmp->pri))
07482             tmp->inalarm = 1;
07483          else
07484             tmp->inalarm = 0;
07485 #endif            
07486          memset(&si, 0, sizeof(si));
07487          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07488             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07489             destroy_zt_pvt(&tmp);
07490             return NULL;
07491          }
07492          if (si.alarms) tmp->inalarm = 1;
07493       }
07494 
07495       tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
07496       tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
07497       tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
07498       tmp->sendcalleridafter = conf.chan.sendcalleridafter;
07499 
07500    }
07501    if (tmp && !here) {
07502       /* nothing on the iflist */
07503       if (!*wlist) {
07504          *wlist = tmp;
07505          tmp->prev = NULL;
07506          tmp->next = NULL;
07507          *wend = tmp;
07508       } else {
07509          /* at least one member on the iflist */
07510          struct zt_pvt *working = *wlist;
07511 
07512          /* check if we maybe have to put it on the begining */
07513          if (working->channel > tmp->channel) {
07514             tmp->next = *wlist;
07515             tmp->prev = NULL;
07516             (*wlist)->prev = tmp;
07517             *wlist = tmp;
07518          } else {
07519          /* go through all the members and put the member in the right place */
07520             while (working) {
07521                /* in the middle */
07522                if (working->next) {
07523                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07524                      tmp->next = working->next;
07525                      tmp->prev = working;
07526                      working->next->prev = tmp;
07527                      working->next = tmp;
07528                      break;
07529                   }
07530                } else {
07531                /* the last */
07532                   if (working->channel < tmp->channel) {
07533                      working->next = tmp;
07534                      tmp->next = NULL;
07535                      tmp->prev = working;
07536                      *wend = tmp;
07537                      break;
07538                   }
07539                }
07540                working = working->next;
07541             }
07542          }
07543       }
07544    }
07545    return tmp;
07546 }
07547 
07548 static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
07549 {
07550    int res;
07551    ZT_PARAMS par;
07552 
07553    /* First, check group matching */
07554    if (groupmatch) {
07555       if ((p->group & groupmatch) != groupmatch)
07556          return 0;
07557       *groupmatched = 1;
07558    }
07559    /* Check to see if we have a channel match */
07560    if (channelmatch != -1) {
07561       if (p->channel != channelmatch)
07562          return 0;
07563       *channelmatched = 1;
07564    }
07565    /* We're at least busy at this point */
07566    if (busy) {
07567       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07568          *busy = 1;
07569    }
07570    /* If do not disturb, definitely not */
07571    if (p->dnd)
07572       return 0;
07573    /* If guard time, definitely not */
07574    if (p->guardtime && (time(NULL) < p->guardtime)) 
07575       return 0;
07576       
07577    /* If no owner definitely available */
07578    if (!p->owner) {
07579 #ifdef HAVE_PRI
07580       /* Trust PRI */
07581       if (p->pri) {
07582          if (p->resetting || p->call)
07583             return 0;
07584          else
07585             return 1;
07586       }
07587 #endif
07588       if (!(p->radio || (p->oprmode < 0)))
07589       {
07590          if (!p->sig || (p->sig == SIG_FXSLS))
07591             return 1;
07592          /* Check hook state */
07593          if (p->subs[SUB_REAL].zfd > -1)
07594             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07595          else {
07596             /* Assume not off hook on CVRS */
07597             res = 0;
07598             par.rxisoffhook = 0;
07599          }
07600          if (res) {
07601             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07602          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07603             /* When "onhook" that means no battery on the line, and thus
07604               it is out of service..., if it's on a TDM card... If it's a channel
07605               bank, there is no telling... */
07606             if (par.rxbits > -1)
07607                return 1;
07608             if (par.rxisoffhook)
07609                return 1;
07610             else
07611 #ifdef ZAP_CHECK_HOOKSTATE
07612                return 0;
07613 #else
07614                return 1;
07615 #endif
07616          } else if (par.rxisoffhook) {
07617             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07618             /* Not available when the other end is off hook */
07619             return 0;
07620          }
07621       }
07622       return 1;
07623    }
07624 
07625    /* If it's not an FXO, forget about call wait */
07626    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07627       return 0;
07628 
07629    if (!p->callwaiting) {
07630       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07631       return 0;
07632    }
07633 
07634    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07635       /* If there is already a call waiting call, then we can't take a second one */
07636       return 0;
07637    }
07638    
07639    if ((p->owner->_state != AST_STATE_UP) &&
07640        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07641       /* If the current call is not up, then don't allow the call */
07642       return 0;
07643    }
07644    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07645       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07646       return 0;
07647    }
07648    /* We're cool */
07649    return 1;
07650 }
07651 
07652 static struct zt_pvt *chandup(struct zt_pvt *src)
07653 {
07654    struct zt_pvt *p;
07655    ZT_BUFFERINFO bi;
07656    int res;
07657    
07658    if ((p = ast_malloc(sizeof(*p)))) {
07659       memcpy(p, src, sizeof(struct zt_pvt));
07660       ast_mutex_init(&p->lock);
07661       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07662       /* Allocate a zapata structure */
07663       if (p->subs[SUB_REAL].zfd < 0) {
07664          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07665          destroy_zt_pvt(&p);
07666          return NULL;
07667       }
07668       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07669       if (!res) {
07670          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07671          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07672          bi.numbufs = numbufs;
07673          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07674          if (res < 0) {
07675             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07676          }
07677       } else
07678          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07679    }
07680    p->destroy = 1;
07681    p->next = iflist;
07682    iflist = p;
07683    return p;
07684 }
07685    
07686 
07687 #ifdef HAVE_PRI
07688 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
07689 {
07690    int x;
07691    if (backwards)
07692       x = pri->numchans;
07693    else
07694       x = 0;
07695    for (;;) {
07696       if (backwards && (x < 0))
07697          break;
07698       if (!backwards && (x >= pri->numchans))
07699          break;
07700       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
07701          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
07702             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
07703          return x;
07704       }
07705       if (backwards)
07706          x--;
07707       else
07708          x++;
07709    }
07710    return -1;
07711 }
07712 #endif
07713 
07714 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
07715 {
07716    int groupmatch = 0;
07717    int channelmatch = -1;
07718    int roundrobin = 0;
07719    int callwait = 0;
07720    int busy = 0;
07721    struct zt_pvt *p;
07722    struct ast_channel *tmp = NULL;
07723    char *dest=NULL;
07724    int x;
07725    char *s;
07726    char opt=0;
07727    int res=0, y=0;
07728    int backwards = 0;
07729 #ifdef HAVE_PRI
07730    int crv;
07731    int bearer = -1;
07732    int trunkgroup;
07733    struct zt_pri *pri=NULL;
07734 #endif   
07735    struct zt_pvt *exit, *start, *end;
07736    ast_mutex_t *lock;
07737    int channelmatched = 0;
07738    int groupmatched = 0;
07739    
07740    /* Assume we're locking the iflock */
07741    lock = &iflock;
07742    start = iflist;
07743    end = ifend;
07744    if (data) {
07745       dest = ast_strdupa((char *)data);
07746    } else {
07747       ast_log(LOG_WARNING, "Channel requested with no data\n");
07748       return NULL;
07749    }
07750    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07751       /* Retrieve the group number */
07752       char *stringp=NULL;
07753       stringp=dest + 1;
07754       s = strsep(&stringp, "/");
07755       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07756          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07757          return NULL;
07758       }
07759       groupmatch = 1 << x;
07760       if (toupper(dest[0]) == 'G') {
07761          if (dest[0] == 'G') {
07762             backwards = 1;
07763             p = ifend;
07764          } else
07765             p = iflist;
07766       } else {
07767          if (dest[0] == 'R') {
07768             backwards = 1;
07769             p = round_robin[x]?round_robin[x]->prev:ifend;
07770             if (!p)
07771                p = ifend;
07772          } else {
07773             p = round_robin[x]?round_robin[x]->next:iflist;
07774             if (!p)
07775                p = iflist;
07776          }
07777          roundrobin = 1;
07778       }
07779    } else {
07780       char *stringp=NULL;
07781       stringp=dest;
07782       s = strsep(&stringp, "/");
07783       p = iflist;
07784       if (!strcasecmp(s, "pseudo")) {
07785          /* Special case for pseudo */
07786          x = CHAN_PSEUDO;
07787          channelmatch = x;
07788       } 
07789 #ifdef HAVE_PRI
07790       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07791          if ((trunkgroup < 1) || (crv < 1)) {
07792             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07793             return NULL;
07794          }
07795          res--;
07796          for (x = 0; x < NUM_SPANS; x++) {
07797             if (pris[x].trunkgroup == trunkgroup) {
07798                pri = pris + x;
07799                lock = &pri->lock;
07800                start = pri->crvs;
07801                end = pri->crvend;
07802                break;
07803             }
07804          }
07805          if (!pri) {
07806             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07807             return NULL;
07808          }
07809          channelmatch = crv;
07810          p = pris[x].crvs;
07811       }
07812 #endif   
07813       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07814          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07815          return NULL;
07816       } else {
07817          channelmatch = x;
07818       }
07819    }
07820    /* Search for an unowned channel */
07821    ast_mutex_lock(lock);
07822    exit = p;
07823    while (p && !tmp) {
07824       if (roundrobin)
07825          round_robin[x] = p;
07826 #if 0
07827       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07828 #endif
07829 
07830       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07831          if (option_debug)
07832             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07833             if (p->inalarm) 
07834                goto next;
07835 
07836          callwait = (p->owner != NULL);
07837 #ifdef HAVE_PRI
07838          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07839             if (p->sig != SIG_FXSKS) {
07840                /* Gotta find an actual channel to use for this
07841                   CRV if this isn't a callwait */
07842                bearer = pri_find_empty_chan(pri, 0);
07843                if (bearer < 0) {
07844                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07845                   p = NULL;
07846                   break;
07847                }
07848                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07849             } else {
07850                if (alloc_sub(p, 0)) {
07851                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07852                   p = NULL;
07853                   break;
07854                } else
07855                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07856                p->pri = pri;
07857             }
07858          }
07859 #endif         
07860          if (p->channel == CHAN_PSEUDO) {
07861             p = chandup(p);
07862             if (!p) {
07863                break;
07864             }
07865          }
07866          if (p->owner) {
07867             if (alloc_sub(p, SUB_CALLWAIT)) {
07868                p = NULL;
07869                break;
07870             }
07871          }
07872          p->outgoing = 1;
07873          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07874 #ifdef HAVE_PRI
07875          if (p->bearer) {
07876             /* Log owner to bearer channel, too */
07877             p->bearer->owner = tmp;
07878          }
07879 #endif         
07880          /* Make special notes */
07881          if (res > 1) {
07882             if (opt == 'c') {
07883                /* Confirm answer */
07884                p->confirmanswer = 1;
07885             } else if (opt == 'r') {
07886                /* Distinctive ring */
07887                if (res < 3)
07888                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07889                else
07890                   p->distinctivering = y;
07891             } else if (opt == 'd') {
07892                /* If this is an ISDN call, make it digital */
07893                p->digital = 1;
07894                if (tmp)
07895                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07896             } else {
07897                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07898             }
07899          }
07900          /* Note if the call is a call waiting call */
07901          if (tmp && callwait)
07902             tmp->cdrflags |= AST_CDR_CALLWAIT;
07903          break;
07904       }
07905 next:
07906       if (backwards) {
07907          p = p->prev;
07908          if (!p)
07909             p = end;
07910       } else {
07911          p = p->next;
07912          if (!p)
07913             p = start;
07914       }
07915       /* stop when you roll to the one that we started from */
07916       if (p == exit)
07917          break;
07918    }
07919    ast_mutex_unlock(lock);
07920    restart_monitor();
07921    if (callwait)
07922       *cause = AST_CAUSE_BUSY;
07923    else if (!tmp) {
07924       if (channelmatched) {
07925          if (busy)
07926             *cause = AST_CAUSE_BUSY;
07927       } else if (groupmatched) {
07928          *cause = AST_CAUSE_CONGESTION;
07929       }
07930    }
07931       
07932    return tmp;
07933 }
07934 
07935 
07936 #ifdef HAVE_PRI
07937 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
07938 {
07939    struct zt_pvt *p;
07940    p = pri->crvs;
07941    while (p) {
07942       if (p->channel == crv)
07943          return p;
07944       p = p->next;
07945    }
07946    return NULL;
07947 }
07948 
07949 
07950 static int pri_find_principle(struct zt_pri *pri, int channel)
07951 {
07952    int x;
07953    int span = PRI_SPAN(channel);
07954    int spanfd;
07955    ZT_PARAMS param;
07956    int principle = -1;
07957    int explicit = PRI_EXPLICIT(channel);
07958    channel = PRI_CHANNEL(channel);
07959 
07960    if (!explicit) {
07961       spanfd = pri_active_dchan_fd(pri);
07962       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
07963          return -1;
07964       span = pris[param.spanno - 1].prilogicalspan;
07965    }
07966 
07967    for (x = 0; x < pri->numchans; x++) {
07968       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
07969          principle = x;
07970          break;
07971       }
07972    }
07973    
07974    return principle;
07975 }
07976 
07977 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
07978 {
07979    int x;
07980    struct zt_pvt *crv;
07981    if (!c) {
07982       if (principle < 0)
07983          return -1;
07984       return principle;
07985    }
07986    if ((principle > -1) && 
07987       (principle < pri->numchans) && 
07988       (pri->pvts[principle]) && 
07989       (pri->pvts[principle]->call == c))
07990       return principle;
07991    /* First, check for other bearers */
07992    for (x = 0; x < pri->numchans; x++) {
07993       if (!pri->pvts[x])
07994          continue;
07995       if (pri->pvts[x]->call == c) {
07996          /* Found our call */
07997          if (principle != x) {
07998             if (option_verbose > 2)
07999                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08000                   pri->pvts[x]->channel, pri->pvts[principle]->channel);
08001             if (pri->pvts[principle]->owner) {
08002                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08003                   pri->pvts[x]->channel, pri->pvts[principle]->channel, pri->pvts[principle]->channel);
08004                return -1;
08005             }
08006             /* Fix it all up now */
08007             pri->pvts[principle]->owner = pri->pvts[x]->owner;
08008             if (pri->pvts[principle]->owner) {
08009                ast_string_field_build(pri->pvts[principle]->owner, name, 
08010                             "Zap/%d:%d-%d", pri->trunkgroup,
08011                             pri->pvts[principle]->channel, 1);
08012                pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
08013                pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
08014                pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
08015             } else
08016                ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", pri->pvts[x]->channel, pri->pvts[principle]->channel);
08017             pri->pvts[principle]->call = pri->pvts[x]->call;
08018             /* Free up the old channel, now not in use */
08019             pri->pvts[x]->subs[SUB_REAL].owner = NULL;
08020             pri->pvts[x]->owner = NULL;
08021             pri->pvts[x]->call = NULL;
08022          }
08023          return principle;
08024       }
08025    }
08026    /* Now check for a CRV with no bearer */
08027    crv = pri->crvs;
08028    while (crv) {
08029       if (crv->call == c) {
08030          /* This is our match...  Perform some basic checks */
08031          if (crv->bearer)
08032             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08033          else if (pri->pvts[principle]->owner) 
08034             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08035          else {
08036             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08037                wakeup the potential sleeper */
08038             zt_close(crv->subs[SUB_REAL].zfd);
08039             pri->pvts[principle]->call = crv->call;
08040             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08041             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08042                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08043                            pri->trunkgroup, crv->channel);
08044             wakeup_sub(crv, SUB_REAL, pri);
08045          }
08046          return principle;
08047       }
08048       crv = crv->next;
08049    }
08050    ast_log(LOG_WARNING, "Call specified, but not found?\n");
08051    return -1;
08052 }
08053 
08054 static void *do_idle_thread(void *vchan)
08055 {
08056    struct ast_channel *chan = vchan;
08057    struct zt_pvt *pvt = chan->tech_pvt;
08058    struct ast_frame *f;
08059    char ex[80];
08060    /* Wait up to 30 seconds for an answer */
08061    int newms, ms = 30000;
08062    if (option_verbose > 2) 
08063       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08064    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08065    if (ast_call(chan, ex, 0)) {
08066       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08067       ast_hangup(chan);
08068       return NULL;
08069    }
08070    while ((newms = ast_waitfor(chan, ms)) > 0) {
08071       f = ast_read(chan);
08072       if (!f) {
08073          /* Got hangup */
08074          break;
08075       }
08076       if (f->frametype == AST_FRAME_CONTROL) {
08077          switch (f->subclass) {
08078          case AST_CONTROL_ANSWER:
08079             /* Launch the PBX */
08080             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08081             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08082             chan->priority = 1;
08083             if (option_verbose > 3) 
08084                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08085             ast_pbx_run(chan);
08086             /* It's already hungup, return immediately */
08087             return NULL;
08088          case AST_CONTROL_BUSY:
08089             if (option_verbose > 3) 
08090                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08091             break;
08092          case AST_CONTROL_CONGESTION:
08093             if (option_verbose > 3) 
08094                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08095             break;
08096          };
08097       }
08098       ast_frfree(f);
08099       ms = newms;
08100    }
08101    /* Hangup the channel since nothing happend */
08102    ast_hangup(chan);
08103    return NULL;
08104 }
08105 
08106 #ifndef PRI_RESTART
08107 #error "Upgrade your libpri"
08108 #endif
08109 static void zt_pri_message(struct pri *pri, char *s)
08110 {
08111    int x, y;
08112    int dchan = -1, span = -1;
08113    int dchancount = 0;
08114 
08115    if (pri) {
08116       for (x = 0; x < NUM_SPANS; x++) {
08117          for (y = 0; y < NUM_DCHANS; y++) {
08118             if (pris[x].dchans[y])
08119                dchancount++;
08120 
08121             if (pris[x].dchans[y] == pri)
08122                dchan = y;
08123          }
08124          if (dchan >= 0) {
08125             span = x;
08126             break;
08127          }
08128          dchancount = 0;
08129       }
08130       if ((dchan >= 0) && (span >= 0)) {
08131          if (dchancount > 1)
08132             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
08133          else
08134             ast_verbose("%s", s);
08135       } else
08136          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08137    } else
08138       ast_verbose("%s", s);
08139 
08140    ast_mutex_lock(&pridebugfdlock);
08141 
08142    if (pridebugfd >= 0)
08143       write(pridebugfd, s, strlen(s));
08144 
08145    ast_mutex_unlock(&pridebugfdlock);
08146 }
08147 
08148 static void zt_pri_error(struct pri *pri, char *s)
08149 {
08150    int x, y;
08151    int dchan = -1, span = -1;
08152    int dchancount = 0;
08153 
08154    if (pri) {
08155       for (x = 0; x < NUM_SPANS; x++) {
08156          for (y = 0; y < NUM_DCHANS; y++) {
08157             if (pris[x].dchans[y])
08158                dchancount++;
08159 
08160             if (pris[x].dchans[y] == pri)
08161                dchan = y;
08162          }
08163          if (dchan >= 0) {
08164             span = x;
08165             break;
08166          }
08167          dchancount = 0;
08168       }
08169       if ((dchan >= 0) && (span >= 0)) {
08170          if (dchancount > 1)
08171             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
08172          else
08173             ast_log(LOG_ERROR, "%s", s);
08174       } else
08175          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08176    } else
08177       ast_log(LOG_ERROR, "%s", s);
08178 
08179    ast_mutex_lock(&pridebugfdlock);
08180 
08181    if (pridebugfd >= 0)
08182       write(pridebugfd, s, strlen(s));
08183 
08184    ast_mutex_unlock(&pridebugfdlock);
08185 }
08186 
08187 static int pri_check_restart(struct zt_pri *pri)
08188 {
08189    do {
08190       pri->resetpos++;
08191    } while ((pri->resetpos < pri->numchans) &&
08192        (!pri->pvts[pri->resetpos] ||
08193         pri->pvts[pri->resetpos]->call ||
08194         pri->pvts[pri->resetpos]->resetting));
08195    if (pri->resetpos < pri->numchans) {
08196       /* Mark the channel as resetting and restart it */
08197       pri->pvts[pri->resetpos]->resetting = 1;
08198       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08199    } else {
08200       pri->resetting = 0;
08201       time(&pri->lastreset);
08202    }
08203    return 0;
08204 }
08205 
08206 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08207 {
08208    int x;
08209    int redo;
08210    ast_mutex_unlock(&pri->lock);
08211    ast_mutex_lock(&p->lock);
08212    do {
08213       redo = 0;
08214       for (x = 0; x < 3; x++) {
08215          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08216             redo++;
08217             ast_mutex_unlock(&p->lock);
08218             usleep(1);
08219             ast_mutex_lock(&p->lock);
08220          }
08221          if (p->subs[x].owner) {
08222             ast_queue_hangup(p->subs[x].owner);
08223             ast_mutex_unlock(&p->subs[x].owner->lock);
08224          }
08225       }
08226    } while (redo);
08227    ast_mutex_unlock(&p->lock);
08228    ast_mutex_lock(&pri->lock);
08229    return 0;
08230 }
08231 
08232 static char * redirectingreason2str(int redirectingreason)
08233 {
08234    switch (redirectingreason) {
08235    case 0:
08236       return "UNKNOWN";
08237    case 1:
08238       return "BUSY";
08239    case 2:
08240       return "NO_REPLY";
08241    case 0xF:
08242       return "UNCONDITIONAL";
08243    default:
08244       return "NOREDIRECT";
08245    }
08246 }
08247 
08248 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08249 {
08250    switch (plan) {
08251    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08252       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08253       break;
08254    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08255       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08256       break;
08257    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08258       snprintf(buf, size, "%s%s", pri->localprefix, number);
08259       break;
08260    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08261       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08262       break;
08263    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08264       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08265       break;
08266    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08267       snprintf(buf, size, "%s", number);
08268       break;
08269    }
08270 }
08271 
08272 static int zt_setlaw(int zfd, int law)
08273 {
08274    int res;
08275    res = ioctl(zfd, ZT_SETLAW, &law);
08276    if (res)
08277       return res;
08278    return 0;
08279 }
08280 
08281 static void *pri_dchannel(void *vpri)
08282 {
08283    struct zt_pri *pri = vpri;
08284    pri_event *e;
08285    struct pollfd fds[NUM_DCHANS];
08286    int res;
08287    int chanpos = 0;
08288    int x;
08289    int haveidles;
08290    int activeidles;
08291    int nextidle = -1;
08292    struct ast_channel *c;
08293    struct timeval tv, lowest, *next;
08294    struct timeval lastidle = { 0, 0 };
08295    int doidling=0;
08296    char *cc;
08297    char idlen[80];
08298    struct ast_channel *idle;
08299    pthread_t p;
08300    time_t t;
08301    int i, which=-1;
08302    int numdchans;
08303    int cause=0;
08304    struct zt_pvt *crv;
08305    pthread_t threadid;
08306    pthread_attr_t attr;
08307    char ani2str[6];
08308    char plancallingnum[256];
08309    char plancallingani[256];
08310    char calledtonstr[10];
08311    
08312    gettimeofday(&lastidle, NULL);
08313    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08314       /* Need to do idle dialing, check to be sure though */
08315       cc = strchr(pri->idleext, '@');
08316       if (cc) {
08317          *cc = '\0';
08318          cc++;
08319          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08320 #if 0
08321          /* Extensions may not be loaded yet */
08322          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08323             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08324          else
08325 #endif
08326             doidling = 1;
08327       } else
08328          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08329    }
08330    for (;;) {
08331       for (i = 0; i < NUM_DCHANS; i++) {
08332          if (!pri->dchannels[i])
08333             break;
08334          fds[i].fd = pri->fds[i];
08335          fds[i].events = POLLIN | POLLPRI;
08336          fds[i].revents = 0;
08337       }
08338       numdchans = i;
08339       time(&t);
08340       ast_mutex_lock(&pri->lock);
08341       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08342          if (pri->resetting && pri_is_up(pri)) {
08343             if (pri->resetpos < 0)
08344                pri_check_restart(pri);
08345          } else {
08346             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08347                pri->resetting = 1;
08348                pri->resetpos = -1;
08349             }
08350          }
08351       }
08352       /* Look for any idle channels if appropriate */
08353       if (doidling && pri_is_up(pri)) {
08354          nextidle = -1;
08355          haveidles = 0;
08356          activeidles = 0;
08357          for (x = pri->numchans; x >= 0; x--) {
08358             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08359                 !pri->pvts[x]->call) {
08360                if (haveidles < pri->minunused) {
08361                   haveidles++;
08362                } else if (!pri->pvts[x]->resetting) {
08363                   nextidle = x;
08364                   break;
08365                }
08366             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08367                activeidles++;
08368          }
08369          if (nextidle > -1) {
08370             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08371                /* Don't create a new idle call more than once per second */
08372                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08373                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08374                if (idle) {
08375                   pri->pvts[nextidle]->isidlecall = 1;
08376                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08377                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08378                      zt_hangup(idle);
08379                   }
08380                } else
08381                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08382                gettimeofday(&lastidle, NULL);
08383             }
08384          } else if ((haveidles < pri->minunused) &&
08385                (activeidles > pri->minidle)) {
08386             /* Mark something for hangup if there is something 
08387                that can be hungup */
08388             for (x = pri->numchans; x >= 0; x--) {
08389                /* find a candidate channel */
08390                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08391                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08392                   haveidles++;
08393                   /* Stop if we have enough idle channels or
08394                     can't spare any more active idle ones */
08395                   if ((haveidles >= pri->minunused) ||
08396                       (activeidles <= pri->minidle))
08397                      break;
08398                } 
08399             }
08400          }
08401       }
08402       /* Start with reasonable max */
08403       lowest = ast_tv(60, 0);
08404       for (i = 0; i < NUM_DCHANS; i++) {
08405          /* Find lowest available d-channel */
08406          if (!pri->dchannels[i])
08407             break;
08408          if ((next = pri_schedule_next(pri->dchans[i]))) {
08409             /* We need relative time here */
08410             tv = ast_tvsub(*next, ast_tvnow());
08411             if (tv.tv_sec < 0) {
08412                tv = ast_tv(0,0);
08413             }
08414             if (doidling || pri->resetting) {
08415                if (tv.tv_sec > 1) {
08416                   tv = ast_tv(1, 0);
08417                }
08418             } else {
08419                if (tv.tv_sec > 60) {
08420                   tv = ast_tv(60, 0);
08421                }
08422             }
08423          } else if (doidling || pri->resetting) {
08424             /* Make sure we stop at least once per second if we're
08425                monitoring idle channels */
08426             tv = ast_tv(1,0);
08427          } else {
08428             /* Don't poll for more than 60 seconds */
08429             tv = ast_tv(60, 0);
08430          }
08431          if (!i || ast_tvcmp(tv, lowest) < 0) {
08432             lowest = tv;
08433          }
08434       }
08435       ast_mutex_unlock(&pri->lock);
08436 
08437       e = NULL;
08438       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
08439 
08440       ast_mutex_lock(&pri->lock);
08441       if (!res) {
08442          for (which = 0; which < NUM_DCHANS; which++) {
08443             if (!pri->dchans[which])
08444                break;
08445             /* Just a timeout, run the scheduler */
08446             e = pri_schedule_run(pri->dchans[which]);
08447             if (e)
08448                break;
08449          }
08450       } else if (res > -1) {
08451          for (which = 0; which < NUM_DCHANS; which++) {
08452             if (!pri->dchans[which])
08453                break;
08454             if (fds[which].revents & POLLPRI) {
08455                /* Check for an event */
08456                x = 0;
08457                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
08458                if (x) 
08459                   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);
08460                /* Keep track of alarm state */  
08461                if (x == ZT_EVENT_ALARM) {
08462                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
08463                   pri_find_dchan(pri);
08464                } else if (x == ZT_EVENT_NOALARM) {
08465                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
08466                   pri_restart(pri->dchans[which]);
08467                }
08468             
08469                if (option_debug)
08470                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
08471             } else if (fds[which].revents & POLLIN) {
08472                e = pri_check_event(pri->dchans[which]);
08473             }
08474             if (e)
08475                break;
08476          }
08477       } else if (errno != EINTR)
08478          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
08479 
08480       if (e) {
08481          if (pri->debug)
08482             pri_dump_event(pri->dchans[which], e);
08483          if (e->e != PRI_EVENT_DCHAN_DOWN)
08484             pri->dchanavail[which] |= DCHAN_UP;
08485 
08486          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
08487             /* Must be an NFAS group that has the secondary dchan active */
08488             pri->pri = pri->dchans[which];
08489 
08490          switch (e->e) {
08491          case PRI_EVENT_DCHAN_UP:
08492             if (option_verbose > 1) 
08493                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
08494             pri->dchanavail[which] |= DCHAN_UP;
08495             if (!pri->pri) pri_find_dchan(pri);
08496 
08497             /* Note presense of D-channel */
08498             time(&pri->lastreset);
08499 
08500             /* Restart in 5 seconds */
08501             if (pri->resetinterval > -1) {
08502                pri->lastreset -= pri->resetinterval;
08503                pri->lastreset += 5;
08504             }
08505             pri->resetting = 0;
08506             /* Take the channels from inalarm condition */
08507             for (i = 0; i < pri->numchans; i++)
08508                if (pri->pvts[i]) {
08509                   pri->pvts[i]->inalarm = 0;
08510                }
08511             break;
08512          case PRI_EVENT_DCHAN_DOWN:
08513             if (option_verbose > 1) 
08514                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
08515             pri->dchanavail[which] &= ~DCHAN_UP;
08516             pri_find_dchan(pri);
08517             if (!pri_is_up(pri)) {
08518                pri->resetting = 0;
08519                /* Hangup active channels and put them in alarm mode */
08520                for (i = 0; i < pri->numchans; i++) {
08521                   struct zt_pvt *p = pri->pvts[i];
08522                   if (p) {
08523                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08524                         /* T309 is not enabled : hangup calls when alarm occurs */
08525                         if (p->call) {
08526                            if (p->pri && p->pri->pri) {
08527                               pri_hangup(p->pri->pri, p->call, -1);
08528                               pri_destroycall(p->pri->pri, p->call);
08529                               p->call = NULL;
08530                            } else
08531                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
08532                         }
08533                         if (p->realcall) {
08534                            pri_hangup_all(p->realcall, pri);
08535                         } else if (p->owner)
08536                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08537                      }
08538                      p->inalarm = 1;
08539                   }
08540                }
08541             }
08542             break;
08543          case PRI_EVENT_RESTART:
08544             if (e->restart.channel > -1) {
08545                chanpos = pri_find_principle(pri, e->restart.channel);
08546                if (chanpos < 0)
08547                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
08548                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08549                else {
08550                   if (option_verbose > 2)
08551                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
08552                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08553                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08554                   if (pri->pvts[chanpos]->call) {
08555                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
08556                      pri->pvts[chanpos]->call = NULL;
08557                   }
08558                   /* Force soft hangup if appropriate */
08559                   if (pri->pvts[chanpos]->realcall) 
08560                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08561                   else if (pri->pvts[chanpos]->owner)
08562                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08563                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08564                }
08565             } else {
08566                if (option_verbose > 2)
08567                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
08568                for (x = 0; x < pri->numchans; x++)
08569                   if (pri->pvts[x]) {
08570                      ast_mutex_lock(&pri->pvts[x]->lock);
08571                      if (pri->pvts[x]->call) {
08572                         pri_destroycall(pri->pri, pri->pvts[x]->call);
08573                         pri->pvts[x]->call = NULL;
08574                      }
08575                      if (pri->pvts[chanpos]->realcall) 
08576                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08577                      else if (pri->pvts[x]->owner)
08578                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08579                      ast_mutex_unlock(&pri->pvts[x]->lock);
08580                   }
08581             }
08582             break;
08583          case PRI_EVENT_KEYPAD_DIGIT:
08584             chanpos = pri_find_principle(pri, e->digit.channel);
08585             if (chanpos < 0) {
08586                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
08587                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
08588             } else {
08589                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
08590                if (chanpos > -1) {
08591                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08592                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
08593                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
08594                      /* how to do that */
08595                      int digitlen = strlen(e->digit.digits);
08596                      char digit;
08597                      int i;               
08598                      for (i = 0; i < digitlen; i++) { 
08599                         digit = e->digit.digits[i];
08600                         {
08601                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08602                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08603                         }
08604                      }
08605                   }
08606                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08607                }
08608             }
08609             break;
08610             
08611          case PRI_EVENT_INFO_RECEIVED:
08612             chanpos = pri_find_principle(pri, e->ring.channel);
08613             if (chanpos < 0) {
08614                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
08615                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08616             } else {
08617                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
08618                if (chanpos > -1) {
08619                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08620                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
08621                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
08622                      /* how to do that */
08623                      int digitlen = strlen(e->ring.callednum);
08624                      char digit;
08625                      int i;               
08626                      for (i = 0; i < digitlen; i++) { 
08627                         digit = e->ring.callednum[i];
08628                         {
08629                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08630                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08631                         }
08632                      }
08633                   }
08634                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08635                }
08636             }
08637             break;
08638          case PRI_EVENT_RING:
08639             crv = NULL;
08640             if (e->ring.channel == -1)
08641                chanpos = pri_find_empty_chan(pri, 1);
08642             else
08643                chanpos = pri_find_principle(pri, e->ring.channel);
08644             /* if no channel specified find one empty */
08645             if (chanpos < 0) {
08646                ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 
08647                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08648             } else {
08649                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08650                if (pri->pvts[chanpos]->owner) {
08651                   if (pri->pvts[chanpos]->call == e->ring.call) {
08652                      ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
08653                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08654                      break;
08655                   } else {
08656                      /* This is where we handle initial glare */
08657                      ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiating channel.\n", 
08658                      PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08659                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08660                      chanpos = -1;
08661                   }
08662                }
08663                if (chanpos > -1)
08664                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08665             }
08666             if ((chanpos < 0) && (e->ring.flexible))
08667                chanpos = pri_find_empty_chan(pri, 1);
08668             if (chanpos > -1) {
08669                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08670                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
08671                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
08672                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
08673                   if (crv)
08674                      ast_mutex_lock(&crv->lock);
08675                   if (!crv || crv->owner) {
08676                      pri->pvts[chanpos]->call = NULL;
08677                      if (crv) {
08678                         if (crv->owner)
08679                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08680                         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);
08681                      } else
08682                         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);
08683                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
08684                      if (crv)
08685                         ast_mutex_unlock(&crv->lock);
08686                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08687                      break;
08688                   }
08689                }
08690                pri->pvts[chanpos]->call = e->ring.call;
08691                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
08692                if (pri->pvts[chanpos]->use_callerid) {
08693                   ast_shrink_phone_number(plancallingnum);
08694                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
08695 #ifdef PRI_ANI
08696                   if (!ast_strlen_zero(e->ring.callingani)) {
08697                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
08698                      ast_shrink_phone_number(plancallingani);
08699                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
08700                   } else {
08701                      pri->pvts[chanpos]->cid_ani[0] = '\0';
08702                   }
08703 #endif
08704                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
08705                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
08706                } else {
08707                   pri->pvts[chanpos]->cid_num[0] = '\0';
08708                   pri->pvts[chanpos]->cid_ani[0] = '\0';
08709                   pri->pvts[chanpos]->cid_name[0] = '\0';
08710                   pri->pvts[chanpos]->cid_ton = 0;
08711                }
08712                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
08713                           e->ring.redirectingnum, e->ring.callingplanrdnis);
08714                /* If immediate=yes go to s|1 */
08715                if (pri->pvts[chanpos]->immediate) {
08716                   if (option_verbose > 2)
08717                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
08718                   pri->pvts[chanpos]->exten[0] = 's';
08719                   pri->pvts[chanpos]->exten[1] = '\0';
08720                }
08721                /* Get called number */
08722                else if (!ast_strlen_zero(e->ring.callednum)) {
08723                   ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
08724                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08725                } else
08726                   pri->pvts[chanpos]->exten[0] = '\0';
08727                /* Set DNID on all incoming calls -- even immediate */
08728                if (!ast_strlen_zero(e->ring.callednum))
08729                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08730                /* No number yet, but received "sending complete"? */
08731                if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
08732                   if (option_verbose > 2)
08733                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
08734                   pri->pvts[chanpos]->exten[0] = 's';
08735                   pri->pvts[chanpos]->exten[1] = '\0';
08736                }
08737                /* Make sure extension exists (or in overlap dial mode, can exist) */
08738                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
08739                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08740                   /* Setup law */
08741                   int law;
08742                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
08743                      /* Set to audio mode at this point */
08744                      law = 1;
08745                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08746                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
08747                   }
08748                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
08749                      law = ZT_LAW_ALAW;
08750                   else
08751                      law = ZT_LAW_MULAW;
08752                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
08753                   if (res < 0) 
08754                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
08755                   res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
08756                   if (res < 0)
08757                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
08758                   if (e->ring.complete || !pri->overlapdial) {
08759                      /* Just announce proceeding */
08760                      pri->pvts[chanpos]->proceeding = 1;
08761                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
08762                   } else {
08763                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
08764                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08765                      else
08766                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08767                   }
08768                   /* Get the use_callingpres state */
08769                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
08770                
08771                   /* Start PBX */
08772                   if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08773                      /* Release the PRI lock while we create the channel */
08774                      ast_mutex_unlock(&pri->lock);
08775                      if (crv) {
08776                         /* Set bearer and such */
08777                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
08778                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08779                         pri->pvts[chanpos]->owner = &inuse;
08780                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
08781                      } else {
08782                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08783                      }
08784                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
08785                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
08786                      }
08787                      if (e->ring.ani2 >= 0) {
08788                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
08789                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08790                      }
08791 
08792 #ifdef SUPPORT_USERUSER
08793                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
08794                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08795                      }
08796 #endif
08797 
08798                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08799                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08800                      if (e->ring.redirectingreason >= 0)
08801                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08802                      
08803                      ast_mutex_lock(&pri->lock);
08804                      pthread_attr_init(&attr);
08805                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08806                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
08807                         if (option_verbose > 2)
08808                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
08809                               plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
08810                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08811                      } else {
08812                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08813                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08814                         if (c)
08815                            ast_hangup(c);
08816                         else {
08817                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08818                            pri->pvts[chanpos]->call = NULL;
08819                         }
08820                      }
08821                      pthread_attr_destroy(&attr);
08822                   } else  {
08823                      ast_mutex_unlock(&pri->lock);
08824                      /* Release PRI lock while we create the channel */
08825                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
08826                      ast_mutex_lock(&pri->lock);
08827                      if (c) {
08828                         char calledtonstr[10];
08829                         if (e->ring.ani2 >= 0) {
08830                            snprintf(ani2str, 5, "%d", e->ring.ani2);
08831                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08832                         }
08833 
08834 #ifdef SUPPORT_USERUSER
08835                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
08836                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08837                         }
08838 #endif
08839 
08840                         if (e->ring.redirectingreason >= 0)
08841                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08842                      
08843                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08844                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08845                         if (option_verbose > 2)
08846                            ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
08847                               plancallingnum, pri->pvts[chanpos]->exten, 
08848                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08849                         zt_enable_ec(pri->pvts[chanpos]);
08850                      } else {
08851                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08852                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08853                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08854                         pri->pvts[chanpos]->call = NULL;
08855                      }
08856                   }
08857                } else {
08858                   if (option_verbose > 2)
08859                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
08860                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
08861                            pri->pvts[chanpos]->prioffset, pri->span);
08862                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
08863                   pri->pvts[chanpos]->call = NULL;
08864                   pri->pvts[chanpos]->exten[0] = '\0';
08865                }
08866                if (crv)
08867                   ast_mutex_unlock(&crv->lock);
08868                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08869             } else {
08870                if (e->ring.flexible)
08871                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
08872                else
08873                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
08874             }
08875             break;
08876          case PRI_EVENT_RINGING:
08877             chanpos = pri_find_principle(pri, e->ringing.channel);
08878             if (chanpos < 0) {
08879                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
08880                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08881             } else {
08882                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
08883                if (chanpos < 0) {
08884                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
08885                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08886                } else {
08887                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08888                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
08889                      zt_enable_ec(pri->pvts[chanpos]);
08890                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
08891                      pri->pvts[chanpos]->alerting = 1;
08892                   } else
08893                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
08894 #ifdef PRI_PROGRESS_MASK
08895                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08896 #else
08897                   if (e->ringing.progress == 8) {
08898 #endif
08899                      /* Now we can do call progress detection */
08900                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08901                         /* RINGING detection isn't required because we got ALERTING signal */
08902                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
08903                         pri->pvts[chanpos]->dsp_features = 0;
08904                      }
08905                   }
08906 
08907 #ifdef SUPPORT_USERUSER
08908                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
08909                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->ringing.useruserinfo);
08910                   }
08911 #endif
08912 
08913                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08914                }
08915             }
08916             break;
08917          case PRI_EVENT_PROGRESS:
08918             /* Get chan value if e->e is not PRI_EVNT_RINGING */
08919             chanpos = pri_find_principle(pri, e->proceeding.channel);
08920             if (chanpos > -1) {
08921 #ifdef PRI_PROGRESS_MASK
08922                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
08923 #else
08924                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
08925 #endif
08926                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
08927 
08928                   if (e->proceeding.cause > -1) {
08929                      if (option_verbose > 2)
08930                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
08931 
08932                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
08933                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
08934                         if (pri->pvts[chanpos]->owner) {
08935                            if (option_verbose > 2)
08936                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
08937 
08938                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
08939                            f.subclass = AST_CONTROL_BUSY;
08940                         }
08941                      }
08942                   }
08943                   
08944                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08945                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
08946                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08947                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08948 #ifdef PRI_PROGRESS_MASK
08949                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08950 #else
08951                   if (e->proceeding.progress == 8) {
08952 #endif
08953                      /* Now we can do call progress detection */
08954                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08955                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08956                         pri->pvts[chanpos]->dsp_features = 0;
08957                      }
08958                   }
08959                   pri->pvts[chanpos]->progress = 1;
08960                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08961                }
08962             }
08963             break;
08964          case PRI_EVENT_PROCEEDING:
08965             chanpos = pri_find_principle(pri, e->proceeding.channel);
08966             if (chanpos > -1) {
08967                if (!pri->pvts[chanpos]->proceeding) {
08968                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
08969                   
08970                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08971                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
08972                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08973                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08974 #ifdef PRI_PROGRESS_MASK
08975                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08976 #else
08977                   if (e->proceeding.progress == 8) {
08978 #endif
08979                      /* Now we can do call progress detection */
08980                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08981                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08982                         pri->pvts[chanpos]->dsp_features = 0;
08983                      }
08984                      /* Bring voice path up */
08985                      f.subclass = AST_CONTROL_PROGRESS;
08986                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
08987                   }
08988                   pri->pvts[chanpos]->proceeding = 1;
08989                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08990                }
08991             }
08992             break;
08993          case PRI_EVENT_FACNAME:
08994             chanpos = pri_find_principle(pri, e->facname.channel);
08995             if (chanpos < 0) {
08996                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
08997                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
08998             } else {
08999                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09000                if (chanpos < 0) {
09001                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09002                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09003                } else {
09004                   /* Re-use *69 field for PRI */
09005                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09006                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09007                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09008                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09009                   zt_enable_ec(pri->pvts[chanpos]);
09010                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09011                }
09012             }
09013             break;            
09014          case PRI_EVENT_ANSWER:
09015             chanpos = pri_find_principle(pri, e->answer.channel);
09016             if (chanpos < 0) {
09017                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09018                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09019             } else {
09020                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09021                if (chanpos < 0) {
09022                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09023                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09024                } else {
09025                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09026                   /* Now we can do call progress detection */
09027 
09028                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09029                    * By this time, we need DTMF detection and other features that were previously disabled
09030                    * -- Matt F */
09031                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09032                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09033                      pri->pvts[chanpos]->dsp_features = 0;
09034                   }
09035                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09036                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09037                      x = ZT_START;
09038                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09039                      if (res < 0) {
09040                         if (errno != EINPROGRESS) {
09041                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09042                         }
09043                      }
09044                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09045                      pri->pvts[chanpos]->dialing = 1;
09046                      /* Send any "w" waited stuff */
09047                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09048                      if (res < 0) {
09049                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09050                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09051                      } else 
09052                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
09053                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09054                   } else if (pri->pvts[chanpos]->confirmanswer) {
09055                      ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
09056                   } else {
09057                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
09058                      /* Enable echo cancellation if it's not on already */
09059                      zt_enable_ec(pri->pvts[chanpos]);
09060                   }
09061 
09062 #ifdef SUPPORT_USERUSER
09063                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
09064                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->answer.useruserinfo);
09065                   }
09066 #endif
09067 
09068                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09069                }
09070             }
09071             break;            
09072          case PRI_EVENT_HANGUP:
09073             chanpos = pri_find_principle(pri, e->hangup.channel);
09074             if (chanpos < 0) {
09075                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
09076                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09077             } else {
09078                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09079                if (chanpos > -1) {
09080                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09081                   if (!pri->pvts[chanpos]->alreadyhungup) {
09082                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
09083                      pri->pvts[chanpos]->alreadyhungup = 1;
09084                      if (pri->pvts[chanpos]->realcall) 
09085                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09086                      else if (pri->pvts[chanpos]->owner) {
09087                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
09088                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09089                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09090                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09091                         else {
09092                            switch (e->hangup.cause) {
09093                               case PRI_CAUSE_USER_BUSY:
09094                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09095                                  break;
09096                               case PRI_CAUSE_CALL_REJECTED:
09097                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09098                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09099                               case PRI_CAUSE_SWITCH_CONGESTION:
09100                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09101                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09102                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09103                                  break;
09104                               default:
09105                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09106                            }
09107                         }
09108                      }
09109                      if (option_verbose > 2) 
09110                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
09111                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
09112                   } else {
09113                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09114                      pri->pvts[chanpos]->call = NULL;
09115                   }
09116                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09117                      if (option_verbose > 2)
09118                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
09119                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09120                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09121                      pri->pvts[chanpos]->resetting = 1;
09122                   }
09123                   if (e->hangup.aoc_units > -1)
09124                      if (option_verbose > 2)
09125                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09126                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09127 
09128 #ifdef SUPPORT_USERUSER
09129                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09130                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09131                   }
09132 #endif
09133 
09134                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09135                } else {
09136                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
09137                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09138                }
09139             } 
09140             break;
09141 #ifndef PRI_EVENT_HANGUP_REQ
09142 #error please update libpri
09143 #endif
09144          case PRI_EVENT_HANGUP_REQ:
09145             chanpos = pri_find_principle(pri, e->hangup.channel);
09146             if (chanpos < 0) {
09147                ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
09148                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09149             } else {
09150                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09151                if (chanpos > -1) {
09152                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09153                   if (pri->pvts[chanpos]->realcall) 
09154                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09155                   else if (pri->pvts[chanpos]->owner) {
09156                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09157                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09158                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09159                      else {
09160                         switch (e->hangup.cause) {
09161                            case PRI_CAUSE_USER_BUSY:
09162                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09163                               break;
09164                            case PRI_CAUSE_CALL_REJECTED:
09165                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09166                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09167                            case PRI_CAUSE_SWITCH_CONGESTION:
09168                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09169                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09170                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09171                               break;
09172                            default:
09173                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09174                         }
09175                      }
09176                      if (option_verbose > 2) 
09177                         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);
09178                      if (e->hangup.aoc_units > -1)
09179                         if (option_verbose > 2)
09180                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09181                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09182                   } else {
09183                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09184                      pri->pvts[chanpos]->call = NULL;
09185                   }
09186                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09187                      if (option_verbose > 2)
09188                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
09189                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09190                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09191                      pri->pvts[chanpos]->resetting = 1;
09192                   }
09193 
09194 #ifdef SUPPORT_USERUSER
09195                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09196                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09197                   }
09198 #endif
09199 
09200                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09201                } else {
09202                   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);
09203                }
09204             } 
09205             break;
09206          case PRI_EVENT_HANGUP_ACK:
09207             chanpos = pri_find_principle(pri, e->hangup.channel);
09208             if (chanpos < 0) {
09209                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
09210                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09211             } else {
09212                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09213                if (chanpos > -1) {
09214                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09215                   pri->pvts[chanpos]->call = NULL;
09216                   pri->pvts[chanpos]->resetting = 0;
09217                   if (pri->pvts[chanpos]->owner) {
09218                      if (option_verbose > 2) 
09219                         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);
09220                   }
09221 
09222 #ifdef SUPPORT_USERUSER
09223                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09224                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09225                   }
09226 #endif
09227 
09228                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09229                }
09230             }
09231             break;
09232          case PRI_EVENT_CONFIG_ERR:
09233             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
09234             break;
09235          case PRI_EVENT_RESTART_ACK:
09236             chanpos = pri_find_principle(pri, e->restartack.channel);
09237             if (chanpos < 0) {
09238                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
09239                   channel number, so we have to figure it out...  This must be why
09240                   everybody resets exactly a channel at a time. */
09241                for (x = 0; x < pri->numchans; x++) {
09242                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
09243                      chanpos = x;
09244                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09245                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
09246                            pri->pvts[chanpos]->prioffset, pri->span);
09247                      if (pri->pvts[chanpos]->realcall) 
09248                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09249                      else if (pri->pvts[chanpos]->owner) {
09250                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
09251                            pri->pvts[chanpos]->prioffset, pri->span);
09252                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09253                      }
09254                      pri->pvts[chanpos]->resetting = 0;
09255                      if (option_verbose > 2)
09256                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09257                            pri->pvts[chanpos]->prioffset, pri->span);
09258                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09259                      if (pri->resetting)
09260                         pri_check_restart(pri);
09261                      break;
09262                   }
09263                }
09264                if (chanpos < 0) {
09265                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
09266                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09267                }
09268             } else {
09269                if (pri->pvts[chanpos]) {
09270                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09271                   if (pri->pvts[chanpos]->realcall) 
09272                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09273                   else if (pri->pvts[chanpos]->owner) {
09274                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
09275                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09276                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09277                   }
09278                   pri->pvts[chanpos]->resetting = 0;
09279                   if (option_verbose > 2)
09280                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09281                            pri->pvts[chanpos]->prioffset, pri->span);
09282                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09283                   if (pri->resetting)
09284                      pri_check_restart(pri);
09285                }
09286             }
09287             break;
09288          case PRI_EVENT_SETUP_ACK:
09289             chanpos = pri_find_principle(pri, e->setup_ack.channel);
09290             if (chanpos < 0) {
09291                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
09292                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
09293             } else {
09294                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
09295                if (chanpos > -1) {
09296                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09297                   pri->pvts[chanpos]->setup_ack = 1;
09298                   /* Send any queued digits */
09299                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
09300                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
09301                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
09302                         pri->pvts[chanpos]->dialdest[x]);
09303                   }
09304                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09305                } else
09306                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
09307             }
09308             break;
09309          case PRI_EVENT_NOTIFY:
09310             chanpos = pri_find_principle(pri, e->notify.channel);
09311             if (chanpos < 0) {
09312                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
09313                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
09314             } else {
09315                struct ast_frame f = { AST_FRAME_CONTROL, };
09316                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09317                switch (e->notify.info) {
09318                case PRI_NOTIFY_REMOTE_HOLD:
09319                   f.subclass = AST_CONTROL_HOLD;
09320                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09321                   break;
09322                case PRI_NOTIFY_REMOTE_RETRIEVAL:
09323                   f.subclass = AST_CONTROL_UNHOLD;
09324                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09325                   break;
09326                }
09327                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09328             }
09329             break;
09330          default:
09331             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
09332          }
09333       }  
09334       ast_mutex_unlock(&pri->lock);
09335    }
09336    /* Never reached */
09337    return NULL;
09338 }
09339 
09340 static int start_pri(struct zt_pri *pri)
09341 {
09342    int res, x;
09343    ZT_PARAMS p;
09344    ZT_BUFFERINFO bi;
09345    struct zt_spaninfo si;
09346    int i;
09347    
09348    for (i = 0; i < NUM_DCHANS; i++) {
09349       if (!pri->dchannels[i])
09350          break;
09351       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
09352       x = pri->dchannels[i];
09353       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
09354          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
09355          return -1;
09356       }
09357       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
09358       if (res) {
09359          zt_close(pri->fds[i]);
09360          pri->fds[i] = -1;
09361          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
09362          return -1;
09363       }
09364       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
09365          zt_close(pri->fds[i]);
09366          pri->fds[i] = -1;
09367          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
09368          return -1;
09369       }
09370       memset(&si, 0, sizeof(si));
09371       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
09372       if (res) {
09373          zt_close(pri->fds[i]);
09374          pri->fds[i] = -1;
09375          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
09376       }
09377       if (!si.alarms)
09378          pri->dchanavail[i] |= DCHAN_NOTINALARM;
09379       else
09380          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
09381       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
09382       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
09383       bi.numbufs = 32;
09384       bi.bufsize = 1024;
09385       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
09386          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
09387          zt_close(pri->fds[i]);
09388          pri->fds[i] = -1;
09389          return -1;
09390       }
09391       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
09392       /* Force overlap dial if we're doing GR-303! */
09393       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
09394          pri->overlapdial = 1;
09395       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
09396       /* Enslave to master if appropriate */
09397       if (i)
09398          pri_enslave(pri->dchans[0], pri->dchans[i]);
09399       if (!pri->dchans[i]) {
09400          zt_close(pri->fds[i]);
09401          pri->fds[i] = -1;
09402          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
09403          return -1;
09404       }
09405       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
09406       pri_set_nsf(pri->dchans[i], pri->nsf);
09407 #ifdef PRI_GETSET_TIMERS
09408       for (x = 0; x < PRI_MAX_TIMERS; x++) {
09409          if (pritimers[x] != 0)
09410             pri_set_timer(pri->dchans[i], x, pritimers[x]);
09411       }
09412 #endif
09413    }
09414    /* Assume primary is the one we use */
09415    pri->pri = pri->dchans[0];
09416    pri->resetpos = -1;
09417    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
09418       for (i = 0; i < NUM_DCHANS; i++) {
09419          if (!pri->dchannels[i])
09420             break;
09421          zt_close(pri->fds[i]);
09422          pri->fds[i] = -1;
09423       }
09424       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
09425       return -1;
09426    }
09427    return 0;
09428 }
09429 
09430 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
09431 {
09432    int which, span;
09433    char *ret = NULL;
09434 
09435    if (pos != rpos)
09436       return ret;
09437 
09438    for (which = span = 0; span < NUM_SPANS; span++) {
09439       if (pris[span].pri && ++which > state) {
09440          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
09441          break;
09442       }
09443    }
09444    return ret;
09445 }
09446 
09447 static char *complete_span_4(const char *line, const char *word, int pos, int state)
09448 {
09449    return complete_span_helper(line,word,pos,state,3);
09450 }
09451 
09452 static char *complete_span_5(const char *line, const char *word, int pos, int state)
09453 {
09454    return complete_span_helper(line,word,pos,state,4);
09455 }
09456 
09457 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
09458 {
09459    int myfd;
09460 
09461    if (!strncasecmp(argv[1], "set", 3)) {
09462       if (argc < 5) 
09463          return RESULT_SHOWUSAGE;
09464 
09465       if (ast_strlen_zero(argv[4]))
09466          return RESULT_SHOWUSAGE;
09467 
09468       myfd = open(argv[4], O_CREAT|O_WRONLY);
09469       if (myfd < 0) {
09470          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
09471          return RESULT_SUCCESS;
09472       }
09473 
09474       ast_mutex_lock(&pridebugfdlock);
09475 
09476       if (pridebugfd >= 0)
09477          close(pridebugfd);
09478 
09479       pridebugfd = myfd;
09480       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
09481       
09482       ast_mutex_unlock(&pridebugfdlock);
09483 
09484       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
09485    } else {
09486       /* Assume it is unset */
09487       ast_mutex_lock(&pridebugfdlock);
09488       close(pridebugfd);
09489       pridebugfd = -1;
09490       ast_cli(fd, "PRI debug output to file disabled\n");
09491       ast_mutex_unlock(&pridebugfdlock);
09492    }
09493 
09494    return RESULT_SUCCESS;
09495 }
09496 
09497 static int handle_pri_debug(int fd, int argc, char *argv[])
09498 {
09499    int span;
09500    int x;
09501    if (argc < 4) {
09502       return RESULT_SHOWUSAGE;
09503    }
09504    span = atoi(argv[3]);
09505    if ((span < 1) || (span > NUM_SPANS)) {
09506       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
09507       return RESULT_SUCCESS;
09508    }
09509    if (!pris[span-1].pri) {
09510       ast_cli(fd, "No PRI running on span %d\n", span);
09511       return RESULT_SUCCESS;
09512    }
09513    for (x = 0; x < NUM_DCHANS; x++) {
09514       if (pris[span-1].dchans[x])
09515          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09516                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09517                                                PRI_DEBUG_Q921_STATE);
09518    }
09519    ast_cli(fd, "Enabled debugging on span %d\n", span);
09520    return RESULT_SUCCESS;
09521 }
09522 
09523 
09524 
09525 static int handle_pri_no_debug(int fd, int argc, char *argv[])
09526 {
09527    int span;
09528    int x;
09529    if (argc < 5)
09530       return RESULT_SHOWUSAGE;
09531    span = atoi(argv[4]);
09532    if ((span < 1) || (span > NUM_SPANS)) {
09533       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09534       return RESULT_SUCCESS;
09535    }
09536    if (!pris[span-1].pri) {
09537       ast_cli(fd, "No PRI running on span %d\n", span);
09538       return RESULT_SUCCESS;
09539    }
09540    for (x = 0; x < NUM_DCHANS; x++) {
09541       if (pris[span-1].dchans[x])
09542          pri_set_debug(pris[span-1].dchans[x], 0);
09543    }
09544    ast_cli(fd, "Disabled debugging on span %d\n", span);
09545    return RESULT_SUCCESS;
09546 }
09547 
09548 static int handle_pri_really_debug(int fd, int argc, char *argv[])
09549 {
09550    int span;
09551    int x;
09552    if (argc < 5)
09553       return RESULT_SHOWUSAGE;
09554    span = atoi(argv[4]);
09555    if ((span < 1) || (span > NUM_SPANS)) {
09556       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09557       return RESULT_SUCCESS;
09558    }
09559    if (!pris[span-1].pri) {
09560       ast_cli(fd, "No PRI running on span %d\n", span);
09561       return RESULT_SUCCESS;
09562    }
09563    for (x = 0; x < NUM_DCHANS; x++) {
09564       if (pris[span-1].dchans[x])
09565          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09566                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09567                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
09568    }
09569    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
09570    return RESULT_SUCCESS;
09571 }
09572 
09573 static void build_status(char *s, size_t len, int status, int active)
09574 {
09575    if (!s || len < 1) {
09576       return;
09577    }
09578    s[0] = '\0';
09579    if (status & DCHAN_PROVISIONED)
09580       strncat(s, "Provisioned, ", len - strlen(s) - 1);
09581    if (!(status & DCHAN_NOTINALARM))
09582       strncat(s, "In Alarm, ", len - strlen(s) - 1);
09583    if (status & DCHAN_UP)
09584       strncat(s, "Up", len - strlen(s) - 1);
09585    else
09586       strncat(s, "Down", len - strlen(s) - 1);
09587    if (active)
09588       strncat(s, ", Active", len - strlen(s) - 1);
09589    else
09590       strncat(s, ", Standby", len - strlen(s) - 1);
09591    s[len - 1] = '\0';
09592 }
09593 
09594 static int handle_pri_show_spans(int fd, int argc, char *argv[])
09595 {
09596    int span;
09597    int x;
09598    char status[256];
09599    if (argc != 3)
09600       return RESULT_SHOWUSAGE;
09601 
09602    for (span = 0; span < NUM_SPANS; span++) {
09603       if (pris[span].pri) {
09604          for (x = 0; x < NUM_DCHANS; x++) {
09605             if (pris[span].dchannels[x]) {
09606                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
09607                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
09608             }
09609          }
09610       }
09611    }
09612    return RESULT_SUCCESS;
09613 }
09614 
09615 static int handle_pri_show_span(int fd, int argc, char *argv[])
09616 {
09617    int span;
09618    int x;
09619    char status[256];
09620    if (argc < 4)
09621       return RESULT_SHOWUSAGE;
09622    span = atoi(argv[3]);
09623    if ((span < 1) || (span > NUM_SPANS)) {
09624       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
09625       return RESULT_SUCCESS;
09626    }
09627    if (!pris[span-1].pri) {
09628       ast_cli(fd, "No PRI running on span %d\n", span);
09629       return RESULT_SUCCESS;
09630    }
09631    for (x = 0; x < NUM_DCHANS; x++) {
09632       if (pris[span-1].dchannels[x]) {
09633 #ifdef PRI_DUMP_INFO_STR
09634          char *info_str = NULL;
09635 #endif
09636          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
09637          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
09638          ast_cli(fd, "Status: %s\n", status);
09639 #ifdef PRI_DUMP_INFO_STR
09640          info_str = pri_dump_info_str(pris[span-1].pri);
09641          if (info_str) {
09642             ast_cli(fd, "%s", info_str);
09643             free(info_str);
09644          }
09645 #else
09646          pri_dump_info(pris[span-1].pri);
09647 #endif
09648          ast_cli(fd, "\n");
09649       }
09650    }
09651    return RESULT_SUCCESS;
09652 }
09653 
09654 static int handle_pri_show_debug(int fd, int argc, char *argv[])
09655 {
09656    int x;
09657    int span;
09658    int count=0;
09659    int debug=0;
09660 
09661    for (span = 0; span < NUM_SPANS; span++) {
09662            if (pris[span].pri) {
09663          for (x = 0; x < NUM_DCHANS; x++) {
09664             debug = 0;
09665                if (pris[span].dchans[x]) {
09666                   debug = pri_get_debug(pris[span].dchans[x]);
09667                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" );
09668                count++;
09669             }
09670          }
09671       }
09672 
09673    }
09674    ast_mutex_lock(&pridebugfdlock);
09675    if (pridebugfd >= 0) 
09676       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
09677    ast_mutex_unlock(&pridebugfdlock);
09678        
09679    if (!count) 
09680       ast_cli(fd, "No debug set or no PRI running\n");
09681    return RESULT_SUCCESS;
09682 }
09683 
09684 static const char pri_debug_help[] = 
09685    "Usage: pri debug span <span>\n"
09686    "       Enables debugging on a given PRI span\n";
09687    
09688 static const char pri_no_debug_help[] = 
09689    "Usage: pri no debug span <span>\n"
09690    "       Disables debugging on a given PRI span\n";
09691 
09692 static const char pri_really_debug_help[] = 
09693    "Usage: pri intensive debug span <span>\n"
09694    "       Enables debugging down to the Q.921 level\n";
09695 
09696 static const char pri_show_span_help[] = 
09697    "Usage: pri show span <span>\n"
09698    "       Displays PRI Information on a given PRI span\n";
09699 
09700 static const char pri_show_spans_help[] = 
09701    "Usage: pri show spans\n"
09702    "       Displays PRI Information\n";
09703 
09704 static struct ast_cli_entry zap_pri_cli[] = {
09705    { { "pri", "debug", "span", NULL },
09706    handle_pri_debug, "Enables PRI debugging on a span",
09707    pri_debug_help, complete_span_4 },
09708 
09709    { { "pri", "no", "debug", "span", NULL },
09710    handle_pri_no_debug, "Disables PRI debugging on a span",
09711    pri_no_debug_help, complete_span_5 },
09712 
09713    { { "pri", "intense", "debug", "span", NULL },
09714    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
09715    pri_really_debug_help, complete_span_5 },
09716 
09717    { { "pri", "show", "spans", NULL },
09718    handle_pri_show_spans, "Displays PRI Information",
09719    pri_show_spans_help },
09720 
09721    { { "pri", "show", "span", NULL },
09722    handle_pri_show_span, "Displays PRI Information",
09723    pri_show_span_help, complete_span_4 },
09724 
09725    { { "pri", "show", "debug", NULL },
09726    handle_pri_show_debug, "Displays current PRI debug settings" },
09727 
09728    { { "pri", "set", "debug", "file", NULL },
09729    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
09730 
09731    { { "pri", "unset", "debug", "file", NULL },
09732    handle_pri_set_debug_file, "Ends PRI debug output to file" },
09733 };
09734 
09735 #endif /* HAVE_PRI */
09736 
09737 static int zap_destroy_channel(int fd, int argc, char **argv)
09738 {
09739    int channel;
09740    
09741    if (argc != 4)
09742       return RESULT_SHOWUSAGE;
09743    
09744    channel = atoi(argv[3]);
09745 
09746    return zap_destroy_channel_bynum(channel);
09747 }
09748 
09749 static int setup_zap(int reload);
09750 static int zap_restart(void)
09751 {
09752    if (option_verbose > 0)
09753       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09754    while (iflist) {
09755       if (option_debug)
09756          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09757       /* Also updates iflist: */
09758       destroy_channel(NULL, iflist, 1);
09759    }
09760    if (option_debug)
09761       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09762    if (setup_zap(0) != 0) {
09763       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09764       return 1;
09765    }
09766    return 0;
09767 }
09768 
09769 static int zap_restart_cmd(int fd, int argc, char **argv)
09770 {
09771    if (argc != 2) {
09772       return RESULT_SHOWUSAGE;
09773    }
09774 
09775    if (zap_restart() != 0)
09776       return RESULT_FAILURE;
09777    return RESULT_SUCCESS;
09778 }
09779 
09780 static int action_zaprestart(struct mansession *s, const struct message *m)
09781 {
09782    if (zap_restart() != 0) {
09783       astman_send_error(s, m, "Failed rereading zaptel configuration");
09784       return 1;
09785    }
09786    astman_send_ack(s, m, "ZapRestart: Success");
09787    return 0;
09788 }
09789 
09790 static int zap_show_channels(int fd, int argc, char **argv)
09791 {
09792 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09793 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09794    struct zt_pvt *tmp = NULL;
09795    char tmps[20] = "";
09796    ast_mutex_t *lock;
09797    struct zt_pvt *start;
09798 #ifdef HAVE_PRI
09799    int trunkgroup;
09800    struct zt_pri *pri = NULL;
09801    int x;
09802 #endif
09803 
09804    lock = &iflock;
09805    start = iflist;
09806 
09807 #ifdef HAVE_PRI
09808    if (argc == 4) {
09809       if ((trunkgroup = atoi(argv[3])) < 1)
09810          return RESULT_SHOWUSAGE;
09811       for (x = 0; x < NUM_SPANS; x++) {
09812          if (pris[x].trunkgroup == trunkgroup) {
09813             pri = pris + x;
09814             break;
09815          }
09816       }
09817       if (pri) {
09818          start = pri->crvs;
09819          lock = &pri->lock;
09820       } else {
09821          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09822          return RESULT_FAILURE;
09823       }
09824    } else
09825 #endif
09826    if (argc != 3)
09827       return RESULT_SHOWUSAGE;
09828 
09829    ast_mutex_lock(lock);
09830 #ifdef HAVE_PRI
09831    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
09832 #else
09833    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
09834 #endif   
09835    
09836    tmp = start;
09837    while (tmp) {
09838       if (tmp->channel > 0) {
09839          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09840       } else
09841          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09842       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
09843       tmp = tmp->next;
09844    }
09845    ast_mutex_unlock(lock);
09846    return RESULT_SUCCESS;
09847 #undef FORMAT
09848 #undef FORMAT2
09849 }
09850 
09851 static int zap_show_channel(int fd, int argc, char **argv)
09852 {
09853    int channel;
09854    struct zt_pvt *tmp = NULL;
09855    ZT_CONFINFO ci;
09856    ZT_PARAMS ps;
09857    int x;
09858    ast_mutex_t *lock;
09859    struct zt_pvt *start;
09860 #ifdef HAVE_PRI
09861    char *c;
09862    int trunkgroup;
09863    struct zt_pri *pri=NULL;
09864 #endif
09865 
09866    lock = &iflock;
09867    start = iflist;
09868 
09869    if (argc != 4)
09870       return RESULT_SHOWUSAGE;
09871 #ifdef HAVE_PRI
09872    if ((c = strchr(argv[3], ':'))) {
09873       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09874          return RESULT_SHOWUSAGE;
09875       if ((trunkgroup < 1) || (channel < 1))
09876          return RESULT_SHOWUSAGE;
09877       for (x = 0; x < NUM_SPANS; x++) {
09878          if (pris[x].trunkgroup == trunkgroup) {
09879             pri = pris + x;
09880             break;
09881          }
09882       }
09883       if (pri) {
09884          start = pri->crvs;
09885          lock = &pri->lock;
09886       } else {
09887          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09888          return RESULT_FAILURE;
09889       }
09890    } else
09891 #endif
09892       channel = atoi(argv[3]);
09893 
09894    ast_mutex_lock(lock);
09895    tmp = start;
09896    while (tmp) {
09897       if (tmp->channel == channel) {
09898 #ifdef HAVE_PRI
09899          if (pri) 
09900             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
09901          else
09902 #endif         
09903          ast_cli(fd, "Channel: %d\n", tmp->channel);
09904          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
09905          ast_cli(fd, "Span: %d\n", tmp->span);
09906          ast_cli(fd, "Extension: %s\n", tmp->exten);
09907          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
09908          ast_cli(fd, "Context: %s\n", tmp->context);
09909          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
09910          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
09911          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
09912          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
09913          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
09914          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
09915          ast_cli(fd, "Radio: %d\n", tmp->radio);
09916          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
09917          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)" : "");
09918          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)" : "");
09919          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)" : "");
09920          ast_cli(fd, "Confno: %d\n", tmp->confno);
09921          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
09922          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
09923          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
09924          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
09925          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
09926          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
09927          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
09928          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
09929          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
09930          if (tmp->master)
09931             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
09932          for (x = 0; x < MAX_SLAVES; x++) {
09933             if (tmp->slaves[x])
09934                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
09935          }
09936 #ifdef HAVE_PRI
09937          if (tmp->pri) {
09938             ast_cli(fd, "PRI Flags: ");
09939             if (tmp->resetting)
09940                ast_cli(fd, "Resetting ");
09941             if (tmp->call)
09942                ast_cli(fd, "Call ");
09943             if (tmp->bearer)
09944                ast_cli(fd, "Bearer ");
09945             ast_cli(fd, "\n");
09946             if (tmp->logicalspan) 
09947                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
09948             else
09949                ast_cli(fd, "PRI Logical Span: Implicit\n");
09950          }
09951             
09952 #endif
09953          memset(&ci, 0, sizeof(ci));
09954          ps.channo = tmp->channel;
09955          if (tmp->subs[SUB_REAL].zfd > -1) {
09956             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
09957                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
09958             }
09959 #ifdef ZT_GETCONFMUTE
09960             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
09961                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
09962             }
09963 #endif
09964             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
09965                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
09966             } else {
09967                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
09968             }
09969          }
09970          ast_mutex_unlock(lock);
09971          return RESULT_SUCCESS;
09972       }
09973       tmp = tmp->next;
09974    }
09975    
09976    ast_cli(fd, "Unable to find given channel %d\n", channel);
09977    ast_mutex_unlock(lock);
09978    return RESULT_FAILURE;
09979 }
09980 
09981 static char zap_show_cadences_help[] =
09982 "Usage: zap show cadences\n"
09983 "       Shows all cadences currently defined\n";
09984 
09985 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
09986 {
09987    int i, j;
09988    for (i = 0; i < num_cadence; i++) {
09989       char output[1024];
09990       char tmp[16], tmp2[64];
09991       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09992       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09993 
09994       for (j = 0; j < 16; j++) {
09995          if (cadences[i].ringcadence[j] == 0)
09996             break;
09997          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
09998          if (cidrings[i] * 2 - 1 == j)
09999             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
10000          else
10001             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
10002          if (j != 0)
10003             strncat(output, ",", sizeof(output) - strlen(output) - 1);
10004          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
10005       }
10006       ast_cli(fd,"%s\n",output);
10007    }
10008    return 0;
10009 }
10010 
10011 /* Based on irqmiss.c */
10012 static int zap_show_status(int fd, int argc, char *argv[]) {
10013    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
10014    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
10015 
10016    int span;
10017    int res;
10018    char alarms[50];
10019 
10020    int ctl;
10021    ZT_SPANINFO s;
10022 
10023    ctl = open("/dev/zap/ctl", O_RDWR);
10024    if (ctl < 0) {
10025       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
10026       ast_cli(fd, "No Zaptel interface found.\n");
10027       return RESULT_FAILURE;
10028    }
10029    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10030 
10031    for (span = 1; span < ZT_MAX_SPANS; ++span) {
10032       s.spanno = span;
10033       res = ioctl(ctl, ZT_SPANSTAT, &s);
10034       if (res) {
10035          continue;
10036       }
10037       alarms[0] = '\0';
10038       if (s.alarms > 0) {
10039          if (s.alarms & ZT_ALARM_BLUE)
10040             strcat(alarms, "BLU/");
10041          if (s.alarms & ZT_ALARM_YELLOW)
10042             strcat(alarms, "YEL/");
10043          if (s.alarms & ZT_ALARM_RED)
10044             strcat(alarms, "RED/");
10045          if (s.alarms & ZT_ALARM_LOOPBACK)
10046             strcat(alarms, "LB/");
10047          if (s.alarms & ZT_ALARM_RECOVER)
10048             strcat(alarms, "REC/");
10049          if (s.alarms & ZT_ALARM_NOTOPEN)
10050             strcat(alarms, "NOP/");
10051          if (!strlen(alarms))
10052             strcat(alarms, "UUU/");
10053          if (strlen(alarms)) {
10054             /* Strip trailing / */
10055             alarms[strlen(alarms) - 1] = '\0';
10056          }
10057       } else {
10058          if (s.numchans)
10059             strcpy(alarms, "OK");
10060          else
10061             strcpy(alarms, "UNCONFIGURED");
10062       }
10063 
10064       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
10065    }
10066    close(ctl);
10067 
10068    return RESULT_SUCCESS;
10069 #undef FORMAT
10070 #undef FORMAT2
10071 }
10072 
10073 static char show_channels_usage[] =
10074    "Usage: zap show channels\n"
10075    "  Shows a list of available channels\n";
10076 
10077 static char show_channel_usage[] =
10078    "Usage: zap show channel <chan num>\n"
10079    "  Detailed information about a given channel\n";
10080 
10081 static char zap_show_status_usage[] =
10082    "Usage: zap show status\n"
10083    "       Shows a list of Zaptel cards with status\n";
10084 
10085 static char destroy_channel_usage[] =
10086    "Usage: zap destroy channel <chan num>\n"
10087    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
10088 
10089 static char zap_restart_usage[] =
10090    "Usage: zap restart\n"
10091    "  Restarts the zaptel channels: destroys them all and then\n"
10092    "  re-reads them from zapata.conf.\n"
10093    "  Note that this will STOP any running CALL on zaptel channels.\n"
10094    "";
10095 
10096 static struct ast_cli_entry zap_cli[] = {
10097    { { "zap", "show", "cadences", NULL },
10098    handle_zap_show_cadences, "List cadences",
10099    zap_show_cadences_help },
10100 
10101    { { "zap", "show", "channels", NULL},
10102    zap_show_channels, "Show active zapata channels",
10103    show_channels_usage },
10104 
10105    { { "zap", "show", "channel", NULL},
10106    zap_show_channel, "Show information on a channel",
10107    show_channel_usage },
10108 
10109    { { "zap", "destroy", "channel", NULL},
10110    zap_destroy_channel, "Destroy a channel",
10111    destroy_channel_usage },
10112 
10113    { { "zap", "restart", NULL},
10114    zap_restart_cmd, "Fully restart zaptel channels",
10115    zap_restart_usage },
10116 
10117    { { "zap", "show", "status", NULL},
10118    zap_show_status, "Show all Zaptel cards status",
10119    zap_show_status_usage },
10120 };
10121 
10122 #define TRANSFER  0
10123 #define HANGUP    1
10124 
10125 static int zap_fake_event(struct zt_pvt *p, int mode)
10126 {
10127    if (p) {
10128       switch (mode) {
10129          case TRANSFER:
10130             p->fake_event = ZT_EVENT_WINKFLASH;
10131             break;
10132          case HANGUP:
10133             p->fake_event = ZT_EVENT_ONHOOK;
10134             break;
10135          default:
10136             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10137       }
10138    }
10139    return 0;
10140 }
10141 static struct zt_pvt *find_channel(int channel)
10142 {
10143    struct zt_pvt *p = iflist;
10144    while (p) {
10145       if (p->channel == channel) {
10146          break;
10147       }
10148       p = p->next;
10149    }
10150    return p;
10151 }
10152 
10153 static int action_zapdndon(struct mansession *s, const struct message *m)
10154 {
10155    struct zt_pvt *p = NULL;
10156    const char *channel = astman_get_header(m, "ZapChannel");
10157 
10158    if (ast_strlen_zero(channel)) {
10159       astman_send_error(s, m, "No channel specified");
10160       return 0;
10161    }
10162    p = find_channel(atoi(channel));
10163    if (!p) {
10164       astman_send_error(s, m, "No such channel");
10165       return 0;
10166    }
10167    p->dnd = 1;
10168    astman_send_ack(s, m, "DND Enabled");
10169    return 0;
10170 }
10171 
10172 static int action_zapdndoff(struct mansession *s, const struct message *m)
10173 {
10174    struct zt_pvt *p = NULL;
10175    const char *channel = astman_get_header(m, "ZapChannel");
10176 
10177    if (ast_strlen_zero(channel)) {
10178       astman_send_error(s, m, "No channel specified");
10179       return 0;
10180    }
10181    p = find_channel(atoi(channel));
10182    if (!p) {
10183       astman_send_error(s, m, "No such channel");
10184       return 0;
10185    }
10186    p->dnd = 0;
10187    astman_send_ack(s, m, "DND Disabled");
10188    return 0;
10189 }
10190 
10191 static int action_transfer(struct mansession *s, const struct message *m)
10192 {
10193    struct zt_pvt *p = NULL;
10194    const char *channel = astman_get_header(m, "ZapChannel");
10195 
10196    if (ast_strlen_zero(channel)) {
10197       astman_send_error(s, m, "No channel specified");
10198       return 0;
10199    }
10200    p = find_channel(atoi(channel));
10201    if (!p) {
10202       astman_send_error(s, m, "No such channel");
10203       return 0;
10204    }
10205    zap_fake_event(p,TRANSFER);
10206    astman_send_ack(s, m, "ZapTransfer");
10207    return 0;
10208 }
10209 
10210 static int action_transferhangup(struct mansession *s, const struct message *m)
10211 {
10212    struct zt_pvt *p = NULL;
10213    const char *channel = astman_get_header(m, "ZapChannel");
10214 
10215    if (ast_strlen_zero(channel)) {
10216       astman_send_error(s, m, "No channel specified");
10217       return 0;
10218    }
10219    p = find_channel(atoi(channel));
10220    if (!p) {
10221       astman_send_error(s, m, "No such channel");
10222       return 0;
10223    }
10224    zap_fake_event(p,HANGUP);
10225    astman_send_ack(s, m, "ZapHangup");
10226    return 0;
10227 }
10228 
10229 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
10230 {
10231    struct zt_pvt *p = NULL;
10232    const char *channel = astman_get_header(m, "ZapChannel");
10233    const char *number = astman_get_header(m, "Number");
10234    int i;
10235 
10236    if (ast_strlen_zero(channel)) {
10237       astman_send_error(s, m, "No channel specified");
10238       return 0;
10239    }
10240    if (ast_strlen_zero(number)) {
10241       astman_send_error(s, m, "No number specified");
10242       return 0;
10243    }
10244    p = find_channel(atoi(channel));
10245    if (!p) {
10246       astman_send_error(s, m, "No such channel");
10247       return 0;
10248    }
10249    if (!p->owner) {
10250       astman_send_error(s, m, "Channel does not have it's owner");
10251       return 0;
10252    }
10253    for (i = 0; i < strlen(number); i++) {
10254       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10255       zap_queue_frame(p, &f, NULL); 
10256    }
10257    astman_send_ack(s, m, "ZapDialOffhook");
10258    return 0;
10259 }
10260 
10261 static int action_zapshowchannels(struct mansession *s, const struct message *m)
10262 {
10263    struct zt_pvt *tmp = NULL;
10264    const char *id = astman_get_header(m, "ActionID");
10265    char idText[256] = "";
10266 
10267    astman_send_ack(s, m, "Zapata channel status will follow");
10268    if (!ast_strlen_zero(id))
10269       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10270 
10271    ast_mutex_lock(&iflock);
10272    
10273    tmp = iflist;
10274    while (tmp) {
10275       if (tmp->channel > 0) {
10276          int alarm = get_alarms(tmp);
10277          astman_append(s,
10278             "Event: ZapShowChannels\r\n"
10279             "Channel: %d\r\n"
10280             "Signalling: %s\r\n"
10281             "Context: %s\r\n"
10282             "DND: %s\r\n"
10283             "Alarm: %s\r\n"
10284             "%s"
10285             "\r\n",
10286             tmp->channel, sig2str(tmp->sig), tmp->context, 
10287             tmp->dnd ? "Enabled" : "Disabled",
10288             alarm2str(alarm), idText);
10289       } 
10290 
10291       tmp = tmp->next;
10292    }
10293 
10294    ast_mutex_unlock(&iflock);
10295    
10296    astman_append(s, 
10297       "Event: ZapShowChannelsComplete\r\n"
10298       "%s"
10299       "\r\n", 
10300       idText);
10301    return 0;
10302 }
10303 
10304 static int __unload_module(void)
10305 {
10306    int x;
10307    struct zt_pvt *p, *pl;
10308 
10309 #ifdef HAVE_PRI
10310    int i;
10311    for (i = 0; i < NUM_SPANS; i++) {
10312       if (pris[i].master != AST_PTHREADT_NULL) 
10313          pthread_cancel(pris[i].master);
10314    }
10315    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
10316    ast_unregister_application(zap_send_keypad_facility_app);
10317 #endif
10318    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
10319    ast_manager_unregister( "ZapDialOffhook" );
10320    ast_manager_unregister( "ZapHangup" );
10321    ast_manager_unregister( "ZapTransfer" );
10322    ast_manager_unregister( "ZapDNDoff" );
10323    ast_manager_unregister( "ZapDNDon" );
10324    ast_manager_unregister("ZapShowChannels");
10325    ast_manager_unregister("ZapRestart");
10326    ast_channel_unregister(&zap_tech);
10327    ast_mutex_lock(&iflock);
10328    /* Hangup all interfaces if they have an owner */
10329    p = iflist;
10330    while (p) {
10331       if (p->owner)
10332          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10333       p = p->next;
10334    }
10335    ast_mutex_unlock(&iflock);
10336    ast_mutex_lock(&monlock);
10337    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10338       pthread_cancel(monitor_thread);
10339       pthread_kill(monitor_thread, SIGURG);
10340       pthread_join(monitor_thread, NULL);
10341    }
10342    monitor_thread = AST_PTHREADT_STOP;
10343    ast_mutex_unlock(&monlock);
10344 
10345    ast_mutex_lock(&iflock);
10346    /* Destroy all the interfaces and free their memory */
10347    p = iflist;
10348    while (p) {
10349       /* Free any callerid */
10350       if (p->cidspill)
10351          free(p->cidspill);
10352       /* Close the zapata thingy */
10353       if (p->subs[SUB_REAL].zfd > -1)
10354          zt_close(p->subs[SUB_REAL].zfd);
10355       pl = p;
10356       p = p->next;
10357       x = pl->channel;
10358       /* Free associated memory */
10359       if (pl)
10360          destroy_zt_pvt(&pl);
10361       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10362    }
10363    iflist = NULL;
10364    ifcount = 0;
10365    ast_mutex_unlock(&iflock);
10366 #ifdef HAVE_PRI      
10367    for (i = 0; i < NUM_SPANS; i++) {
10368       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10369          pthread_join(pris[i].master, NULL);
10370       zt_close(pris[i].fds[i]);
10371    }
10372 #endif
10373    return 0;
10374 }
10375 
10376 static int unload_module(void)
10377 {
10378 #ifdef HAVE_PRI      
10379    int y;
10380    for (y = 0; y < NUM_SPANS; y++)
10381       ast_mutex_destroy(&pris[y].lock);
10382 #endif
10383    return __unload_module();
10384 }
10385 
10386 static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
10387 {
10388    char *c, *chan;
10389    int x, start, finish;
10390    struct zt_pvt *tmp;
10391 #ifdef HAVE_PRI
10392    struct zt_pri *pri;
10393    int trunkgroup, y;
10394 #endif
10395    
10396    if ((reload == 0) && (conf.chan.sig < 0)) {
10397       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10398       return -1;
10399    }
10400 
10401    c = ast_strdupa(value);
10402 
10403 #ifdef HAVE_PRI
10404    pri = NULL;
10405    if (iscrv) {
10406       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10407          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
10408          return -1;
10409       }
10410       if (trunkgroup < 1) {
10411          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
10412          return -1;
10413       }
10414       c += y;
10415       for (y = 0; y < NUM_SPANS; y++) {
10416          if (pris[y].trunkgroup == trunkgroup) {
10417             pri = pris + y;
10418             break;
10419          }
10420       }
10421       if (!pri) {
10422          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
10423          return -1;
10424       }
10425    }
10426 #endif         
10427 
10428    while ((chan = strsep(&c, ","))) {
10429       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10430          /* Range */
10431       } else if (sscanf(chan, "%d", &start)) {
10432          /* Just one */
10433          finish = start;
10434       } else if (!strcasecmp(chan, "pseudo")) {
10435          finish = start = CHAN_PSEUDO;
10436          if (found_pseudo)
10437             *found_pseudo = 1;
10438       } else {
10439          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
10440          return -1;
10441       }
10442       if (finish < start) {
10443          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10444          x = finish;
10445          finish = start;
10446          start = x;
10447       }
10448 
10449       for (x = start; x <= finish; x++) {
10450 #ifdef HAVE_PRI
10451          tmp = mkintf(x, conf, pri, reload);
10452 #else       
10453          tmp = mkintf(x, conf, NULL, reload);
10454 #endif         
10455 
10456          if (tmp) {
10457             if (option_verbose > 2) {
10458 #ifdef HAVE_PRI
10459                if (pri)
10460                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
10461                else
10462 #endif
10463                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10464             }
10465          } else {
10466             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
10467                (reload == 1) ? "reconfigure" : "register", value);
10468             return -1;
10469          }
10470       }
10471    }
10472 
10473    return 0;
10474 }
10475 
10476 /** The length of the parameters list of 'zapchan'. 
10477  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10478 #define MAX_CHANLIST_LEN 80
10479 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
10480 {
10481    struct zt_pvt *tmp;
10482    char *ringc; /* temporary string for parsing the dring number. */
10483    int y;
10484    int found_pseudo = 0;
10485         char zapchan[MAX_CHANLIST_LEN] = {};
10486 
10487    for (; v; v = v->next) {
10488       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
10489          continue;
10490 
10491       /* Create the interface list */
10492       if (!strcasecmp(v->name, "channel")
10493 #ifdef HAVE_PRI
10494           || !strcasecmp(v->name, "crv")
10495 #endif         
10496          ) {
10497          int iscrv;
10498          if (skipchannels)
10499             continue;
10500          iscrv = !strcasecmp(v->name, "crv");
10501          if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
10502                return -1;
10503       } else if (!strcasecmp(v->name, "zapchan")) {
10504          ast_copy_string(zapchan, v->value, sizeof(zapchan));
10505       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10506          if (ast_true(v->value))
10507             confp->chan.usedistinctiveringdetection = 1;
10508       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
10509          if (ast_true(v->value))
10510             distinctiveringaftercid = 1;
10511       } else if (!strcasecmp(v->name, "dring1context")) {
10512          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
10513       } else if (!strcasecmp(v->name, "dring2context")) {
10514          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
10515       } else if (!strcasecmp(v->name, "dring3context")) {
10516          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
10517       } else if (!strcasecmp(v->name, "dring1")) {
10518          ringc = v->value;
10519          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10520       } else if (!strcasecmp(v->name, "dring2")) {
10521          ringc = v->value;
10522          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10523       } else if (!strcasecmp(v->name, "dring3")) {
10524          ringc = v->value;
10525          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10526       } else if (!strcasecmp(v->name, "usecallerid")) {
10527          confp->chan.use_callerid = ast_true(v->value);
10528       } else if (!strcasecmp(v->name, "cidsignalling")) {
10529          if (!strcasecmp(v->value, "bell"))
10530             confp->chan.cid_signalling = CID_SIG_BELL;
10531          else if (!strcasecmp(v->value, "v23"))
10532             confp->chan.cid_signalling = CID_SIG_V23;
10533          else if (!strcasecmp(v->value, "dtmf"))
10534             confp->chan.cid_signalling = CID_SIG_DTMF;
10535          else if (!strcasecmp(v->value, "smdi"))
10536             confp->chan.cid_signalling = CID_SIG_SMDI;
10537          else if (!strcasecmp(v->value, "v23_jp"))
10538             confp->chan.cid_signalling = CID_SIG_V23_JP;
10539          else if (ast_true(v->value))
10540             confp->chan.cid_signalling = CID_SIG_BELL;
10541       } else if (!strcasecmp(v->name, "cidstart")) {
10542          if (!strcasecmp(v->value, "ring"))
10543             confp->chan.cid_start = CID_START_RING;
10544          else if (!strcasecmp(v->value, "polarity"))
10545             confp->chan.cid_start = CID_START_POLARITY;
10546          else if (ast_true(v->value))
10547             confp->chan.cid_start = CID_START_RING;
10548       } else if (!strcasecmp(v->name, "threewaycalling")) {
10549          confp->chan.threewaycalling = ast_true(v->value);
10550       } else if (!strcasecmp(v->name, "cancallforward")) {
10551          confp->chan.cancallforward = ast_true(v->value);
10552       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10553          if (ast_true(v->value)) 
10554             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
10555          else
10556             confp->chan.dtmfrelax = 0;
10557       } else if (!strcasecmp(v->name, "mailbox")) {
10558          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
10559       } else if (!strcasecmp(v->name, "adsi")) {
10560          confp->chan.adsi = ast_true(v->value);
10561       } else if (!strcasecmp(v->name, "usesmdi")) {
10562          confp->chan.use_smdi = ast_true(v->value);
10563       } else if (!strcasecmp(v->name, "smdiport")) {
10564          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
10565       } else if (!strcasecmp(v->name, "transfer")) {
10566          confp->chan.transfer = ast_true(v->value);
10567       } else if (!strcasecmp(v->name, "canpark")) {
10568          confp->chan.canpark = ast_true(v->value);
10569       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10570          confp->chan.echocanbridged = ast_true(v->value);
10571       } else if (!strcasecmp(v->name, "busydetect")) {
10572          confp->chan.busydetect = ast_true(v->value);
10573       } else if (!strcasecmp(v->name, "busycount")) {
10574          confp->chan.busycount = atoi(v->value);
10575       } else if (!strcasecmp(v->name, "busypattern")) {
10576          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
10577             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
10578          }
10579       } else if (!strcasecmp(v->name, "callprogress")) {
10580          if (ast_true(v->value))
10581             confp->chan.callprogress |= 1;
10582          else
10583             confp->chan.callprogress &= ~1;
10584       } else if (!strcasecmp(v->name, "faxdetect")) {
10585          if (!strcasecmp(v->value, "incoming")) {
10586             confp->chan.callprogress |= 4;
10587             confp->chan.callprogress &= ~2;
10588          } else if (!strcasecmp(v->value, "outgoing")) {
10589             confp->chan.callprogress &= ~4;
10590             confp->chan.callprogress |= 2;
10591          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10592             confp->chan.callprogress |= 6;
10593          else
10594             confp->chan.callprogress &= ~6;
10595       } else if (!strcasecmp(v->name, "echocancel")) {
10596          if (!ast_strlen_zero(v->value)) {
10597             y = atoi(v->value);
10598          } else
10599             y = 0;
10600          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
10601             confp->chan.echocancel = y;
10602          else {
10603             confp->chan.echocancel = ast_true(v->value);
10604             if (confp->chan.echocancel)
10605                confp->chan.echocancel=128;
10606          }
10607       } else if (!strcasecmp(v->name, "echotraining")) {
10608          if (sscanf(v->value, "%d", &y) == 1) {
10609             if ((y < 10) || (y > 4000)) {
10610                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
10611             } else {
10612                confp->chan.echotraining = y;
10613             }
10614          } else if (ast_true(v->value)) {
10615             confp->chan.echotraining = 400;
10616          } else
10617             confp->chan.echotraining = 0;
10618       } else if (!strcasecmp(v->name, "hidecallerid")) {
10619          confp->chan.hidecallerid = ast_true(v->value);
10620       } else if (!strcasecmp(v->name, "hidecalleridname")) {
10621          confp->chan.hidecalleridname = ast_true(v->value);
10622       } else if (!strcasecmp(v->name, "pulsedial")) {
10623          confp->chan.pulse = ast_true(v->value);
10624       } else if (!strcasecmp(v->name, "callreturn")) {
10625          confp->chan.callreturn = ast_true(v->value);
10626       } else if (!strcasecmp(v->name, "callwaiting")) {
10627          confp->chan.callwaiting = ast_true(v->value);
10628       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10629          confp->chan.callwaitingcallerid = ast_true(v->value);
10630       } else if (!strcasecmp(v->name, "context")) {
10631          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
10632       } else if (!strcasecmp(v->name, "language")) {
10633          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
10634       } else if (!strcasecmp(v->name, "progzone")) {
10635          ast_copy_string(progzone, v->value, sizeof(progzone));
10636       } else if (!strcasecmp(v->name, "mohinterpret") 
10637          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
10638          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
10639       } else if (!strcasecmp(v->name, "mohsuggest")) {
10640          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
10641       } else if (!strcasecmp(v->name, "stripmsd")) {
10642          confp->chan.stripmsd = atoi(v->value);
10643       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10644          numbufs = atoi(v->value);
10645       } else if (!strcasecmp(v->name, "group")) {
10646          confp->chan.group = ast_get_group(v->value);
10647       } else if (!strcasecmp(v->name, "callgroup")) {
10648          confp->chan.callgroup = ast_get_group(v->value);
10649       } else if (!strcasecmp(v->name, "pickupgroup")) {
10650          confp->chan.pickupgroup = ast_get_group(v->value);
10651       } else if (!strcasecmp(v->name, "immediate")) {
10652          confp->chan.immediate = ast_true(v->value);
10653       } else if (!strcasecmp(v->name, "transfertobusy")) {
10654          confp->chan.transfertobusy = ast_true(v->value);
10655       } else if (!strcasecmp(v->name, "rxgain")) {
10656          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
10657             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10658          }
10659       } else if (!strcasecmp(v->name, "txgain")) {
10660          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
10661             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10662          }
10663       } else if (!strcasecmp(v->name, "tonezone")) {
10664          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
10665             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10666          }
10667       } else if (!strcasecmp(v->name, "callerid")) {
10668          if (!strcasecmp(v->value, "asreceived")) {
10669             confp->chan.cid_num[0] = '\0';
10670             confp->chan.cid_name[0] = '\0';
10671          } else {
10672             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
10673          } 
10674       } else if (!strcasecmp(v->name, "fullname")) {
10675          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
10676       } else if (!strcasecmp(v->name, "cid_number")) {
10677          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
10678       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10679          confp->chan.zaptrcallerid = ast_true(v->value);
10680       } else if (!strcasecmp(v->name, "restrictcid")) {
10681          confp->chan.restrictcid = ast_true(v->value);
10682       } else if (!strcasecmp(v->name, "usecallingpres")) {
10683          confp->chan.use_callingpres = ast_true(v->value);
10684       } else if (!strcasecmp(v->name, "accountcode")) {
10685          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
10686       } else if (!strcasecmp(v->name, "amaflags")) {
10687          y = ast_cdr_amaflags2int(v->value);
10688          if (y < 0) 
10689             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10690          else
10691             confp->chan.amaflags = y;
10692       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
10693          confp->chan.polarityonanswerdelay = atoi(v->value);
10694       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
10695          confp->chan.answeronpolarityswitch = ast_true(v->value);
10696       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
10697          confp->chan.hanguponpolarityswitch = ast_true(v->value);
10698       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
10699          confp->chan.sendcalleridafter = atoi(v->value);
10700       } else if (!reload){ 
10701           if (!strcasecmp(v->name, "signalling")) {
10702             confp->chan.outsigmod = -1;
10703             if (!strcasecmp(v->value, "em")) {
10704                confp->chan.sig = SIG_EM;
10705             } else if (!strcasecmp(v->value, "em_e1")) {
10706                confp->chan.sig = SIG_EM_E1;
10707             } else if (!strcasecmp(v->value, "em_w")) {
10708                confp->chan.sig = SIG_EMWINK;
10709                confp->chan.radio = 0;
10710             } else if (!strcasecmp(v->value, "fxs_ls")) {
10711                confp->chan.sig = SIG_FXSLS;
10712                confp->chan.radio = 0;
10713             } else if (!strcasecmp(v->value, "fxs_gs")) {
10714                confp->chan.sig = SIG_FXSGS;
10715                confp->chan.radio = 0;
10716             } else if (!strcasecmp(v->value, "fxs_ks")) {
10717                confp->chan.sig = SIG_FXSKS;
10718                confp->chan.radio = 0;
10719             } else if (!strcasecmp(v->value, "fxo_ls")) {
10720                confp->chan.sig = SIG_FXOLS;
10721                confp->chan.radio = 0;
10722             } else if (!strcasecmp(v->value, "fxo_gs")) {
10723                confp->chan.sig = SIG_FXOGS;
10724                confp->chan.radio = 0;
10725             } else if (!strcasecmp(v->value, "fxo_ks")) {
10726                confp->chan.sig = SIG_FXOKS;
10727                confp->chan.radio = 0;
10728             } else if (!strcasecmp(v->value, "fxs_rx")) {
10729                confp->chan.sig = SIG_FXSKS;
10730                confp->chan.radio = 1;
10731             } else if (!strcasecmp(v->value, "fxo_rx")) {
10732                confp->chan.sig = SIG_FXOLS;
10733                confp->chan.radio = 1;
10734             } else if (!strcasecmp(v->value, "fxs_tx")) {
10735                confp->chan.sig = SIG_FXSLS;
10736                confp->chan.radio = 1;
10737             } else if (!strcasecmp(v->value, "fxo_tx")) {
10738                confp->chan.sig = SIG_FXOGS;
10739                confp->chan.radio = 1;
10740             } else if (!strcasecmp(v->value, "em_rx")) {
10741                confp->chan.sig = SIG_EM;
10742                confp->chan.radio = 1;
10743             } else if (!strcasecmp(v->value, "em_tx")) {
10744                confp->chan.sig = SIG_EM;
10745                confp->chan.radio = 1;
10746             } else if (!strcasecmp(v->value, "em_rxtx")) {
10747                confp->chan.sig = SIG_EM;
10748                confp->chan.radio = 2;
10749             } else if (!strcasecmp(v->value, "em_txrx")) {
10750                confp->chan.sig = SIG_EM;
10751                confp->chan.radio = 2;
10752             } else if (!strcasecmp(v->value, "sf")) {
10753                confp->chan.sig = SIG_SF;
10754                confp->chan.radio = 0;
10755             } else if (!strcasecmp(v->value, "sf_w")) {
10756                confp->chan.sig = SIG_SFWINK;
10757                confp->chan.radio = 0;
10758             } else if (!strcasecmp(v->value, "sf_featd")) {
10759                confp->chan.sig = SIG_FEATD;
10760                confp->chan.radio = 0;
10761             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10762                confp->chan.sig = SIG_FEATDMF;
10763                confp->chan.radio = 0;
10764             } else if (!strcasecmp(v->value, "sf_featb")) {
10765                confp->chan.sig = SIG_SF_FEATB;
10766                confp->chan.radio = 0;
10767             } else if (!strcasecmp(v->value, "sf")) {
10768                confp->chan.sig = SIG_SF;
10769                confp->chan.radio = 0;
10770             } else if (!strcasecmp(v->value, "sf_rx")) {
10771                confp->chan.sig = SIG_SF;
10772                confp->chan.radio = 1;
10773             } else if (!strcasecmp(v->value, "sf_tx")) {
10774                confp->chan.sig = SIG_SF;
10775                confp->chan.radio = 1;
10776             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10777                confp->chan.sig = SIG_SF;
10778                confp->chan.radio = 2;
10779             } else if (!strcasecmp(v->value, "sf_txrx")) {
10780                confp->chan.sig = SIG_SF;
10781                confp->chan.radio = 2;
10782             } else if (!strcasecmp(v->value, "featd")) {
10783                confp->chan.sig = SIG_FEATD;
10784                confp->chan.radio = 0;
10785             } else if (!strcasecmp(v->value, "featdmf")) {
10786                confp->chan.sig = SIG_FEATDMF;
10787                confp->chan.radio = 0;
10788             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10789                confp->chan.sig = SIG_FEATDMF_TA;
10790                confp->chan.radio = 0;
10791             } else if (!strcasecmp(v->value, "e911")) {
10792                confp->chan.sig = SIG_E911;
10793                confp->chan.radio = 0;
10794             } else if (!strcasecmp(v->value, "fgccama")) {
10795                confp->chan.sig = SIG_FGC_CAMA;
10796                confp->chan.radio = 0;
10797             } else if (!strcasecmp(v->value, "fgccamamf")) {
10798                confp->chan.sig = SIG_FGC_CAMAMF;
10799                confp->chan.radio = 0;
10800             } else if (!strcasecmp(v->value, "featb")) {
10801                confp->chan.sig = SIG_FEATB;
10802                confp->chan.radio = 0;
10803 #ifdef HAVE_PRI
10804             } else if (!strcasecmp(v->value, "pri_net")) {
10805                confp->chan.radio = 0;
10806                confp->chan.sig = SIG_PRI;
10807                confp->pri.nodetype = PRI_NETWORK;
10808             } else if (!strcasecmp(v->value, "pri_cpe")) {
10809                confp->chan.sig = SIG_PRI;
10810                confp->chan.radio = 0;
10811                confp->pri.nodetype = PRI_CPE;
10812             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10813                confp->chan.sig = SIG_GR303FXOKS;
10814                confp->chan.radio = 0;
10815                confp->pri.nodetype = PRI_NETWORK;
10816             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
10817                confp->chan.sig = SIG_GR303FXSKS;
10818                confp->chan.radio = 0;
10819                confp->pri.nodetype = PRI_CPE;
10820 #endif
10821             } else {
10822                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10823             }
10824           } else if (!strcasecmp(v->name, "outsignalling")) {
10825             if (!strcasecmp(v->value, "em")) {
10826                confp->chan.outsigmod = SIG_EM;
10827             } else if (!strcasecmp(v->value, "em_e1")) {
10828                confp->chan.outsigmod = SIG_EM_E1;
10829             } else if (!strcasecmp(v->value, "em_w")) {
10830                confp->chan.outsigmod = SIG_EMWINK;
10831             } else if (!strcasecmp(v->value, "sf")) {
10832                confp->chan.outsigmod = SIG_SF;
10833             } else if (!strcasecmp(v->value, "sf_w")) {
10834                confp->chan.outsigmod = SIG_SFWINK;
10835             } else if (!strcasecmp(v->value, "sf_featd")) {
10836                confp->chan.outsigmod = SIG_FEATD;
10837             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10838                confp->chan.outsigmod = SIG_FEATDMF;
10839             } else if (!strcasecmp(v->value, "sf_featb")) {
10840                confp->chan.outsigmod = SIG_SF_FEATB;
10841             } else if (!strcasecmp(v->value, "sf")) {
10842                confp->chan.outsigmod = SIG_SF;
10843             } else if (!strcasecmp(v->value, "featd")) {
10844                confp->chan.outsigmod = SIG_FEATD;
10845             } else if (!strcasecmp(v->value, "featdmf")) {
10846                confp->chan.outsigmod = SIG_FEATDMF;
10847             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10848                confp->chan.outsigmod = SIG_FEATDMF_TA;
10849             } else if (!strcasecmp(v->value, "e911")) {
10850                confp->chan.outsigmod = SIG_E911;
10851             } else if (!strcasecmp(v->value, "fgccama")) {
10852                confp->chan.outsigmod = SIG_FGC_CAMA;
10853             } else if (!strcasecmp(v->value, "fgccamamf")) {
10854                confp->chan.outsigmod = SIG_FGC_CAMAMF;
10855             } else if (!strcasecmp(v->value, "featb")) {
10856                confp->chan.outsigmod = SIG_FEATB;
10857             } else {
10858                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10859             }
10860 #ifdef HAVE_PRI
10861          } else if (!strcasecmp(v->name, "pridialplan")) {
10862             if (!strcasecmp(v->value, "national")) {
10863                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
10864             } else if (!strcasecmp(v->value, "unknown")) {
10865                confp->pri.dialplan = PRI_UNKNOWN + 1;
10866             } else if (!strcasecmp(v->value, "private")) {
10867                confp->pri.dialplan = PRI_PRIVATE + 1;
10868             } else if (!strcasecmp(v->value, "international")) {
10869                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
10870             } else if (!strcasecmp(v->value, "local")) {
10871                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
10872             } else if (!strcasecmp(v->value, "dynamic")) {
10873                confp->pri.dialplan = -1;
10874             } else {
10875                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10876             }
10877          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
10878             if (!strcasecmp(v->value, "national")) {
10879                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
10880             } else if (!strcasecmp(v->value, "unknown")) {
10881                confp->pri.localdialplan = PRI_UNKNOWN + 1;
10882             } else if (!strcasecmp(v->value, "private")) {
10883                confp->pri.localdialplan = PRI_PRIVATE + 1;
10884             } else if (!strcasecmp(v->value, "international")) {
10885                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
10886             } else if (!strcasecmp(v->value, "local")) {
10887                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
10888             } else if (!strcasecmp(v->value, "dynamic")) {
10889                confp->pri.localdialplan = -1;
10890             } else {
10891                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10892             }
10893          } else if (!strcasecmp(v->name, "switchtype")) {
10894             if (!strcasecmp(v->value, "national")) 
10895                confp->pri.switchtype = PRI_SWITCH_NI2;
10896             else if (!strcasecmp(v->value, "ni1"))
10897                confp->pri.switchtype = PRI_SWITCH_NI1;
10898             else if (!strcasecmp(v->value, "dms100"))
10899                confp->pri.switchtype = PRI_SWITCH_DMS100;
10900             else if (!strcasecmp(v->value, "4ess"))
10901                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
10902             else if (!strcasecmp(v->value, "5ess"))
10903                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
10904             else if (!strcasecmp(v->value, "euroisdn"))
10905                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
10906             else if (!strcasecmp(v->value, "qsig"))
10907                confp->pri.switchtype = PRI_SWITCH_QSIG;
10908             else {
10909                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
10910                return -1;
10911             }
10912          } else if (!strcasecmp(v->name, "nsf")) {
10913             if (!strcasecmp(v->value, "sdn"))
10914                confp->pri.nsf = PRI_NSF_SDN;
10915             else if (!strcasecmp(v->value, "megacom"))
10916                confp->pri.nsf = PRI_NSF_MEGACOM;
10917             else if (!strcasecmp(v->value, "tollfreemegacom"))
10918                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
10919             else if (!strcasecmp(v->value, "accunet"))
10920                confp->pri.nsf = PRI_NSF_ACCUNET;
10921             else if (!strcasecmp(v->value, "none"))
10922                confp->pri.nsf = PRI_NSF_NONE;
10923             else {
10924                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
10925                confp->pri.nsf = PRI_NSF_NONE;
10926             }
10927          } else if (!strcasecmp(v->name, "priindication")) {
10928             if (!strcasecmp(v->value, "outofband"))
10929                confp->chan.priindication_oob = 1;
10930             else if (!strcasecmp(v->value, "inband"))
10931                confp->chan.priindication_oob = 0;
10932             else
10933                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
10934                   v->value, v->lineno);
10935          } else if (!strcasecmp(v->name, "priexclusive")) {
10936             confp->chan.priexclusive = ast_true(v->value);
10937          } else if (!strcasecmp(v->name, "internationalprefix")) {
10938             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
10939          } else if (!strcasecmp(v->name, "nationalprefix")) {
10940             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
10941          } else if (!strcasecmp(v->name, "localprefix")) {
10942             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
10943          } else if (!strcasecmp(v->name, "privateprefix")) {
10944             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
10945          } else if (!strcasecmp(v->name, "unknownprefix")) {
10946             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
10947          } else if (!strcasecmp(v->name, "resetinterval")) {
10948             if (!strcasecmp(v->value, "never"))
10949                confp->pri.resetinterval = -1;
10950             else if (atoi(v->value) >= 60)
10951                confp->pri.resetinterval = atoi(v->value);
10952             else
10953                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
10954                   v->value, v->lineno);
10955          } else if (!strcasecmp(v->name, "minunused")) {
10956             confp->pri.minunused = atoi(v->value);
10957          } else if (!strcasecmp(v->name, "minidle")) {
10958             confp->pri.minidle = atoi(v->value); 
10959          } else if (!strcasecmp(v->name, "idleext")) {
10960             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
10961          } else if (!strcasecmp(v->name, "idledial")) {
10962             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
10963          } else if (!strcasecmp(v->name, "overlapdial")) {
10964             confp->pri.overlapdial = ast_true(v->value);
10965          } else if (!strcasecmp(v->name, "pritimer")) {
10966 #ifdef PRI_GETSET_TIMERS
10967             char *timerc, *c;
10968             int timer, timeridx;
10969             c = v->value;
10970             timerc = strsep(&c, ",");
10971             if (timerc) {
10972                timer = atoi(c);
10973                if (!timer)
10974                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
10975                else {
10976                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
10977                      pritimers[timeridx] = timer;
10978                   else
10979                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
10980                }
10981             } else
10982                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
10983 
10984          } else if (!strcasecmp(v->name, "facilityenable")) {
10985             confp->pri.facilityenable = ast_true(v->value);
10986 #endif /* PRI_GETSET_TIMERS */
10987 #endif /* HAVE_PRI */
10988          } else if (!strcasecmp(v->name, "cadence")) {
10989             /* setup to scan our argument */
10990             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
10991             int i;
10992             struct zt_ring_cadence new_cadence;
10993             int cid_location = -1;
10994             int firstcadencepos = 0;
10995             char original_args[80];
10996             int cadence_is_ok = 1;
10997 
10998             ast_copy_string(original_args, v->value, sizeof(original_args));
10999             /* 16 cadences allowed (8 pairs) */
11000             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]);
11001    
11002             /* Cadence must be even (on/off) */
11003             if (element_count % 2 == 1) {
11004                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
11005                cadence_is_ok = 0;
11006             }
11007    
11008             /* Ring cadences cannot be negative */
11009             for (i = 0; i < element_count; i++) {
11010                if (c[i] == 0) {
11011                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
11012                   cadence_is_ok = 0;
11013                   break;
11014                } else if (c[i] < 0) {
11015                   if (i % 2 == 1) {
11016                      /* Silence duration, negative possibly okay */
11017                      if (cid_location == -1) {
11018                         cid_location = i;
11019                         c[i] *= -1;
11020                      } else {
11021                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
11022                         cadence_is_ok = 0;
11023                         break;
11024                      }
11025                   } else {
11026                      if (firstcadencepos == 0) {
11027                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
11028                                  /* duration will be passed negative to the zaptel driver */
11029                      } else {
11030                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
11031                         cadence_is_ok = 0;
11032                         break;
11033                      }
11034                   }
11035                }
11036             }
11037    
11038             /* Substitute our scanned cadence */
11039             for (i = 0; i < 16; i++) {
11040                new_cadence.ringcadence[i] = c[i];
11041             }
11042    
11043             if (cadence_is_ok) {
11044                /* ---we scanned it without getting annoyed; now some sanity checks--- */
11045                if (element_count < 2) {
11046                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
11047                } else {
11048                   if (cid_location == -1) {
11049                      /* user didn't say; default to first pause */
11050                      cid_location = 1;
11051                   } else {
11052                      /* convert element_index to cidrings value */
11053                      cid_location = (cid_location + 1) / 2;
11054                   }
11055                   /* ---we like their cadence; try to install it--- */
11056                   if (!user_has_defined_cadences++)
11057                      /* this is the first user-defined cadence; clear the default user cadences */
11058                      num_cadence = 0;
11059                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
11060                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
11061                   else {
11062                      cadences[num_cadence] = new_cadence;
11063                      cidrings[num_cadence++] = cid_location;
11064                      if (option_verbose > 2)
11065                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
11066                   }
11067                }
11068             }
11069          } else if (!strcasecmp(v->name, "ringtimeout")) {
11070             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
11071          } else if (!strcasecmp(v->name, "prewink")) {
11072             confp->timing.prewinktime = atoi(v->value);
11073          } else if (!strcasecmp(v->name, "preflash")) {
11074             confp->timing.preflashtime = atoi(v->value);
11075          } else if (!strcasecmp(v->name, "wink")) {
11076             confp->timing.winktime = atoi(v->value);
11077          } else if (!strcasecmp(v->name, "flash")) {
11078             confp->timing.flashtime = atoi(v->value);
11079          } else if (!strcasecmp(v->name, "start")) {
11080             confp->timing.starttime = atoi(v->value);
11081          } else if (!strcasecmp(v->name, "rxwink")) {
11082             confp->timing.rxwinktime = atoi(v->value);
11083          } else if (!strcasecmp(v->name, "rxflash")) {
11084             confp->timing.rxflashtime = atoi(v->value);
11085          } else if (!strcasecmp(v->name, "debounce")) {
11086             confp->timing.debouncetime = atoi(v->value);
11087          } else if (!strcasecmp(v->name, "toneduration")) {
11088             int toneduration;
11089             int ctlfd;
11090             int res;
11091             struct zt_dialparams dps;
11092 
11093             ctlfd = open("/dev/zap/ctl", O_RDWR);
11094             if (ctlfd == -1) {
11095                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11096                return -1;
11097             }
11098 
11099             toneduration = atoi(v->value);
11100             if (toneduration > -1) {
11101                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11102                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11103                if (res < 0) {
11104                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11105                   return -1;
11106                }
11107             }
11108             close(ctlfd);
11109          } else if (!strcasecmp(v->name, "defaultcic")) {
11110             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11111          } else if (!strcasecmp(v->name, "defaultozz")) {
11112             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11113          } 
11114       } else if (!skipchannels)
11115          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11116    }
11117    if (zapchan[0]) { 
11118       /* The user has set 'zapchan' */
11119       /*< \todo pass proper line number instead of 0 */
11120       if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
11121          return -1;
11122       }
11123    }
11124    /*< \todo why check for the pseudo in the per-channel section.
11125     * Any actual use for manual setup of the pseudo channel? */
11126    if (!found_pseudo && reload == 0) {
11127       /* Make sure pseudo isn't a member of any groups if
11128          we're automatically making it. */   
11129       
11130       confp->chan.group = 0;
11131       confp->chan.callgroup = 0;
11132       confp->chan.pickupgroup = 0;
11133 
11134       tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
11135 
11136       if (tmp) {
11137          if (option_verbose > 2)
11138             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11139       } else {
11140          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11141       }
11142    }
11143    return 0;
11144 }
11145       
11146 static int setup_zap(int reload)
11147 {
11148    struct ast_config *cfg;
11149    struct ast_variable *v;
11150    struct zt_chan_conf conf = zt_chan_conf_default();
11151    int res;
11152 
11153 #ifdef HAVE_PRI
11154    char *c;
11155    int spanno;
11156    int i, x;
11157    int logicalspan;
11158    int trunkgroup;
11159    int dchannels[NUM_DCHANS];
11160 #endif
11161 
11162    cfg = ast_config_load(config);
11163 
11164    /* Error if we have no config file */
11165    if (!cfg) {
11166       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
11167       return 0;
11168    }
11169 
11170    /* It's a little silly to lock it, but we mind as well just to be sure */
11171    ast_mutex_lock(&iflock);
11172 #ifdef HAVE_PRI
11173    if (!reload) {
11174       /* Process trunkgroups first */
11175       v = ast_variable_browse(cfg, "trunkgroups");
11176       while (v) {
11177          if (!strcasecmp(v->name, "trunkgroup")) {
11178             trunkgroup = atoi(v->value);
11179             if (trunkgroup > 0) {
11180                if ((c = strchr(v->value, ','))) {
11181                   i = 0;
11182                   memset(dchannels, 0, sizeof(dchannels));
11183                   while (c && (i < NUM_DCHANS)) {
11184                      dchannels[i] = atoi(c + 1);
11185                      if (dchannels[i] < 0) {
11186                         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);
11187                      } else
11188                         i++;
11189                      c = strchr(c + 1, ',');
11190                   }
11191                   if (i) {
11192                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
11193                         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);
11194                      } else if (option_verbose > 1)
11195                         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");
11196                   } else
11197                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
11198                } else
11199                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
11200             } else
11201                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
11202          } else if (!strcasecmp(v->name, "spanmap")) {
11203             spanno = atoi(v->value);
11204             if (spanno > 0) {
11205                if ((c = strchr(v->value, ','))) {
11206                   trunkgroup = atoi(c + 1);
11207                   if (trunkgroup > 0) {
11208                      if ((c = strchr(c + 1, ','))) 
11209                         logicalspan = atoi(c + 1);
11210                      else
11211                         logicalspan = 0;
11212                      if (logicalspan >= 0) {
11213                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
11214                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11215                         } else if (option_verbose > 1) 
11216                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11217                      } else
11218                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
11219                   } else
11220                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
11221                } else
11222                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
11223             } else
11224                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
11225          } else {
11226             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
11227          }
11228          v = v->next;
11229       }
11230    }
11231 #endif
11232    
11233    /* Copy the default jb config over global_jbconf */
11234    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
11235 
11236    v = ast_variable_browse(cfg, "channels");
11237    res = process_zap(&conf, v, reload, 0);
11238    ast_mutex_unlock(&iflock);
11239    ast_config_destroy(cfg);
11240    if (res)
11241       return res;
11242    cfg = ast_config_load("users.conf");
11243    if (cfg) {
11244       char *cat;
11245       const char *chans;
11246       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
11247       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
11248          if (!strcasecmp(cat, "general"))
11249             continue;
11250          chans = ast_variable_retrieve(cfg, cat, "zapchan");
11251          if (!ast_strlen_zero(chans)) {
11252             /** \todo At this point we should probably 
11253              * duplicate conf, and pass a copy, to prevent 
11254              * one section from affecting another
11255              */
11256             process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
11257          }
11258       }
11259       ast_config_destroy(cfg);
11260    }
11261 #ifdef HAVE_PRI
11262    if (!reload) {
11263       for (x = 0; x < NUM_SPANS; x++) {
11264          if (pris[x].pvts[0]) {
11265             if (start_pri(pris + x)) {
11266                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11267                return -1;
11268             } else if (option_verbose > 1)
11269                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11270          }
11271       }
11272    }
11273 #endif
11274    /* And start the monitor for the first time */
11275    restart_monitor();
11276    return 0;
11277 }
11278 
11279 static int load_module(void)
11280 {
11281    int res;
11282 
11283 #ifdef HAVE_PRI
11284    int y,i;
11285    memset(pris, 0, sizeof(pris));
11286    for (y = 0; y < NUM_SPANS; y++) {
11287       ast_mutex_init(&pris[y].lock);
11288       pris[y].offset = -1;
11289       pris[y].master = AST_PTHREADT_NULL;
11290       for (i = 0; i < NUM_DCHANS; i++)
11291          pris[y].fds[i] = -1;
11292    }
11293    pri_set_error(zt_pri_error);
11294    pri_set_message(zt_pri_message);
11295    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
11296          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
11297 #endif
11298    res = setup_zap(0);
11299    /* Make sure we can register our Zap channel type */
11300    if (res)
11301       return AST_MODULE_LOAD_DECLINE;
11302    if (ast_channel_register(&zap_tech)) {
11303       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
11304       __unload_module();
11305       return -1;
11306    }
11307 #ifdef HAVE_PRI
11308    ast_string_field_init(&inuse, 16);
11309    ast_string_field_set(&inuse, name, "GR-303InUse");
11310    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11311 #endif   
11312    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11313    
11314    memset(round_robin, 0, sizeof(round_robin));
11315    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11316    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11317    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11318    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11319    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11320    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11321    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
11322 
11323    return res;
11324 }
11325 
11326 static int zt_sendtext(struct ast_channel *c, const char *text)
11327 {
11328 #define  END_SILENCE_LEN 400
11329 #define  HEADER_MS 50
11330 #define  TRAILER_MS 5
11331 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11332 #define  ASCII_BYTES_PER_CHAR 80
11333 
11334    unsigned char *buf,*mybuf;
11335    struct zt_pvt *p = c->tech_pvt;
11336    struct pollfd fds[1];
11337    int size,res,fd,len,x;
11338    int bytes=0;
11339    /* Initial carrier (imaginary) */
11340    float cr = 1.0;
11341    float ci = 0.0;
11342    float scont = 0.0;
11343    int index;
11344 
11345    index = zt_get_index(c, p, 0);
11346    if (index < 0) {
11347       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11348       return -1;
11349    }
11350    if (!text[0]) return(0); /* if nothing to send, dont */
11351    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11352    if (p->mate) 
11353       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11354    else
11355       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11356    if (!buf)
11357       return -1;
11358    mybuf = buf;
11359    if (p->mate) {
11360       int codec = AST_LAW(p);
11361       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
11362          PUT_CLID_MARKMS;
11363       }
11364       /* Put actual message */
11365       for (x = 0; text[x]; x++) {
11366          PUT_CLID(text[x]);
11367       }
11368       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
11369          PUT_CLID_MARKMS;
11370       }
11371       len = bytes;
11372       buf = mybuf;
11373    } else {
11374       len = tdd_generate(p->tdd, buf, text);
11375       if (len < 1) {
11376          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
11377          free(mybuf);
11378          return -1;
11379       }
11380    }
11381    memset(buf + len, 0x7f, END_SILENCE_LEN);
11382    len += END_SILENCE_LEN;
11383    fd = p->subs[index].zfd;
11384    while (len) {
11385       if (ast_check_hangup(c)) {
11386          free(mybuf);
11387          return -1;
11388       }
11389       size = len;
11390       if (size > READ_SIZE)
11391          size = READ_SIZE;
11392       fds[0].fd = fd;
11393       fds[0].events = POLLOUT | POLLPRI;
11394       fds[0].revents = 0;
11395       res = poll(fds, 1, -1);
11396       if (!res) {
11397          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11398          continue;
11399       }
11400         /* if got exception */
11401       if (fds[0].revents & POLLPRI)
11402          return -1;
11403       if (!(fds[0].revents & POLLOUT)) {
11404          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11405          continue;
11406       }
11407       res = write(fd, buf, size);
11408       if (res != size) {
11409          if (res == -1) {
11410             free(mybuf);
11411             return -1;
11412          }
11413          if (option_debug)
11414             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11415          break;
11416       }
11417       len -= size;
11418       buf += size;
11419    }
11420    free(mybuf);
11421    return(0);
11422 }
11423 
11424 
11425 static int reload(void)
11426 {
11427    int res = 0;
11428 
11429    res = setup_zap(1);
11430    if (res) {
11431       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11432       return -1;
11433    }
11434    return 0;
11435 }
11436 
11437 /* This is a workaround so that menuselect displays a proper description
11438  * AST_MODULE_INFO(, , "Zapata Telephony"
11439  */
11440 
11441 #ifdef ZAPATA_PRI
11442 #define tdesc "Zapata Telephony w/PRI"
11443 #else
11444 #define tdesc "Zapata Telephony"
11445 #endif
11446 
11447 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
11448       .load = load_module,
11449       .unload = unload_module,
11450       .reload = reload,
11451           );
11452 
11453 

Generated on Fri Aug 24 02:22:14 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1