Wed Aug 15 01:24:19 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>res_smdi</depend>
00042    <depend>zaptel_vldtmf</depend>
00043    <depend>zaptel</depend>
00044    <depend>tonezone</depend>
00045    <use>pri</use>
00046  ***/
00047 
00048 #include "asterisk.h"
00049 
00050 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 78371 $")
00051 
00052 #include <stdio.h>
00053 #include <string.h>
00054 #ifdef __NetBSD__
00055 #include <pthread.h>
00056 #include <signal.h>
00057 #else
00058 #include <sys/signal.h>
00059 #endif
00060 #include <errno.h>
00061 #include <stdlib.h>
00062 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00063 #include <stdint.h>
00064 #endif
00065 #include <unistd.h>
00066 #include <sys/ioctl.h>
00067 #include <math.h>
00068 #include <ctype.h>
00069 #include <zaptel/zaptel.h>
00070 #include <zaptel/tonezone.h>
00071 
00072 #ifdef HAVE_PRI
00073 #include <libpri.h>
00074 #endif
00075 
00076 #include "asterisk/lock.h"
00077 #include "asterisk/channel.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/logger.h"
00080 #include "asterisk/module.h"
00081 #include "asterisk/pbx.h"
00082 #include "asterisk/options.h"
00083 #include "asterisk/file.h"
00084 #include "asterisk/ulaw.h"
00085 #include "asterisk/alaw.h"
00086 #include "asterisk/callerid.h"
00087 #include "asterisk/adsi.h"
00088 #include "asterisk/cli.h"
00089 #include "asterisk/cdr.h"
00090 #include "asterisk/features.h"
00091 #include "asterisk/musiconhold.h"
00092 #include "asterisk/say.h"
00093 #include "asterisk/tdd.h"
00094 #include "asterisk/app.h"
00095 #include "asterisk/dsp.h"
00096 #include "asterisk/astdb.h"
00097 #include "asterisk/manager.h"
00098 #include "asterisk/causes.h"
00099 #include "asterisk/term.h"
00100 #include "asterisk/utils.h"
00101 #include "asterisk/transcap.h"
00102 #include "asterisk/stringfields.h"
00103 #include "asterisk/abstract_jb.h"
00104 #include "asterisk/smdi.h"
00105 #include "asterisk/astobj.h"
00106 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00107 
00108 /*! Global jitterbuffer configuration - by default, jb is disabled */
00109 static struct ast_jb_conf default_jbconf =
00110 {
00111    .flags = 0,
00112    .max_size = -1,
00113    .resync_threshold = -1,
00114    .impl = ""
00115 };
00116 static struct ast_jb_conf global_jbconf;
00117 
00118 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00119 #error "Your zaptel is too old.  Please update"
00120 #endif
00121 
00122 #ifndef ZT_TONEDETECT
00123 /* Work around older code with no tone detect */
00124 #define ZT_EVENT_DTMFDOWN 0
00125 #define ZT_EVENT_DTMFUP 0
00126 #endif
00127 
00128 /* define this to send PRI user-user information elements */
00129 #undef SUPPORT_USERUSER
00130 
00131 /*! 
00132  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00133  * the user hangs up to reset the state machine so ring works properly.
00134  * This is used to be able to support kewlstart by putting the zhone in
00135  * groundstart mode since their forward disconnect supervision is entirely
00136  * broken even though their documentation says it isn't and their support
00137  * is entirely unwilling to provide any assistance with their channel banks
00138  * even though their web site says they support their products for life.
00139  */
00140 /* #define ZHONE_HACK */
00141 
00142 /*! \note
00143  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00144  * before dialing on it.  Certain FXO interfaces always think they're out of
00145  * service with this method however.
00146  */
00147 /* #define ZAP_CHECK_HOOKSTATE */
00148 
00149 /*! \brief Typically, how many rings before we should send Caller*ID */
00150 #define DEFAULT_CIDRINGS 1
00151 
00152 #define CHANNEL_PSEUDO -12
00153 
00154 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00155 
00156 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00157 #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)) 
00158 
00159 static const char tdesc[] = "Zapata Telephony Driver"
00160 #ifdef HAVE_PRI
00161                " w/PRI"
00162 #endif
00163 ;
00164 
00165 static const char config[] = "zapata.conf";
00166 
00167 #define SIG_EM    ZT_SIG_EM
00168 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00169 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00170 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00171 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00172 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00173 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00174 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00175 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00176 #define SIG_FXSLS ZT_SIG_FXSLS
00177 #define SIG_FXSGS ZT_SIG_FXSGS
00178 #define SIG_FXSKS ZT_SIG_FXSKS
00179 #define SIG_FXOLS ZT_SIG_FXOLS
00180 #define SIG_FXOGS ZT_SIG_FXOGS
00181 #define SIG_FXOKS ZT_SIG_FXOKS
00182 #define SIG_PRI      ZT_SIG_CLEAR
00183 #define  SIG_SF      ZT_SIG_SF
00184 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00185 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00186 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00187 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00188 #define SIG_EM_E1 ZT_SIG_EM_E1
00189 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00190 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00191 
00192 #define NUM_SPANS       32
00193 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00194 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00195 
00196 #define CHAN_PSEUDO  -2
00197 
00198 #define DCHAN_PROVISIONED (1 << 0)
00199 #define DCHAN_NOTINALARM  (1 << 1)
00200 #define DCHAN_UP          (1 << 2)
00201 
00202 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00203 
00204 static char defaultcic[64] = "";
00205 static char defaultozz[64] = "";
00206 
00207 static char progzone[10] = "";
00208 
00209 static int distinctiveringaftercid = 0;
00210 
00211 static int numbufs = 4;
00212 
00213 #ifdef HAVE_PRI
00214 static struct ast_channel inuse;
00215 #ifdef PRI_GETSET_TIMERS
00216 static int pritimers[PRI_MAX_TIMERS];
00217 #endif
00218 static int pridebugfd = -1;
00219 static char pridebugfilename[1024] = "";
00220 #endif
00221 
00222 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00223 static int firstdigittimeout = 16000;
00224 
00225 /*! \brief How long to wait for following digits (FXO logic) */
00226 static int gendigittimeout = 8000;
00227 
00228 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00229 static int matchdigittimeout = 3000;
00230 
00231 /*! \brief Protect the interface list (of zt_pvt's) */
00232 AST_MUTEX_DEFINE_STATIC(iflock);
00233 
00234 
00235 static int ifcount = 0;
00236 
00237 #ifdef HAVE_PRI
00238 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00239 #endif
00240 
00241 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00242    when it's doing something critical. */
00243 AST_MUTEX_DEFINE_STATIC(monlock);
00244 
00245 /*! \brief This is the thread for the monitor which checks for input on the channels
00246    which are not currently in use. */
00247 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00248 
00249 static int restart_monitor(void);
00250 
00251 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);
00252 
00253 static int zt_sendtext(struct ast_channel *c, const char *text);
00254 
00255 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00256 static inline int zt_get_event(int fd)
00257 {
00258    int j;
00259    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00260       return -1;
00261    return j;
00262 }
00263 
00264 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00265 static inline int zt_wait_event(int fd)
00266 {
00267    int i, j = 0;
00268    i = ZT_IOMUX_SIGEVENT;
00269    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00270       return -1;
00271    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00272       return -1;
00273    return j;
00274 }
00275 
00276 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00277 #define READ_SIZE 160
00278 
00279 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00280 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00281 
00282 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00283 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 300 ms */
00284 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00285 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00286 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE)
00287 
00288 struct zt_pvt;
00289 
00290 static int ringt_base = DEFAULT_RINGT;
00291 
00292 #ifdef HAVE_PRI
00293 
00294 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00295 #define PRI_CHANNEL(p) ((p) & 0xff)
00296 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00297 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00298 
00299 struct zt_pri {
00300    pthread_t master;                /*!< Thread of master */
00301    ast_mutex_t lock;                /*!< Mutex */
00302    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00303    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00304    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00305    int minunused;                   /*!< Min # of channels to keep empty */
00306    int minidle;                     /*!< Min # of "idling" calls to keep active */
00307    int nodetype;                    /*!< Node type */
00308    int switchtype;                     /*!< Type of switch to emulate */
00309    int nsf;                   /*!< Network-Specific Facilities */
00310    int dialplan;                    /*!< Dialing plan */
00311    int localdialplan;                  /*!< Local dialing plan */
00312    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00313    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00314    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00315    char privateprefix[20];                /*!< for private dialplans */
00316    char unknownprefix[20];                /*!< for unknown dialplans */
00317    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00318    int trunkgroup;                     /*!< What our trunkgroup is */
00319    int mastertrunkgroup;                  /*!< What trunk group is our master */
00320    int prilogicalspan;                 /*!< Logical span number within trunk group */
00321    int numchans;                    /*!< Num of channels we represent */
00322    int overlapdial;                 /*!< In overlap dialing mode */
00323    int facilityenable;                 /*!< Enable facility IEs */
00324    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00325    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00326    struct pri *pri;                 /*!< Currently active D-channel */
00327    int debug;
00328    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00329    int offset;
00330    int span;
00331    int resetting;
00332    int resetpos;
00333    time_t lastreset;                /*!< time when unused channels were last reset */
00334    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00335    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00336    struct zt_pvt *crvs;                /*!< Member CRV structs */
00337    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00338 };
00339 
00340 
00341 static struct zt_pri pris[NUM_SPANS];
00342 
00343 #if 0
00344 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00345 #else
00346 #define DEFAULT_PRI_DEBUG 0
00347 #endif
00348 
00349 static inline void pri_rel(struct zt_pri *pri)
00350 {
00351    ast_mutex_unlock(&pri->lock);
00352 }
00353 
00354 #else
00355 /*! Shut up the compiler */
00356 struct zt_pri;
00357 #endif
00358 
00359 #define SUB_REAL  0        /*!< Active call */
00360 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00361 #define SUB_THREEWAY 2        /*!< Three-way call */
00362 
00363 /* Polarity states */
00364 #define POLARITY_IDLE   0
00365 #define POLARITY_REV    1
00366 
00367 
00368 static struct zt_distRings drings;
00369 
00370 struct distRingData {
00371    int ring[3];
00372 };
00373 struct ringContextData {
00374    char contextData[AST_MAX_CONTEXT];
00375 };
00376 struct zt_distRings {
00377    struct distRingData ringnum[3];
00378    struct ringContextData ringContext[3];
00379 };
00380 
00381 static char *subnames[] = {
00382    "Real",
00383    "Callwait",
00384    "Threeway"
00385 };
00386 
00387 struct zt_subchannel {
00388    int zfd;
00389    struct ast_channel *owner;
00390    int chan;
00391    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00392    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00393    unsigned int needringing:1;
00394    unsigned int needbusy:1;
00395    unsigned int needcongestion:1;
00396    unsigned int needcallerid:1;
00397    unsigned int needanswer:1;
00398    unsigned int needflash:1;
00399    unsigned int needhold:1;
00400    unsigned int needunhold:1;
00401    unsigned int linear:1;
00402    unsigned int inthreeway:1;
00403    ZT_CONFINFO curconf;
00404 };
00405 
00406 #define CONF_USER_REAL     (1 << 0)
00407 #define CONF_USER_THIRDCALL   (1 << 1)
00408 
00409 #define MAX_SLAVES   4
00410 
00411 static struct zt_pvt {
00412    ast_mutex_t lock;
00413    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00414                      /*!< Up to three channels can be associated with this call */
00415       
00416    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00417    struct zt_subchannel subs[3];       /*!< Sub-channels */
00418    struct zt_confinfo saveconf;        /*!< Saved conference info */
00419 
00420    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00421    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00422    int inconference;          /*!< If our real should be in the conference */
00423    
00424    int sig;             /*!< Signalling style */
00425    int radio;              /*!< radio type */
00426    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00427    int oprmode;               /*!< "Operator Services" mode */
00428    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00429    float rxgain;
00430    float txgain;
00431    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00432    struct zt_pvt *next;          /*!< Next channel in list */
00433    struct zt_pvt *prev;          /*!< Prev channel in list */
00434 
00435    /* flags */
00436    unsigned int adsi:1;
00437    unsigned int answeronpolarityswitch:1;
00438    unsigned int busydetect:1;
00439    unsigned int callreturn:1;
00440    unsigned int callwaiting:1;
00441    unsigned int callwaitingcallerid:1;
00442    unsigned int cancallforward:1;
00443    unsigned int canpark:1;
00444    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00445    unsigned int destroy:1;
00446    unsigned int didtdd:1;           /*!< flag to say its done it once */
00447    unsigned int dialednone:1;
00448    unsigned int dialing:1;
00449    unsigned int digital:1;
00450    unsigned int dnd:1;
00451    unsigned int echobreak:1;
00452    unsigned int echocanbridged:1;
00453    unsigned int echocanon:1;
00454    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00455    unsigned int firstradio:1;
00456    unsigned int hanguponpolarityswitch:1;
00457    unsigned int hardwaredtmf:1;
00458    unsigned int hidecallerid:1;
00459    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00460    unsigned int ignoredtmf:1;
00461    unsigned int immediate:1;        /*!< Answer before getting digits? */
00462    unsigned int inalarm:1;
00463    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00464    unsigned int outgoing:1;
00465    unsigned int overlapdial:1;
00466    unsigned int permcallwaiting:1;
00467    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00468    unsigned int priindication_oob:1;
00469    unsigned int priexclusive:1;
00470    unsigned int pulse:1;
00471    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00472    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00473    unsigned int threewaycalling:1;
00474    unsigned int transfer:1;
00475    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00476    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00477    unsigned int usedistinctiveringdetection:1;
00478    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00479    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00480 #if defined(HAVE_PRI)
00481    unsigned int alerting:1;
00482    unsigned int alreadyhungup:1;
00483    unsigned int isidlecall:1;
00484    unsigned int proceeding:1;
00485    unsigned int progress:1;
00486    unsigned int resetting:1;
00487    unsigned int setup_ack:1;
00488 #endif
00489    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00490    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00491 
00492    struct zt_distRings drings;
00493 
00494    char context[AST_MAX_CONTEXT];
00495    char defcontext[AST_MAX_CONTEXT];
00496    char exten[AST_MAX_EXTENSION];
00497    char language[MAX_LANGUAGE];
00498    char mohinterpret[MAX_MUSICCLASS];
00499    char mohsuggest[MAX_MUSICCLASS];
00500 #ifdef PRI_ANI
00501    char cid_ani[AST_MAX_EXTENSION];
00502 #endif
00503    char cid_num[AST_MAX_EXTENSION];
00504    int cid_ton;               /*!< Type Of Number (TON) */
00505    char cid_name[AST_MAX_EXTENSION];
00506    char lastcid_num[AST_MAX_EXTENSION];
00507    char lastcid_name[AST_MAX_EXTENSION];
00508    char *origcid_num;            /*!< malloced original callerid */
00509    char *origcid_name;           /*!< malloced original callerid */
00510    char callwait_num[AST_MAX_EXTENSION];
00511    char callwait_name[AST_MAX_EXTENSION];
00512    char rdnis[AST_MAX_EXTENSION];
00513    char dnid[AST_MAX_EXTENSION];
00514    ast_group_t group;
00515    int law;
00516    int confno;             /*!< Our conference */
00517    int confusers;             /*!< Who is using our conference */
00518    int propconfno;               /*!< Propagated conference number */
00519    ast_group_t callgroup;
00520    ast_group_t pickupgroup;
00521    int channel;               /*!< Channel Number or CRV */
00522    int span;               /*!< Span number */
00523    time_t guardtime;          /*!< Must wait this much time before using for new call */
00524    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00525    int cid_start;             /*!< CID start indicator, polarity or ring */
00526    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00527    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00528    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00529    unsigned char *cidspill;
00530    int cidpos;
00531    int cidlen;
00532    int ringt;
00533    int ringt_base;
00534    int stripmsd;
00535    int callwaitcas;
00536    int callwaitrings;
00537    int echocancel;
00538    int echotraining;
00539    char echorest[20];
00540    int busycount;
00541    int busy_tonelength;
00542    int busy_quietlength;
00543    int callprogress;
00544    struct timeval flashtime;        /*!< Last flash-hook time */
00545    struct ast_dsp *dsp;
00546    int cref;               /*!< Call reference number */
00547    ZT_DIAL_OPERATION dop;
00548    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00549    char finaldial[64];
00550    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00551    int amaflags;              /*!< AMA Flags */
00552    struct tdd_state *tdd;           /*!< TDD flag */
00553    char call_forward[AST_MAX_EXTENSION];
00554    char mailbox[AST_MAX_EXTENSION];
00555    char dialdest[256];
00556    int onhooktime;
00557    int msgstate;
00558    int distinctivering;          /*!< Which distinctivering to use */
00559    int cidrings;              /*!< Which ring to deliver CID on */
00560    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00561    int fake_event;
00562    int polarityonanswerdelay;
00563    struct timeval polaritydelaytv;
00564    int sendcalleridafter;
00565 #ifdef HAVE_PRI
00566    struct zt_pri *pri;
00567    struct zt_pvt *bearer;
00568    struct zt_pvt *realcall;
00569    q931_call *call;
00570    int prioffset;
00571    int logicalspan;
00572 #endif   
00573    int polarity;
00574    int dsp_features;
00575    char begindigit;
00576 } *iflist = NULL, *ifend = NULL;
00577 
00578 /*! \brief Channel configuration from zapata.conf .
00579  * This struct is used for parsing the [channels] section of zapata.conf.
00580  * Generally there is a field here for every possible configuration item.
00581  *
00582  * The state of fields is saved along the parsing and whenever a 'channel'
00583  * statement is reached, the current zt_chan_conf is used to configure the 
00584  * channel (struct zt_pvt)
00585  *
00586  * @seealso zt_chan_init for the default values.
00587  */
00588 struct zt_chan_conf {
00589    struct zt_pvt chan;
00590 #ifdef HAVE_PRI
00591    struct zt_pri pri;
00592 #endif
00593    ZT_PARAMS timing;
00594 
00595    char smdi_port[SMDI_MAX_FILENAME_LEN];
00596 };
00597 
00598 /** returns a new zt_chan_conf with default values (by-value) */
00599 static struct zt_chan_conf zt_chan_conf_default(void) {
00600    /* recall that if a field is not included here it is initialized
00601     * to 0 or equivalent
00602     */
00603    struct zt_chan_conf conf = {
00604 #ifdef HAVE_PRI
00605       .pri = {
00606          .nsf = PRI_NSF_NONE,
00607          .switchtype = PRI_SWITCH_NI2,
00608          .dialplan = PRI_NATIONAL_ISDN + 1,
00609          .localdialplan = PRI_NATIONAL_ISDN + 1,
00610          .nodetype = PRI_CPE,
00611 
00612          .minunused = 2,
00613          .idleext = "",
00614          .idledial = "",
00615          .internationalprefix = "",
00616          .nationalprefix = "",
00617          .localprefix = "",
00618          .privateprefix = "",
00619          .unknownprefix = "",
00620 
00621          .resetinterval = 3600
00622       },
00623 #endif
00624       .chan = {
00625          .context = "default",
00626          .cid_num = "",
00627          .cid_name = "",
00628          .mohinterpret = "default",
00629          .mohsuggest = "",
00630          .transfertobusy = 1,
00631 
00632          .cid_signalling = CID_SIG_BELL,
00633          .cid_start = CID_START_RING,
00634          .zaptrcallerid = 0,
00635          .use_callerid = 1,
00636          .sig = -1,
00637          .outsigmod = -1,
00638 
00639          .tonezone = -1,
00640 
00641          .echocancel = 1,
00642 
00643          .busycount = 3,
00644 
00645          .accountcode = "",
00646 
00647          .mailbox = "",
00648 
00649 
00650          .polarityonanswerdelay = 600,
00651 
00652          .sendcalleridafter = DEFAULT_CIDRINGS
00653       },
00654       .timing = {
00655          .prewinktime = -1,
00656          .preflashtime = -1,
00657          .winktime = -1,
00658          .flashtime = -1,
00659          .starttime = -1,
00660          .rxwinktime = -1,
00661          .rxflashtime = -1,
00662          .debouncetime = -1
00663       },
00664       .smdi_port = "/dev/ttyS0",
00665    };
00666 
00667    return conf;
00668 }
00669 
00670 
00671 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00672 static int zt_digit_begin(struct ast_channel *ast, char digit);
00673 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00674 static int zt_sendtext(struct ast_channel *c, const char *text);
00675 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00676 static int zt_hangup(struct ast_channel *ast);
00677 static int zt_answer(struct ast_channel *ast);
00678 static struct ast_frame *zt_read(struct ast_channel *ast);
00679 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00680 static struct ast_frame *zt_exception(struct ast_channel *ast);
00681 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00682 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00683 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00684 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00685 
00686 static const struct ast_channel_tech zap_tech = {
00687    .type = "Zap",
00688    .description = tdesc,
00689    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00690    .requester = zt_request,
00691    .send_digit_begin = zt_digit_begin,
00692    .send_digit_end = zt_digit_end,
00693    .send_text = zt_sendtext,
00694    .call = zt_call,
00695    .hangup = zt_hangup,
00696    .answer = zt_answer,
00697    .read = zt_read,
00698    .write = zt_write,
00699    .bridge = zt_bridge,
00700    .exception = zt_exception,
00701    .indicate = zt_indicate,
00702    .fixup = zt_fixup,
00703    .setoption = zt_setoption,
00704    .func_channel_read = zt_func_read,
00705 };
00706 
00707 #ifdef HAVE_PRI
00708 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00709 #else
00710 #define GET_CHANNEL(p) ((p)->channel)
00711 #endif
00712 
00713 struct zt_pvt *round_robin[32];
00714 
00715 #ifdef HAVE_PRI
00716 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00717 {
00718    int res;
00719    /* Grab the lock first */
00720    do {
00721       res = ast_mutex_trylock(&pri->lock);
00722       if (res) {
00723          ast_mutex_unlock(&pvt->lock);
00724          /* Release the lock and try again */
00725          usleep(1);
00726          ast_mutex_lock(&pvt->lock);
00727       }
00728    } while (res);
00729    /* Then break the poll */
00730    pthread_kill(pri->master, SIGURG);
00731    return 0;
00732 }
00733 #endif
00734 
00735 #define NUM_CADENCE_MAX 25
00736 static int num_cadence = 4;
00737 static int user_has_defined_cadences = 0;
00738 
00739 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00740    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00741    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00742    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00743    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00744 };
00745 
00746 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00747  * is 1, the second pause is 2 and so on.
00748  */
00749 
00750 static int cidrings[NUM_CADENCE_MAX] = {
00751    2,                            /*!< Right after first long ring */
00752    4,                            /*!< Right after long part */
00753    3,                            /*!< After third chirp */
00754    2,                            /*!< Second spell */
00755 };
00756 
00757 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00758          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00759 
00760 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00761 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00762 
00763 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00764 {
00765    int res;
00766    if (p->subs[0].owner == ast)
00767       res = 0;
00768    else if (p->subs[1].owner == ast)
00769       res = 1;
00770    else if (p->subs[2].owner == ast)
00771       res = 2;
00772    else {
00773       res = -1;
00774       if (!nullok)
00775          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00776    }
00777    return res;
00778 }
00779 
00780 #ifdef HAVE_PRI
00781 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00782 #else
00783 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00784 #endif
00785 {
00786 #ifdef HAVE_PRI
00787    if (pri)
00788       ast_mutex_unlock(&pri->lock);
00789 #endif         
00790    for (;;) {
00791       if (p->subs[a].owner) {
00792          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00793             ast_mutex_unlock(&p->lock);
00794             usleep(1);
00795             ast_mutex_lock(&p->lock);
00796          } else {
00797             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00798             ast_mutex_unlock(&p->subs[a].owner->lock);
00799             break;
00800          }
00801       } else
00802          break;
00803    }
00804 #ifdef HAVE_PRI
00805    if (pri)
00806       ast_mutex_lock(&pri->lock);
00807 #endif         
00808 }
00809 
00810 #ifdef HAVE_PRI
00811 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00812 #else
00813 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00814 #endif
00815 {
00816    /* We must unlock the PRI to avoid the possibility of a deadlock */
00817 #ifdef HAVE_PRI
00818    if (pri)
00819       ast_mutex_unlock(&pri->lock);
00820 #endif      
00821    for (;;) {
00822       if (p->owner) {
00823          if (ast_mutex_trylock(&p->owner->lock)) {
00824             ast_mutex_unlock(&p->lock);
00825             usleep(1);
00826             ast_mutex_lock(&p->lock);
00827          } else {
00828             ast_queue_frame(p->owner, f);
00829             ast_mutex_unlock(&p->owner->lock);
00830             break;
00831          }
00832       } else
00833          break;
00834    }
00835 #ifdef HAVE_PRI
00836    if (pri)
00837       ast_mutex_lock(&pri->lock);
00838 #endif      
00839 }
00840 
00841 static int restore_gains(struct zt_pvt *p);
00842 
00843 static void swap_subs(struct zt_pvt *p, int a, int b)
00844 {
00845    int tchan;
00846    int tinthreeway;
00847    struct ast_channel *towner;
00848 
00849    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00850 
00851    tchan = p->subs[a].chan;
00852    towner = p->subs[a].owner;
00853    tinthreeway = p->subs[a].inthreeway;
00854 
00855    p->subs[a].chan = p->subs[b].chan;
00856    p->subs[a].owner = p->subs[b].owner;
00857    p->subs[a].inthreeway = p->subs[b].inthreeway;
00858 
00859    p->subs[b].chan = tchan;
00860    p->subs[b].owner = towner;
00861    p->subs[b].inthreeway = tinthreeway;
00862 
00863    if (p->subs[a].owner) 
00864       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00865    if (p->subs[b].owner) 
00866       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00867    wakeup_sub(p, a, NULL);
00868    wakeup_sub(p, b, NULL);
00869 }
00870 
00871 static int zt_open(char *fn)
00872 {
00873    int fd;
00874    int isnum;
00875    int chan = 0;
00876    int bs;
00877    int x;
00878    isnum = 1;
00879    for (x = 0; x < strlen(fn); x++) {
00880       if (!isdigit(fn[x])) {
00881          isnum = 0;
00882          break;
00883       }
00884    }
00885    if (isnum) {
00886       chan = atoi(fn);
00887       if (chan < 1) {
00888          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00889          return -1;
00890       }
00891       fn = "/dev/zap/channel";
00892    }
00893    fd = open(fn, O_RDWR | O_NONBLOCK);
00894    if (fd < 0) {
00895       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00896       return -1;
00897    }
00898    if (chan) {
00899       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00900          x = errno;
00901          close(fd);
00902          errno = x;
00903          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00904          return -1;
00905       }
00906    }
00907    bs = READ_SIZE;
00908    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) return -1;
00909    return fd;
00910 }
00911 
00912 static void zt_close(int fd)
00913 {
00914    if (fd > 0)
00915       close(fd);
00916 }
00917 
00918 static int zt_setlinear(int zfd, int linear)
00919 {
00920    int res;
00921    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00922    if (res)
00923       return res;
00924    return 0;
00925 }
00926 
00927 
00928 static int alloc_sub(struct zt_pvt *p, int x)
00929 {
00930    ZT_BUFFERINFO bi;
00931    int res;
00932    if (p->subs[x].zfd < 0) {
00933       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00934       if (p->subs[x].zfd > -1) {
00935          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00936          if (!res) {
00937             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00938             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00939             bi.numbufs = numbufs;
00940             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
00941             if (res < 0) {
00942                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
00943             }
00944          } else 
00945             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
00946          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
00947             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
00948             zt_close(p->subs[x].zfd);
00949             p->subs[x].zfd = -1;
00950             return -1;
00951          }
00952          if (option_debug)
00953             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
00954          return 0;
00955       } else
00956          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00957       return -1;
00958    }
00959    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
00960    return -1;
00961 }
00962 
00963 static int unalloc_sub(struct zt_pvt *p, int x)
00964 {
00965    if (!x) {
00966       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
00967       return -1;
00968    }
00969    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
00970    if (p->subs[x].zfd > -1) {
00971       zt_close(p->subs[x].zfd);
00972    }
00973    p->subs[x].zfd = -1;
00974    p->subs[x].linear = 0;
00975    p->subs[x].chan = 0;
00976    p->subs[x].owner = NULL;
00977    p->subs[x].inthreeway = 0;
00978    p->polarity = POLARITY_IDLE;
00979    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
00980    return 0;
00981 }
00982 
00983 static int digit_to_dtmfindex(char digit)
00984 {
00985    if (isdigit(digit))
00986       return ZT_TONE_DTMF_BASE + (digit - '0');
00987    else if (digit >= 'A' && digit <= 'D')
00988       return ZT_TONE_DTMF_A + (digit - 'A');
00989    else if (digit >= 'a' && digit <= 'd')
00990       return ZT_TONE_DTMF_A + (digit - 'a');
00991    else if (digit == '*')
00992       return ZT_TONE_DTMF_s;
00993    else if (digit == '#')
00994       return ZT_TONE_DTMF_p;
00995    else
00996       return -1;
00997 }
00998 
00999 static int zt_digit_begin(struct ast_channel *chan, char digit)
01000 {
01001    struct zt_pvt *pvt;
01002    int index;
01003    int dtmf = -1;
01004    
01005    pvt = chan->tech_pvt;
01006 
01007    ast_mutex_lock(&pvt->lock);
01008 
01009    index = zt_get_index(chan, pvt, 0);
01010 
01011    if ((index != SUB_REAL) || !pvt->owner)
01012       goto out;
01013 
01014 #ifdef HAVE_PRI
01015    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01016       if (pvt->setup_ack) {
01017          if (!pri_grab(pvt, pvt->pri)) {
01018             pri_information(pvt->pri->pri, pvt->call, digit);
01019             pri_rel(pvt->pri);
01020          } else
01021             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01022       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01023          int res;
01024          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01025          res = strlen(pvt->dialdest);
01026          pvt->dialdest[res++] = digit;
01027          pvt->dialdest[res] = '\0';
01028       }
01029       goto out;
01030    }
01031 #endif
01032    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01033       goto out;
01034 
01035    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01036       int res;
01037       ZT_DIAL_OPERATION zo = {
01038          .op = ZT_DIAL_OP_APPEND,
01039          .dialstr[0] = 'T',
01040          .dialstr[1] = digit,
01041          .dialstr[2] = 0,
01042       };
01043       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01044          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01045       else
01046          pvt->dialing = 1;
01047    } else {
01048       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01049       pvt->dialing = 1;
01050       pvt->begindigit = digit;
01051    }
01052 
01053 out:
01054    ast_mutex_unlock(&pvt->lock);
01055 
01056    return 0;
01057 }
01058 
01059 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01060 {
01061    struct zt_pvt *pvt;
01062    int res = 0;
01063    int index;
01064    int x;
01065    
01066    pvt = chan->tech_pvt;
01067 
01068    ast_mutex_lock(&pvt->lock);
01069    
01070    index = zt_get_index(chan, pvt, 0);
01071 
01072    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01073       goto out;
01074 
01075 #ifdef HAVE_PRI
01076    /* This means that the digit was already sent via PRI signalling */
01077    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01078       goto out;
01079 #endif
01080 
01081    if (pvt->begindigit) {
01082       x = -1;
01083       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01084       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01085       pvt->dialing = 0;
01086       pvt->begindigit = 0;
01087    }
01088 
01089 out:
01090    ast_mutex_unlock(&pvt->lock);
01091 
01092    return res;
01093 }
01094 
01095 static char *events[] = {
01096    "No event",
01097    "On hook",
01098    "Ring/Answered",
01099    "Wink/Flash",
01100    "Alarm",
01101    "No more alarm",
01102    "HDLC Abort",
01103    "HDLC Overrun",
01104    "HDLC Bad FCS",
01105    "Dial Complete",
01106    "Ringer On",
01107    "Ringer Off",
01108    "Hook Transition Complete",
01109    "Bits Changed",
01110    "Pulse Start",
01111    "Timer Expired",
01112    "Timer Ping",
01113    "Polarity Reversal",
01114    "Ring Begin",
01115 };
01116 
01117 static struct {
01118    int alarm;
01119    char *name;
01120 } alarms[] = {
01121    { ZT_ALARM_RED, "Red Alarm" },
01122    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01123    { ZT_ALARM_BLUE, "Blue Alarm" },
01124    { ZT_ALARM_RECOVER, "Recovering" },
01125    { ZT_ALARM_LOOPBACK, "Loopback" },
01126    { ZT_ALARM_NOTOPEN, "Not Open" },
01127    { ZT_ALARM_NONE, "None" },
01128 };
01129 
01130 static char *alarm2str(int alarm)
01131 {
01132    int x;
01133    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01134       if (alarms[x].alarm & alarm)
01135          return alarms[x].name;
01136    }
01137    return alarm ? "Unknown Alarm" : "No Alarm";
01138 }
01139 
01140 static char *event2str(int event)
01141 {
01142    static char buf[256];
01143    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01144       return events[event];
01145    sprintf(buf, "Event %d", event); /* safe */
01146    return buf;
01147 }
01148 
01149 #ifdef HAVE_PRI
01150 static char *dialplan2str(int dialplan)
01151 {
01152    if (dialplan == -1) {
01153       return("Dynamically set dialplan in ISDN");
01154    }
01155    return (pri_plan2str(dialplan));
01156 }
01157 #endif
01158 
01159 static char *zap_sig2str(int sig)
01160 {
01161    static char buf[256];
01162    switch (sig) {
01163    case SIG_EM:
01164       return "E & M Immediate";
01165    case SIG_EMWINK:
01166       return "E & M Wink";
01167    case SIG_EM_E1:
01168       return "E & M E1";
01169    case SIG_FEATD:
01170       return "Feature Group D (DTMF)";
01171    case SIG_FEATDMF:
01172       return "Feature Group D (MF)";
01173    case SIG_FEATDMF_TA:
01174       return "Feature Groud D (MF) Tandem Access";
01175    case SIG_FEATB:
01176       return "Feature Group B (MF)";
01177    case SIG_E911:
01178       return "E911 (MF)";
01179    case SIG_FGC_CAMA:
01180       return "FGC/CAMA (Dialpulse)";
01181    case SIG_FGC_CAMAMF:
01182       return "FGC/CAMA (MF)";
01183    case SIG_FXSLS:
01184       return "FXS Loopstart";
01185    case SIG_FXSGS:
01186       return "FXS Groundstart";
01187    case SIG_FXSKS:
01188       return "FXS Kewlstart";
01189    case SIG_FXOLS:
01190       return "FXO Loopstart";
01191    case SIG_FXOGS:
01192       return "FXO Groundstart";
01193    case SIG_FXOKS:
01194       return "FXO Kewlstart";
01195    case SIG_PRI:
01196       return "PRI Signalling";
01197    case SIG_SF:
01198       return "SF (Tone) Signalling Immediate";
01199    case SIG_SFWINK:
01200       return "SF (Tone) Signalling Wink";
01201    case SIG_SF_FEATD:
01202       return "SF (Tone) Signalling with Feature Group D (DTMF)";
01203    case SIG_SF_FEATDMF:
01204       return "SF (Tone) Signalling with Feature Group D (MF)";
01205    case SIG_SF_FEATB:
01206       return "SF (Tone) Signalling with Feature Group B (MF)";
01207    case SIG_GR303FXOKS:
01208       return "GR-303 Signalling with FXOKS";
01209    case SIG_GR303FXSKS:
01210       return "GR-303 Signalling with FXSKS";
01211    case 0:
01212       return "Pseudo Signalling";
01213    default:
01214       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01215       return buf;
01216    }
01217 }
01218 
01219 #define sig2str zap_sig2str
01220 
01221 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01222 {
01223    /* If the conference already exists, and we're already in it
01224       don't bother doing anything */
01225    ZT_CONFINFO zi;
01226    
01227    memset(&zi, 0, sizeof(zi));
01228    zi.chan = 0;
01229 
01230    if (slavechannel > 0) {
01231       /* If we have only one slave, do a digital mon */
01232       zi.confmode = ZT_CONF_DIGITALMON;
01233       zi.confno = slavechannel;
01234    } else {
01235       if (!index) {
01236          /* Real-side and pseudo-side both participate in conference */
01237          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01238             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01239       } else
01240          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01241       zi.confno = p->confno;
01242    }
01243    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01244       return 0;
01245    if (c->zfd < 0)
01246       return 0;
01247    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01248       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01249       return -1;
01250    }
01251    if (slavechannel < 1) {
01252       p->confno = zi.confno;
01253    }
01254    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01255    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01256    return 0;
01257 }
01258 
01259 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01260 {
01261    /* If they're listening to our channel, they're ours */  
01262    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01263       return 1;
01264    /* If they're a talker on our (allocated) conference, they're ours */
01265    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01266       return 1;
01267    return 0;
01268 }
01269 
01270 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01271 {
01272    ZT_CONFINFO zi;
01273    if (/* Can't delete if there's no zfd */
01274       (c->zfd < 0) ||
01275       /* Don't delete from the conference if it's not our conference */
01276       !isourconf(p, c)
01277       /* Don't delete if we don't think it's conferenced at all (implied) */
01278       ) return 0;
01279    memset(&zi, 0, sizeof(zi));
01280    zi.chan = 0;
01281    zi.confno = 0;
01282    zi.confmode = 0;
01283    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01284       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01285       return -1;
01286    }
01287    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01288    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01289    return 0;
01290 }
01291 
01292 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01293 {
01294    int x;
01295    int useslavenative;
01296    struct zt_pvt *slave = NULL;
01297    /* Start out optimistic */
01298    useslavenative = 1;
01299    /* Update conference state in a stateless fashion */
01300    for (x = 0; x < 3; x++) {
01301       /* Any three-way calling makes slave native mode *definitely* out
01302          of the question */
01303       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01304          useslavenative = 0;
01305    }
01306    /* If we don't have any 3-way calls, check to see if we have
01307       precisely one slave */
01308    if (useslavenative) {
01309       for (x = 0; x < MAX_SLAVES; x++) {
01310          if (p->slaves[x]) {
01311             if (slave) {
01312                /* Whoops already have a slave!  No 
01313                   slave native and stop right away */
01314                slave = NULL;
01315                useslavenative = 0;
01316                break;
01317             } else {
01318                /* We have one slave so far */
01319                slave = p->slaves[x];
01320             }
01321          }
01322       }
01323    }
01324    /* If no slave, slave native definitely out */
01325    if (!slave)
01326       useslavenative = 0;
01327    else if (slave->law != p->law) {
01328       useslavenative = 0;
01329       slave = NULL;
01330    }
01331    if (out)
01332       *out = slave;
01333    return useslavenative;
01334 }
01335 
01336 static int reset_conf(struct zt_pvt *p)
01337 {
01338    ZT_CONFINFO zi;
01339    memset(&zi, 0, sizeof(zi));
01340    p->confno = -1;
01341    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01342    if (p->subs[SUB_REAL].zfd > -1) {
01343       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01344          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01345    }
01346    return 0;
01347 }
01348 
01349 static int update_conf(struct zt_pvt *p)
01350 {
01351    int needconf = 0;
01352    int x;
01353    int useslavenative;
01354    struct zt_pvt *slave = NULL;
01355 
01356    useslavenative = isslavenative(p, &slave);
01357    /* Start with the obvious, general stuff */
01358    for (x = 0; x < 3; x++) {
01359       /* Look for three way calls */
01360       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01361          conf_add(p, &p->subs[x], x, 0);
01362          needconf++;
01363       } else {
01364          conf_del(p, &p->subs[x], x);
01365       }
01366    }
01367    /* If we have a slave, add him to our conference now. or DAX
01368       if this is slave native */
01369    for (x = 0; x < MAX_SLAVES; x++) {
01370       if (p->slaves[x]) {
01371          if (useslavenative)
01372             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01373          else {
01374             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01375             needconf++;
01376          }
01377       }
01378    }
01379    /* If we're supposed to be in there, do so now */
01380    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01381       if (useslavenative)
01382          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01383       else {
01384          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01385          needconf++;
01386       }
01387    }
01388    /* If we have a master, add ourselves to his conference */
01389    if (p->master) {
01390       if (isslavenative(p->master, NULL)) {
01391          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01392       } else {
01393          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01394       }
01395    }
01396    if (!needconf) {
01397       /* Nobody is left (or should be left) in our conference.
01398          Kill it. */
01399       p->confno = -1;
01400    }
01401    if (option_debug)
01402       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01403    return 0;
01404 }
01405 
01406 static void zt_enable_ec(struct zt_pvt *p)
01407 {
01408    int x;
01409    int res;
01410    if (!p)
01411       return;
01412    if (p->echocanon) {
01413       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01414       return;
01415    }
01416    if (p->digital) {
01417       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01418       return;
01419    }
01420    if (p->echocancel) {
01421       if (p->sig == SIG_PRI) {
01422          x = 1;
01423          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01424          if (res)
01425             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01426       }
01427       x = p->echocancel;
01428       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01429       if (res) 
01430          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01431       else {
01432          p->echocanon = 1;
01433          if (option_debug)
01434             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01435       }
01436    } else if (option_debug)
01437       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01438 }
01439 
01440 static void zt_train_ec(struct zt_pvt *p)
01441 {
01442    int x;
01443    int res;
01444    if (p && p->echocancel && p->echotraining) {
01445       x = p->echotraining;
01446       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01447       if (res)
01448          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01449       else {
01450          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01451       }
01452    } else
01453       ast_log(LOG_DEBUG, "No echo training requested\n");
01454 }
01455 
01456 static void zt_disable_ec(struct zt_pvt *p)
01457 {
01458    int x;
01459    int res;
01460    if (p->echocancel) {
01461       x = 0;
01462       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01463       if (res)
01464          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01465       else if (option_debug)
01466          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01467    }
01468    p->echocanon = 0;
01469 }
01470 
01471 static void fill_txgain(struct zt_gains *g, float gain, int law)
01472 {
01473    int j;
01474    int k;
01475    float linear_gain = pow(10.0, gain / 20.0);
01476 
01477    switch (law) {
01478    case ZT_LAW_ALAW:
01479       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01480          if (gain) {
01481             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01482             if (k > 32767) k = 32767;
01483             if (k < -32767) k = -32767;
01484             g->txgain[j] = AST_LIN2A(k);
01485          } else {
01486             g->txgain[j] = j;
01487          }
01488       }
01489       break;
01490    case ZT_LAW_MULAW:
01491       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01492          if (gain) {
01493             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01494             if (k > 32767) k = 32767;
01495             if (k < -32767) k = -32767;
01496             g->txgain[j] = AST_LIN2MU(k);
01497          } else {
01498             g->txgain[j] = j;
01499          }
01500       }
01501       break;
01502    }
01503 }
01504 
01505 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01506 {
01507    int j;
01508    int k;
01509    float linear_gain = pow(10.0, gain / 20.0);
01510 
01511    switch (law) {
01512    case ZT_LAW_ALAW:
01513       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01514          if (gain) {
01515             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01516             if (k > 32767) k = 32767;
01517             if (k < -32767) k = -32767;
01518             g->rxgain[j] = AST_LIN2A(k);
01519          } else {
01520             g->rxgain[j] = j;
01521          }
01522       }
01523       break;
01524    case ZT_LAW_MULAW:
01525       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01526          if (gain) {
01527             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01528             if (k > 32767) k = 32767;
01529             if (k < -32767) k = -32767;
01530             g->rxgain[j] = AST_LIN2MU(k);
01531          } else {
01532             g->rxgain[j] = j;
01533          }
01534       }
01535       break;
01536    }
01537 }
01538 
01539 static int set_actual_txgain(int fd, int chan, float gain, int law)
01540 {
01541    struct zt_gains g;
01542    int res;
01543 
01544    memset(&g, 0, sizeof(g));
01545    g.chan = chan;
01546    res = ioctl(fd, ZT_GETGAINS, &g);
01547    if (res) {
01548       if (option_debug)
01549          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01550       return res;
01551    }
01552 
01553    fill_txgain(&g, gain, law);
01554 
01555    return ioctl(fd, ZT_SETGAINS, &g);
01556 }
01557 
01558 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01559 {
01560    struct zt_gains g;
01561    int res;
01562 
01563    memset(&g, 0, sizeof(g));
01564    g.chan = chan;
01565    res = ioctl(fd, ZT_GETGAINS, &g);
01566    if (res) {
01567       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01568       return res;
01569    }
01570 
01571    fill_rxgain(&g, gain, law);
01572 
01573    return ioctl(fd, ZT_SETGAINS, &g);
01574 }
01575 
01576 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01577 {
01578    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01579 }
01580 
01581 static int bump_gains(struct zt_pvt *p)
01582 {
01583    int res;
01584 
01585    /* Bump receive gain by 5.0db */
01586    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01587    if (res) {
01588       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01589       return -1;
01590    }
01591 
01592    return 0;
01593 }
01594 
01595 static int restore_gains(struct zt_pvt *p)
01596 {
01597    int res;
01598 
01599    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01600    if (res) {
01601       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01602       return -1;
01603    }
01604 
01605    return 0;
01606 }
01607 
01608 static inline int zt_set_hook(int fd, int hs)
01609 {
01610    int x, res;
01611 
01612    x = hs;
01613    res = ioctl(fd, ZT_HOOK, &x);
01614 
01615    if (res < 0) {
01616       if (errno == EINPROGRESS)
01617          return 0;
01618       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01619    }
01620 
01621    return res;
01622 }
01623 
01624 static inline int zt_confmute(struct zt_pvt *p, int muted)
01625 {
01626    int x, y, res;
01627    x = muted;
01628    if (p->sig == SIG_PRI) {
01629       y = 1;
01630       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01631       if (res)
01632          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01633    }
01634    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01635    if (res < 0)
01636       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01637    return res;
01638 }
01639 
01640 static int save_conference(struct zt_pvt *p)
01641 {
01642    struct zt_confinfo c;
01643    int res;
01644    if (p->saveconf.confmode) {
01645       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01646       return -1;
01647    }
01648    p->saveconf.chan = 0;
01649    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01650    if (res) {
01651       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01652       p->saveconf.confmode = 0;
01653       return -1;
01654    }
01655    c.chan = 0;
01656    c.confno = 0;
01657    c.confmode = ZT_CONF_NORMAL;
01658    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01659    if (res) {
01660       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01661       return -1;
01662    }
01663    if (option_debug)
01664       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01665    return 0;
01666 }
01667 
01668 static int restore_conference(struct zt_pvt *p)
01669 {
01670    int res;
01671    if (p->saveconf.confmode) {
01672       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01673       p->saveconf.confmode = 0;
01674       if (res) {
01675          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01676          return -1;
01677       }
01678    }
01679    if (option_debug)
01680       ast_log(LOG_DEBUG, "Restored conferencing\n");
01681    return 0;
01682 }
01683 
01684 static int send_callerid(struct zt_pvt *p);
01685 
01686 static int send_cwcidspill(struct zt_pvt *p)
01687 {
01688    p->callwaitcas = 0;
01689    p->cidcwexpire = 0;
01690    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01691       return -1;
01692    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01693    /* Make sure we account for the end */
01694    p->cidlen += READ_SIZE * 4;
01695    p->cidpos = 0;
01696    send_callerid(p);
01697    if (option_verbose > 2)
01698       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01699    return 0;
01700 }
01701 
01702 static int has_voicemail(struct zt_pvt *p)
01703 {
01704 
01705    return ast_app_has_voicemail(p->mailbox, NULL);
01706 }
01707 
01708 static int send_callerid(struct zt_pvt *p)
01709 {
01710    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01711    int res;
01712    /* Take out of linear mode if necessary */
01713    if (p->subs[SUB_REAL].linear) {
01714       p->subs[SUB_REAL].linear = 0;
01715       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01716    }
01717    while (p->cidpos < p->cidlen) {
01718       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01719       if (res < 0) {
01720          if (errno == EAGAIN)
01721             return 0;
01722          else {
01723             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01724             return -1;
01725          }
01726       }
01727       if (!res)
01728          return 0;
01729       p->cidpos += res;
01730    }
01731    free(p->cidspill);
01732    p->cidspill = NULL;
01733    if (p->callwaitcas) {
01734       /* Wait for CID/CW to expire */
01735       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01736    } else
01737       restore_conference(p);
01738    return 0;
01739 }
01740 
01741 static int zt_callwait(struct ast_channel *ast)
01742 {
01743    struct zt_pvt *p = ast->tech_pvt;
01744    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01745    if (p->cidspill) {
01746       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01747       free(p->cidspill);
01748    }
01749    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01750       return -1;
01751    save_conference(p);
01752    /* Silence */
01753    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01754    if (!p->callwaitrings && p->callwaitingcallerid) {
01755       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01756       p->callwaitcas = 1;
01757       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01758    } else {
01759       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01760       p->callwaitcas = 0;
01761       p->cidlen = 2400 + READ_SIZE * 4;
01762    }
01763    p->cidpos = 0;
01764    send_callerid(p);
01765    
01766    return 0;
01767 }
01768 
01769 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01770 {
01771    struct zt_pvt *p = ast->tech_pvt;
01772    int x, res, index,mysig;
01773    char *c, *n, *l;
01774 #ifdef HAVE_PRI
01775    char *s = NULL;
01776 #endif
01777    char dest[256]; /* must be same length as p->dialdest */
01778    ast_mutex_lock(&p->lock);
01779    ast_copy_string(dest, rdest, sizeof(dest));
01780    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01781    if ((ast->_state == AST_STATE_BUSY)) {
01782       p->subs[SUB_REAL].needbusy = 1;
01783       ast_mutex_unlock(&p->lock);
01784       return 0;
01785    }
01786    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01787       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01788       ast_mutex_unlock(&p->lock);
01789       return -1;
01790    }
01791    p->dialednone = 0;
01792    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01793    {
01794       /* Special pseudo -- automatically up */
01795       ast_setstate(ast, AST_STATE_UP); 
01796       ast_mutex_unlock(&p->lock);
01797       return 0;
01798    }
01799    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01800    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01801    if (res)
01802       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01803    p->outgoing = 1;
01804 
01805    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01806 
01807    mysig = p->sig;
01808    if (p->outsigmod > -1)
01809       mysig = p->outsigmod;
01810 
01811    switch (mysig) {
01812    case SIG_FXOLS:
01813    case SIG_FXOGS:
01814    case SIG_FXOKS:
01815       if (p->owner == ast) {
01816          /* Normal ring, on hook */
01817          
01818          /* Don't send audio while on hook, until the call is answered */
01819          p->dialing = 1;
01820          if (p->use_callerid) {
01821             /* Generate the Caller-ID spill if desired */
01822             if (p->cidspill) {
01823                ast_log(LOG_WARNING, "cidspill already exists??\n");
01824                free(p->cidspill);
01825             }
01826             p->callwaitcas = 0;
01827             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01828                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01829                p->cidpos = 0;
01830                send_callerid(p);
01831             }
01832          }
01833          /* Choose proper cadence */
01834          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01835             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01836                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01837             p->cidrings = cidrings[p->distinctivering - 1];
01838          } else {
01839             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01840                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01841             p->cidrings = p->sendcalleridafter;
01842          }
01843 
01844          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01845          c = strchr(dest, '/');
01846          if (c)
01847             c++;
01848          if (c && (strlen(c) < p->stripmsd)) {
01849             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01850             c = NULL;
01851          }
01852          if (c) {
01853             p->dop.op = ZT_DIAL_OP_REPLACE;
01854             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01855             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01856          } else {
01857             p->dop.dialstr[0] = '\0';
01858          }
01859          x = ZT_RING;
01860          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01861             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01862             ast_mutex_unlock(&p->lock);
01863             return -1;
01864          }
01865          p->dialing = 1;
01866       } else {
01867          /* Call waiting call */
01868          p->callwaitrings = 0;
01869          if (ast->cid.cid_num)
01870             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01871          else
01872             p->callwait_num[0] = '\0';
01873          if (ast->cid.cid_name)
01874             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01875          else
01876             p->callwait_name[0] = '\0';
01877          /* Call waiting tone instead */
01878          if (zt_callwait(ast)) {
01879             ast_mutex_unlock(&p->lock);
01880             return -1;
01881          }
01882          /* Make ring-back */
01883          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01884             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01885             
01886       }
01887       n = ast->cid.cid_name;
01888       l = ast->cid.cid_num;
01889       if (l)
01890          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01891       else
01892          p->lastcid_num[0] = '\0';
01893       if (n)
01894          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01895       else
01896          p->lastcid_name[0] = '\0';
01897       ast_setstate(ast, AST_STATE_RINGING);
01898       index = zt_get_index(ast, p, 0);
01899       if (index > -1) {
01900          p->subs[index].needringing = 1;
01901       }
01902       break;
01903    case SIG_FXSLS:
01904    case SIG_FXSGS:
01905    case SIG_FXSKS:
01906    case SIG_EMWINK:
01907    case SIG_EM:
01908    case SIG_EM_E1:
01909    case SIG_FEATD:
01910    case SIG_FEATDMF:
01911    case SIG_E911:
01912    case SIG_FGC_CAMA:
01913    case SIG_FGC_CAMAMF:
01914    case SIG_FEATB:
01915    case SIG_SFWINK:
01916    case SIG_SF:
01917    case SIG_SF_FEATD:
01918    case SIG_SF_FEATDMF:
01919    case SIG_FEATDMF_TA:
01920    case SIG_SF_FEATB:
01921       c = strchr(dest, '/');
01922       if (c)
01923          c++;
01924       else
01925          c = "";
01926       if (strlen(c) < p->stripmsd) {
01927          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01928          ast_mutex_unlock(&p->lock);
01929          return -1;
01930       }
01931 #ifdef HAVE_PRI
01932       /* Start the trunk, if not GR-303 */
01933       if (!p->pri) {
01934 #endif
01935          x = ZT_START;
01936          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01937          if (res < 0) {
01938             if (errno != EINPROGRESS) {
01939                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01940                ast_mutex_unlock(&p->lock);
01941                return -1;
01942             }
01943          }
01944 #ifdef HAVE_PRI
01945       }
01946 #endif
01947       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01948       p->dop.op = ZT_DIAL_OP_REPLACE;
01949 
01950       c += p->stripmsd;
01951 
01952       switch (mysig) {
01953       case SIG_FEATD:
01954          l = ast->cid.cid_num;
01955          if (l) 
01956             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01957          else
01958             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01959          break;
01960       case SIG_FEATDMF:
01961          l = ast->cid.cid_num;
01962          if (l) 
01963             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01964          else
01965             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01966          break;
01967       case SIG_FEATDMF_TA:
01968       {
01969          const char *cic, *ozz;
01970 
01971          /* If you have to go through a Tandem Access point you need to use this */
01972          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01973          if (!ozz)
01974             ozz = defaultozz;
01975          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01976          if (!cic)
01977             cic = defaultcic;
01978          if (!ozz || !cic) {
01979             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01980             ast_mutex_unlock(&p->lock);
01981             return -1;
01982          }
01983          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01984          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01985          p->whichwink = 0;
01986       }
01987          break;
01988       case SIG_E911:
01989          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01990          break;
01991       case SIG_FGC_CAMA:
01992          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
01993          break;
01994       case SIG_FGC_CAMAMF:
01995       case SIG_FEATB:
01996          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01997          break;
01998       default:
01999          if (p->pulse)
02000             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02001          else
02002             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02003          break;
02004       }
02005 
02006       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02007          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02008          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02009          p->echorest[sizeof(p->echorest) - 1] = '\0';
02010          p->echobreak = 1;
02011          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02012       } else
02013          p->echobreak = 0;
02014       if (!res) {
02015          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02016             x = ZT_ONHOOK;
02017             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02018             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02019             ast_mutex_unlock(&p->lock);
02020             return -1;
02021          }
02022       } else
02023          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02024       p->dialing = 1;
02025       if (ast_strlen_zero(c))
02026          p->dialednone = 1;
02027       ast_setstate(ast, AST_STATE_DIALING);
02028       break;
02029    case 0:
02030       /* Special pseudo -- automatically up*/
02031       ast_setstate(ast, AST_STATE_UP);
02032       break;      
02033    case SIG_PRI:
02034       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02035       p->dialdest[0] = '\0';
02036       break;
02037    default:
02038       ast_log(LOG_DEBUG, "not yet implemented\n");
02039       ast_mutex_unlock(&p->lock);
02040       return -1;
02041    }
02042 #ifdef HAVE_PRI
02043    if (p->pri) {
02044       struct pri_sr *sr;
02045 #ifdef SUPPORT_USERUSER
02046       const char *useruser;
02047 #endif
02048       int pridialplan;
02049       int dp_strip;
02050       int prilocaldialplan;
02051       int ldp_strip;
02052       int exclusive;
02053       const char *rr_str;
02054       int redirect_reason;
02055 
02056       c = strchr(dest, '/');
02057       if (c)
02058          c++;
02059       else
02060          c = dest;
02061       if (!p->hidecalleridname)
02062          n = ast->cid.cid_name;
02063       else
02064          n = NULL;
02065       if (!p->hidecallerid) {
02066          l = ast->cid.cid_num;
02067          n = ast->cid.cid_name;
02068       } else {
02069          l = NULL;
02070          n = NULL;
02071       }
02072       if (strlen(c) < p->stripmsd) {
02073          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02074          ast_mutex_unlock(&p->lock);
02075          return -1;
02076       }
02077       if (mysig != SIG_FXSKS) {
02078          p->dop.op = ZT_DIAL_OP_REPLACE;
02079          s = strchr(c + p->stripmsd, 'w');
02080          if (s) {
02081             if (strlen(s) > 1)
02082                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02083             else
02084                p->dop.dialstr[0] = '\0';
02085             *s = '\0';
02086          } else {
02087             p->dop.dialstr[0] = '\0';
02088          }
02089       }
02090       if (pri_grab(p, p->pri)) {
02091          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02092          ast_mutex_unlock(&p->lock);
02093          return -1;
02094       }
02095       if (!(p->call = pri_new_call(p->pri->pri))) {
02096          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02097          pri_rel(p->pri);
02098          ast_mutex_unlock(&p->lock);
02099          return -1;
02100       }
02101       if (!(sr = pri_sr_new())) {
02102          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02103          pri_rel(p->pri);
02104          ast_mutex_unlock(&p->lock);
02105       }
02106       if (p->bearer || (mysig == SIG_FXSKS)) {
02107          if (p->bearer) {
02108             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);
02109             p->bearer->call = p->call;
02110          } else
02111             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02112          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02113       }
02114       p->digital = IS_DIGITAL(ast->transfercapability);
02115       /* Add support for exclusive override */
02116       if (p->priexclusive)
02117          exclusive = 1;
02118       else {
02119       /* otherwise, traditional behavior */
02120          if (p->pri->nodetype == PRI_NETWORK)
02121             exclusive = 0;
02122          else
02123             exclusive = 1;
02124       }
02125       
02126       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02127       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02128                (p->digital ? -1 : 
02129                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02130       if (p->pri->facilityenable)
02131          pri_facility_enable(p->pri->pri);
02132 
02133       if (option_verbose > 2)
02134          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02135       dp_strip = 0;
02136       pridialplan = p->pri->dialplan - 1;
02137       if (pridialplan == -2) { /* compute dynamically */
02138          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02139             dp_strip = strlen(p->pri->internationalprefix);
02140             pridialplan = PRI_INTERNATIONAL_ISDN;
02141          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02142             dp_strip = strlen(p->pri->nationalprefix);
02143             pridialplan = PRI_NATIONAL_ISDN;
02144          } else {
02145             pridialplan = PRI_LOCAL_ISDN;
02146          }
02147       }
02148       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02149 
02150       ldp_strip = 0;
02151       prilocaldialplan = p->pri->localdialplan - 1;
02152       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02153          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02154             ldp_strip = strlen(p->pri->internationalprefix);
02155             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02156          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02157             ldp_strip = strlen(p->pri->nationalprefix);
02158             prilocaldialplan = PRI_NATIONAL_ISDN;
02159          } else {
02160             prilocaldialplan = PRI_LOCAL_ISDN;
02161          }
02162       }
02163       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02164          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02165       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02166          if (!strcasecmp(rr_str, "UNKNOWN"))
02167             redirect_reason = 0;
02168          else if (!strcasecmp(rr_str, "BUSY"))
02169             redirect_reason = 1;
02170          else if (!strcasecmp(rr_str, "NO_REPLY"))
02171             redirect_reason = 2;
02172          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02173             redirect_reason = 15;
02174          else
02175             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02176       } else
02177          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02178       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02179 
02180 #ifdef SUPPORT_USERUSER
02181       /* User-user info */
02182       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02183 
02184       if (useruser)
02185          pri_sr_set_useruser(sr, useruser);
02186 #endif
02187 
02188       if (pri_setup(p->pri->pri, p->call, sr)) {
02189          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02190             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02191          pri_rel(p->pri);
02192          ast_mutex_unlock(&p->lock);
02193          pri_sr_free(sr);
02194          return -1;
02195       }
02196       pri_sr_free(sr);
02197       ast_setstate(ast, AST_STATE_DIALING);
02198       pri_rel(p->pri);
02199    }
02200 #endif      
02201    ast_mutex_unlock(&p->lock);
02202    return 0;
02203 }
02204 
02205 static void destroy_zt_pvt(struct zt_pvt **pvt)
02206 {
02207    struct zt_pvt *p = *pvt;
02208    /* Remove channel from the list */
02209    if (p->prev)
02210       p->prev->next = p->next;
02211    if (p->next)
02212       p->next->prev = p->prev;
02213    if (p->use_smdi)
02214       ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
02215    ast_mutex_destroy(&p->lock);
02216    free(p);
02217    *pvt = NULL;
02218 }
02219 
02220 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02221 {
02222    int owned = 0;
02223    int i = 0;
02224 
02225    if (!now) {
02226       if (cur->owner) {
02227          owned = 1;
02228       }
02229 
02230       for (i = 0; i < 3; i++) {
02231          if (cur->subs[i].owner) {
02232             owned = 1;
02233          }
02234       }
02235       if (!owned) {
02236          if (prev) {
02237             prev->next = cur->next;
02238             if (prev->next)
02239                prev->next->prev = prev;
02240             else
02241                ifend = prev;
02242          } else {
02243             iflist = cur->next;
02244             if (iflist)
02245                iflist->prev = NULL;
02246             else
02247                ifend = NULL;
02248          }
02249          if (cur->subs[SUB_REAL].zfd > -1) {
02250             zt_close(cur->subs[SUB_REAL].zfd);
02251          }
02252          destroy_zt_pvt(&cur);
02253       }
02254    } else {
02255       if (prev) {
02256          prev->next = cur->next;
02257          if (prev->next)
02258             prev->next->prev = prev;
02259          else
02260             ifend = prev;
02261       } else {
02262          iflist = cur->next;
02263          if (iflist)
02264             iflist->prev = NULL;
02265          else
02266             ifend = NULL;
02267       }
02268       if (cur->subs[SUB_REAL].zfd > -1) {
02269          zt_close(cur->subs[SUB_REAL].zfd);
02270       }
02271       destroy_zt_pvt(&cur);
02272    }
02273    return 0;
02274 }
02275 
02276 #ifdef HAVE_PRI
02277 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02278 
02279 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02280 
02281 static char *zap_send_keypad_facility_descrip = 
02282 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02283 "  IE over the current channel.\n";
02284 
02285 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02286 {
02287    /* Data will be our digit string */
02288    struct zt_pvt *p;
02289    char *digits = (char *) data;
02290 
02291    if (ast_strlen_zero(digits)) {
02292       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02293       return -1;
02294    }
02295 
02296    p = (struct zt_pvt *)chan->tech_pvt;
02297 
02298    if (!p) {
02299       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02300       return -1;
02301    }
02302 
02303    ast_mutex_lock(&p->lock);
02304 
02305    if (!p->pri || !p->call) {
02306       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02307       ast_mutex_unlock(&p->lock);
02308       return -1;
02309    }
02310 
02311    if (!pri_grab(p, p->pri)) {
02312       pri_keypad_facility(p->pri->pri, p->call, digits);
02313       pri_rel(p->pri);
02314    } else {
02315       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02316       ast_mutex_unlock(&p->lock);
02317       return -1;
02318    }
02319 
02320    ast_mutex_unlock(&p->lock);
02321 
02322    return 0;
02323 }
02324 
02325 static int pri_is_up(struct zt_pri *pri)
02326 {
02327    int x;
02328    for (x = 0; x < NUM_DCHANS; x++) {
02329       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02330          return 1;
02331    }
02332    return 0;
02333 }
02334 
02335 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02336 {
02337    bearer->owner = &inuse;
02338    bearer->realcall = crv;
02339    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02340    if (crv->subs[SUB_REAL].owner)
02341       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02342    crv->bearer = bearer;
02343    crv->call = bearer->call;
02344    crv->pri = pri;
02345    return 0;
02346 }
02347 
02348 static char *pri_order(int level)
02349 {
02350    switch (level) {
02351    case 0:
02352       return "Primary";
02353    case 1:
02354       return "Secondary";
02355    case 2:
02356       return "Tertiary";
02357    case 3:
02358       return "Quaternary";
02359    default:
02360       return "<Unknown>";
02361    }     
02362 }
02363 
02364 /* Returns fd of the active dchan */
02365 static int pri_active_dchan_fd(struct zt_pri *pri)
02366 {
02367    int x = -1;
02368 
02369    for (x = 0; x < NUM_DCHANS; x++) {
02370       if ((pri->dchans[x] == pri->pri))
02371          break;
02372    }
02373 
02374    return pri->fds[x];
02375 }
02376 
02377 static int pri_find_dchan(struct zt_pri *pri)
02378 {
02379    int oldslot = -1;
02380    struct pri *old;
02381    int newslot = -1;
02382    int x;
02383    old = pri->pri;
02384    for (x = 0; x < NUM_DCHANS; x++) {
02385       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02386          newslot = x;
02387       if (pri->dchans[x] == old) {
02388          oldslot = x;
02389       }
02390    }
02391    if (newslot < 0) {
02392       newslot = 0;
02393       ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02394          pri->dchannels[newslot]);
02395    }
02396    if (old && (oldslot != newslot))
02397       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02398          pri->dchannels[oldslot], pri->dchannels[newslot]);
02399    pri->pri = pri->dchans[newslot];
02400    return 0;
02401 }
02402 #endif
02403 
02404 static int zt_hangup(struct ast_channel *ast)
02405 {
02406    int res;
02407    int index,x, law;
02408    /*static int restore_gains(struct zt_pvt *p);*/
02409    struct zt_pvt *p = ast->tech_pvt;
02410    struct zt_pvt *tmp = NULL;
02411    struct zt_pvt *prev = NULL;
02412    ZT_PARAMS par;
02413 
02414    if (option_debug)
02415       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02416    if (!ast->tech_pvt) {
02417       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02418       return 0;
02419    }
02420    
02421    ast_mutex_lock(&p->lock);
02422    
02423    index = zt_get_index(ast, p, 1);
02424 
02425    if (p->sig == SIG_PRI) {
02426       x = 1;
02427       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02428    }
02429 
02430    x = 0;
02431    zt_confmute(p, 0);
02432    restore_gains(p);
02433    if (p->origcid_num) {
02434       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02435       free(p->origcid_num);
02436       p->origcid_num = NULL;
02437    }  
02438    if (p->origcid_name) {
02439       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02440       free(p->origcid_name);
02441       p->origcid_name = NULL;
02442    }  
02443    if (p->dsp)
02444       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02445    if (p->exten)
02446       p->exten[0] = '\0';
02447 
02448    if (option_debug)
02449       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02450       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02451    p->ignoredtmf = 0;
02452    
02453    if (index > -1) {
02454       /* Real channel, do some fixup */
02455       p->subs[index].owner = NULL;
02456       p->subs[index].needanswer = 0;
02457       p->subs[index].needflash = 0;
02458       p->subs[index].needringing = 0;
02459       p->subs[index].needbusy = 0;
02460       p->subs[index].needcongestion = 0;
02461       p->subs[index].linear = 0;
02462       p->subs[index].needcallerid = 0;
02463       p->polarity = POLARITY_IDLE;
02464       zt_setlinear(p->subs[index].zfd, 0);
02465       if (index == SUB_REAL) {
02466          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02467             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02468             if (p->subs[SUB_CALLWAIT].inthreeway) {
02469                /* We had flipped over to answer a callwait and now it's gone */
02470                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02471                /* Move to the call-wait, but un-own us until they flip back. */
02472                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02473                unalloc_sub(p, SUB_CALLWAIT);
02474                p->owner = NULL;
02475             } else {
02476                /* The three way hung up, but we still have a call wait */
02477                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02478                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02479                unalloc_sub(p, SUB_THREEWAY);
02480                if (p->subs[SUB_REAL].inthreeway) {
02481                   /* This was part of a three way call.  Immediately make way for
02482                      another call */
02483                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02484                   p->owner = p->subs[SUB_REAL].owner;
02485                } else {
02486                   /* This call hasn't been completed yet...  Set owner to NULL */
02487                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02488                   p->owner = NULL;
02489                }
02490                p->subs[SUB_REAL].inthreeway = 0;
02491             }
02492          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02493             /* Move to the call-wait and switch back to them. */
02494             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02495             unalloc_sub(p, SUB_CALLWAIT);
02496             p->owner = p->subs[SUB_REAL].owner;
02497             if (p->owner->_state != AST_STATE_UP)
02498                p->subs[SUB_REAL].needanswer = 1;
02499             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02500                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02501          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02502             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02503             unalloc_sub(p, SUB_THREEWAY);
02504             if (p->subs[SUB_REAL].inthreeway) {
02505                /* This was part of a three way call.  Immediately make way for
02506                   another call */
02507                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02508                p->owner = p->subs[SUB_REAL].owner;
02509             } else {
02510                /* This call hasn't been completed yet...  Set owner to NULL */
02511                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02512                p->owner = NULL;
02513             }
02514             p->subs[SUB_REAL].inthreeway = 0;
02515          }
02516       } else if (index == SUB_CALLWAIT) {
02517          /* Ditch the holding callwait call, and immediately make it availabe */
02518          if (p->subs[SUB_CALLWAIT].inthreeway) {
02519             /* This is actually part of a three way, placed on hold.  Place the third part
02520                on music on hold now */
02521             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02522                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02523                   S_OR(p->mohsuggest, NULL),
02524                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02525             }
02526             p->subs[SUB_THREEWAY].inthreeway = 0;
02527             /* Make it the call wait now */
02528             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02529             unalloc_sub(p, SUB_THREEWAY);
02530          } else
02531             unalloc_sub(p, SUB_CALLWAIT);
02532       } else if (index == SUB_THREEWAY) {
02533          if (p->subs[SUB_CALLWAIT].inthreeway) {
02534             /* The other party of the three way call is currently in a call-wait state.
02535                Start music on hold for them, and take the main guy out of the third call */
02536             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02537                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02538                   S_OR(p->mohsuggest, NULL),
02539                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02540             }
02541             p->subs[SUB_CALLWAIT].inthreeway = 0;
02542          }
02543          p->subs[SUB_REAL].inthreeway = 0;
02544          /* If this was part of a three way call index, let us make
02545             another three way call */
02546          unalloc_sub(p, SUB_THREEWAY);
02547       } else {
02548          /* This wasn't any sort of call, but how are we an index? */
02549          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02550       }
02551    }
02552 
02553    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02554       p->owner = NULL;
02555       p->ringt = 0;
02556       p->distinctivering = 0;
02557       p->confirmanswer = 0;
02558       p->cidrings = 1;
02559       p->outgoing = 0;
02560       p->digital = 0;
02561       p->faxhandled = 0;
02562       p->pulsedial = 0;
02563       p->onhooktime = time(NULL);
02564 #ifdef HAVE_PRI
02565       p->proceeding = 0;
02566       p->progress = 0;
02567       p->alerting = 0;
02568       p->setup_ack = 0;
02569 #endif      
02570       if (p->dsp) {
02571          ast_dsp_free(p->dsp);
02572          p->dsp = NULL;
02573       }
02574 
02575       law = ZT_LAW_DEFAULT;
02576       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02577       if (res < 0) 
02578          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02579       /* Perform low level hangup if no owner left */
02580 #ifdef HAVE_PRI
02581       if (p->pri) {
02582 #ifdef SUPPORT_USERUSER
02583          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02584 #endif
02585 
02586          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02587          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02588             if (!pri_grab(p, p->pri)) {
02589                if (p->alreadyhungup) {
02590                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02591 
02592 #ifdef SUPPORT_USERUSER
02593                   pri_call_set_useruser(p->call, useruser);
02594 #endif
02595 
02596                   pri_hangup(p->pri->pri, p->call, -1);
02597                   p->call = NULL;
02598                   if (p->bearer) 
02599                      p->bearer->call = NULL;
02600                } else {
02601                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02602                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02603                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02604 
02605 #ifdef SUPPORT_USERUSER
02606                   pri_call_set_useruser(p->call, useruser);
02607 #endif
02608 
02609                   p->alreadyhungup = 1;
02610                   if (p->bearer)
02611                      p->bearer->alreadyhungup = 1;
02612                   if (cause) {
02613                      if (atoi(cause))
02614                         icause = atoi(cause);
02615                   }
02616                   pri_hangup(p->pri->pri, p->call, icause);
02617                }
02618                if (res < 0) 
02619                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02620                pri_rel(p->pri);        
02621             } else {
02622                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02623                res = -1;
02624             }
02625          } else {
02626             if (p->bearer)
02627                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02628             p->call = NULL;
02629             res = 0;
02630          }
02631       }
02632 #endif
02633       if (p->sig && (p->sig != SIG_PRI))
02634          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02635       if (res < 0) {
02636          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02637       }
02638       switch (p->sig) {
02639       case SIG_FXOGS:
02640       case SIG_FXOLS:
02641       case SIG_FXOKS:
02642          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02643          if (!res) {
02644 #if 0
02645             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02646 #endif
02647             /* If they're off hook, try playing congestion */
02648             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02649                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02650             else
02651                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02652          }
02653          break;
02654       case SIG_FXSGS:
02655       case SIG_FXSLS:
02656       case SIG_FXSKS:
02657          /* Make sure we're not made available for at least two seconds assuming
02658             we were actually used for an inbound or outbound call. */
02659          if (ast->_state != AST_STATE_RESERVED) {
02660             time(&p->guardtime);
02661             p->guardtime += 2;
02662          }
02663          break;
02664       default:
02665          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02666       }
02667       if (p->cidspill)
02668          free(p->cidspill);
02669       if (p->sig)
02670          zt_disable_ec(p);
02671       x = 0;
02672       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02673       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02674       p->didtdd = 0;
02675       p->cidspill = NULL;
02676       p->callwaitcas = 0;
02677       p->callwaiting = p->permcallwaiting;
02678       p->hidecallerid = p->permhidecallerid;
02679       p->dialing = 0;
02680       p->rdnis[0] = '\0';
02681       update_conf(p);
02682       reset_conf(p);
02683       /* Restore data mode */
02684       if (p->sig == SIG_PRI) {
02685          x = 0;
02686          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02687       }
02688 #ifdef HAVE_PRI
02689       if (p->bearer) {
02690          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02691          /* Free up the bearer channel as well, and
02692             don't use its file descriptor anymore */
02693          update_conf(p->bearer);
02694          reset_conf(p->bearer);
02695          p->bearer->owner = NULL;
02696          p->bearer->realcall = NULL;
02697          p->bearer = NULL;
02698          p->subs[SUB_REAL].zfd = -1;
02699          p->pri = NULL;
02700       }
02701 #endif
02702       restart_monitor();
02703    }
02704 
02705    p->callwaitingrepeat = 0;
02706    p->cidcwexpire = 0;
02707    p->oprmode = 0;
02708    ast->tech_pvt = NULL;
02709    ast_mutex_unlock(&p->lock);
02710    ast_module_unref(ast_module_info->self);
02711    if (option_verbose > 2) 
02712       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02713 
02714    ast_mutex_lock(&iflock);
02715    tmp = iflist;
02716    prev = NULL;
02717    if (p->destroy) {
02718       while (tmp) {
02719          if (tmp == p) {
02720             destroy_channel(prev, tmp, 0);
02721             break;
02722          } else {
02723             prev = tmp;
02724             tmp = tmp->next;
02725          }
02726       }
02727    }
02728    ast_mutex_unlock(&iflock);
02729    return 0;
02730 }
02731 
02732 static int zt_answer(struct ast_channel *ast)
02733 {
02734    struct zt_pvt *p = ast->tech_pvt;
02735    int res = 0;
02736    int index;
02737    int oldstate = ast->_state;
02738    ast_setstate(ast, AST_STATE_UP);
02739    ast_mutex_lock(&p->lock);
02740    index = zt_get_index(ast, p, 0);
02741    if (index < 0)
02742       index = SUB_REAL;
02743    /* nothing to do if a radio channel */
02744    if ((p->radio || (p->oprmode < 0))) {
02745       ast_mutex_unlock(&p->lock);
02746       return 0;
02747    }
02748    switch (p->sig) {
02749    case SIG_FXSLS:
02750    case SIG_FXSGS:
02751    case SIG_FXSKS:
02752       p->ringt = 0;
02753       /* Fall through */
02754    case SIG_EM:
02755    case SIG_EM_E1:
02756    case SIG_EMWINK:
02757    case SIG_FEATD:
02758    case SIG_FEATDMF:
02759    case SIG_FEATDMF_TA:
02760    case SIG_E911:
02761    case SIG_FGC_CAMA:
02762    case SIG_FGC_CAMAMF:
02763    case SIG_FEATB:
02764    case SIG_SF:
02765    case SIG_SFWINK:
02766    case SIG_SF_FEATD:
02767    case SIG_SF_FEATDMF:
02768    case SIG_SF_FEATB:
02769    case SIG_FXOLS:
02770    case SIG_FXOGS:
02771    case SIG_FXOKS:
02772       /* Pick up the line */
02773       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02774       if (p->hanguponpolarityswitch) {
02775          gettimeofday(&p->polaritydelaytv, NULL);
02776       }
02777       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02778       tone_zone_play_tone(p->subs[index].zfd, -1);
02779       p->dialing = 0;
02780       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02781          if (oldstate == AST_STATE_RINGING) {
02782             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02783             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02784             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02785             p->owner = p->subs[SUB_REAL].owner;
02786          }
02787       }
02788       if (p->sig & __ZT_SIG_FXS) {
02789          zt_enable_ec(p);
02790          zt_train_ec(p);
02791       }
02792       break;
02793 #ifdef HAVE_PRI
02794    case SIG_PRI:
02795       /* Send a pri acknowledge */
02796       if (!pri_grab(p, p->pri)) {
02797          p->proceeding = 1;
02798          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02799          pri_rel(p->pri);
02800       } else {
02801          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02802          res = -1;
02803       }
02804       break;
02805 #endif
02806    case 0:
02807       ast_mutex_unlock(&p->lock);
02808       return 0;
02809    default:
02810       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02811       res = -1;
02812    }
02813    ast_mutex_unlock(&p->lock);
02814    return res;
02815 }
02816 
02817 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02818 {
02819    char *cp;
02820    signed char *scp;
02821    int x;
02822    int index;
02823    struct zt_pvt *p = chan->tech_pvt, *pp;
02824    struct oprmode *oprmode;
02825    
02826 
02827    /* all supported options require data */
02828    if (!data || (datalen < 1)) {
02829       errno = EINVAL;
02830       return -1;
02831    }
02832 
02833    switch (option) {
02834    case AST_OPTION_TXGAIN:
02835       scp = (signed char *) data;
02836       index = zt_get_index(chan, p, 0);
02837       if (index < 0) {
02838          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02839          return -1;
02840       }
02841       if (option_debug)
02842          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02843       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02844    case AST_OPTION_RXGAIN:
02845       scp = (signed char *) data;
02846       index = zt_get_index(chan, p, 0);
02847       if (index < 0) {
02848          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02849          return -1;
02850       }
02851       if (option_debug)
02852          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02853       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02854    case AST_OPTION_TONE_VERIFY:
02855       if (!p->dsp)
02856          break;
02857       cp = (char *) data;
02858       switch (*cp) {
02859       case 1:
02860          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02861          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02862          break;
02863       case 2:
02864          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02865          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02866          break;
02867       default:
02868          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02869          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02870          break;
02871       }
02872       break;
02873    case AST_OPTION_TDD:
02874       /* turn on or off TDD */
02875       cp = (char *) data;
02876       p->mate = 0;
02877       if (!*cp) { /* turn it off */
02878          if (option_debug)
02879             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02880          if (p->tdd)
02881             tdd_free(p->tdd);
02882          p->tdd = 0;
02883          break;
02884       }
02885       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02886          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02887       zt_disable_ec(p);
02888       /* otherwise, turn it on */
02889       if (!p->didtdd) { /* if havent done it yet */
02890          unsigned char mybuf[41000], *buf;
02891          int size, res, fd, len;
02892          struct pollfd fds[1];
02893 
02894          buf = mybuf;
02895          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02896          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02897          len = 40000;
02898          index = zt_get_index(chan, p, 0);
02899          if (index < 0) {
02900             ast_log(LOG_WARNING, "No index in TDD?\n");
02901             return -1;
02902          }
02903          fd = p->subs[index].zfd;
02904          while (len) {
02905             if (ast_check_hangup(chan))
02906                return -1;
02907             size = len;
02908             if (size > READ_SIZE)
02909                size = READ_SIZE;
02910             fds[0].fd = fd;
02911             fds[0].events = POLLPRI | POLLOUT;
02912             fds[0].revents = 0;
02913             res = poll(fds, 1, -1);
02914             if (!res) {
02915                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02916                continue;
02917             }
02918             /* if got exception */
02919             if (fds[0].revents & POLLPRI)
02920                return -1;
02921             if (!(fds[0].revents & POLLOUT)) {
02922                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02923                continue;
02924             }
02925             res = write(fd, buf, size);
02926             if (res != size) {
02927                if (res == -1) return -1;
02928                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02929                break;
02930             }
02931             len -= size;
02932             buf += size;
02933          }
02934          p->didtdd = 1; /* set to have done it now */    
02935       }
02936       if (*cp == 2) { /* Mate mode */
02937          if (p->tdd)
02938             tdd_free(p->tdd);
02939          p->tdd = 0;
02940          p->mate = 1;
02941          break;
02942       }     
02943       if (!p->tdd) { /* if we dont have one yet */
02944          p->tdd = tdd_new(); /* allocate one */
02945       }     
02946       break;
02947    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02948       if (!p->dsp)
02949          break;
02950       cp = (char *) data;
02951       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02952          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02953                 p->dtmfrelax = 0;
02954                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
02955                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
02956       break;
02957    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02958       cp = (char *) data;
02959       if (!*cp) {    
02960          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02961          x = 0;
02962          zt_disable_ec(p);
02963       } else {    
02964          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02965          x = 1;
02966       }
02967       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02968          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02969       break;
02970    case AST_OPTION_OPRMODE:  /* Operator services mode */
02971       oprmode = (struct oprmode *) data;
02972       pp = oprmode->peer->tech_pvt;
02973       p->oprmode = pp->oprmode = 0;
02974       /* setup peers */
02975       p->oprpeer = pp;
02976       pp->oprpeer = p;
02977       /* setup modes, if any */
02978       if (oprmode->mode) 
02979       {
02980          pp->oprmode = oprmode->mode;
02981          p->oprmode = -oprmode->mode;
02982       }
02983       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
02984          oprmode->mode, chan->name,oprmode->peer->name);;
02985       break;
02986    case AST_OPTION_ECHOCAN:
02987       cp = (char *) data;
02988       if (*cp) {
02989          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
02990          zt_enable_ec(p);
02991       } else {
02992          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
02993          zt_disable_ec(p);
02994       }
02995       break;
02996    }
02997    errno = 0;
02998 
02999    return 0;
03000 }
03001 
03002 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03003 {
03004    struct zt_pvt *p = chan->tech_pvt;
03005    
03006    if (!strcasecmp(data, "rxgain")) {
03007       ast_mutex_lock(&p->lock);
03008       snprintf(buf, len, "%f", p->rxgain);
03009       ast_mutex_unlock(&p->lock);   
03010    } else if (!strcasecmp(data, "txgain")) {
03011       ast_mutex_lock(&p->lock);
03012       snprintf(buf, len, "%f", p->txgain);
03013       ast_mutex_unlock(&p->lock);   
03014    } else {
03015       ast_copy_string(buf, "", len);
03016    }
03017    return 0;
03018 }
03019 
03020 
03021 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03022 {
03023    /* Unlink a specific slave or all slaves/masters from a given master */
03024    int x;
03025    int hasslaves;
03026    if (!master)
03027       return;
03028    if (needlock) {
03029       ast_mutex_lock(&master->lock);
03030       if (slave) {
03031          while (ast_mutex_trylock(&slave->lock)) {
03032             ast_mutex_unlock(&master->lock);
03033             usleep(1);
03034             ast_mutex_lock(&master->lock);
03035          }
03036       }
03037    }
03038    hasslaves = 0;
03039    for (x = 0; x < MAX_SLAVES; x++) {
03040       if (master->slaves[x]) {
03041          if (!slave || (master->slaves[x] == slave)) {
03042             /* Take slave out of the conference */
03043             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03044             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03045             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03046             master->slaves[x]->master = NULL;
03047             master->slaves[x] = NULL;
03048          } else
03049             hasslaves = 1;
03050       }
03051       if (!hasslaves)
03052          master->inconference = 0;
03053    }
03054    if (!slave) {
03055       if (master->master) {
03056          /* Take master out of the conference */
03057          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03058          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03059          hasslaves = 0;
03060          for (x = 0; x < MAX_SLAVES; x++) {
03061             if (master->master->slaves[x] == master)
03062                master->master->slaves[x] = NULL;
03063             else if (master->master->slaves[x])
03064                hasslaves = 1;
03065          }
03066          if (!hasslaves)
03067             master->master->inconference = 0;
03068       }
03069       master->master = NULL;
03070    }
03071    update_conf(master);
03072    if (needlock) {
03073       if (slave)
03074          ast_mutex_unlock(&slave->lock);
03075       ast_mutex_unlock(&master->lock);
03076    }
03077 }
03078 
03079 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03080    int x;
03081    if (!slave || !master) {
03082       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03083       return;
03084    }
03085    for (x = 0; x < MAX_SLAVES; x++) {
03086       if (!master->slaves[x]) {
03087          master->slaves[x] = slave;
03088          break;
03089       }
03090    }
03091    if (x >= MAX_SLAVES) {
03092       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03093       master->slaves[MAX_SLAVES - 1] = slave;
03094    }
03095    if (slave->master) 
03096       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03097    slave->master = master;
03098    
03099    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03100 }
03101 
03102 static void disable_dtmf_detect(struct zt_pvt *p)
03103 {
03104 #ifdef ZT_TONEDETECT
03105    int val;
03106 #endif
03107 
03108    p->ignoredtmf = 1;
03109 
03110 #ifdef ZT_TONEDETECT
03111    val = 0;
03112    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03113 #endif      
03114    if (!p->hardwaredtmf && p->dsp) {
03115       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03116       ast_dsp_set_features(p->dsp, p->dsp_features);
03117    }
03118 }
03119 
03120 static void enable_dtmf_detect(struct zt_pvt *p)
03121 {
03122 #ifdef ZT_TONEDETECT
03123    int val;
03124 #endif
03125 
03126    if (p->channel == CHAN_PSEUDO)
03127       return;
03128 
03129    p->ignoredtmf = 0;
03130 
03131 #ifdef ZT_TONEDETECT
03132    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03133    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03134 #endif      
03135    if (!p->hardwaredtmf && p->dsp) {
03136       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03137       ast_dsp_set_features(p->dsp, p->dsp_features);
03138    }
03139 }
03140 
03141 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)
03142 {
03143    struct ast_channel *who;
03144    struct zt_pvt *p0, *p1, *op0, *op1;
03145    struct zt_pvt *master = NULL, *slave = NULL;
03146    struct ast_frame *f;
03147    int inconf = 0;
03148    int nothingok = 1;
03149    int ofd0, ofd1;
03150    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03151    int os0 = -1, os1 = -1;
03152    int priority = 0;
03153    struct ast_channel *oc0, *oc1;
03154    enum ast_bridge_result res;
03155 
03156 #ifdef PRI_2BCT
03157    int triedtopribridge = 0;
03158    q931_call *q931c0 = NULL, *q931c1 = NULL;
03159 #endif
03160 
03161    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03162       There is code below to handle it properly until DTMF is actually seen,
03163       but due to currently unresolved issues it's ignored...
03164    */
03165 
03166    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03167       return AST_BRIDGE_FAILED_NOWARN;
03168 
03169    ast_mutex_lock(&c0->lock);
03170    ast_mutex_lock(&c1->lock);
03171 
03172    p0 = c0->tech_pvt;
03173    p1 = c1->tech_pvt;
03174    /* cant do pseudo-channels here */
03175    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03176       ast_mutex_unlock(&c0->lock);
03177       ast_mutex_unlock(&c1->lock);
03178       return AST_BRIDGE_FAILED_NOWARN;
03179    }
03180 
03181    oi0 = zt_get_index(c0, p0, 0);
03182    oi1 = zt_get_index(c1, p1, 0);
03183    if ((oi0 < 0) || (oi1 < 0)) {
03184       ast_mutex_unlock(&c0->lock);
03185       ast_mutex_unlock(&c1->lock);
03186       return AST_BRIDGE_FAILED;
03187    }
03188 
03189    op0 = p0 = c0->tech_pvt;
03190    op1 = p1 = c1->tech_pvt;
03191    ofd0 = c0->fds[0];
03192    ofd1 = c1->fds[0];
03193    oc0 = p0->owner;
03194    oc1 = p1->owner;
03195 
03196    if (ast_mutex_trylock(&p0->lock)) {
03197       /* Don't block, due to potential for deadlock */
03198       ast_mutex_unlock(&c0->lock);
03199       ast_mutex_unlock(&c1->lock);
03200       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03201       return AST_BRIDGE_RETRY;
03202    }
03203    if (ast_mutex_trylock(&p1->lock)) {
03204       /* Don't block, due to potential for deadlock */
03205       ast_mutex_unlock(&p0->lock);
03206       ast_mutex_unlock(&c0->lock);
03207       ast_mutex_unlock(&c1->lock);
03208       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03209       return AST_BRIDGE_RETRY;
03210    }
03211 
03212    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03213       if (p0->owner && p1->owner) {
03214          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03215          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03216             master = p0;
03217             slave = p1;
03218             inconf = 1;
03219          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03220             master = p1;
03221             slave = p0;
03222             inconf = 1;
03223          } else {
03224             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03225             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03226                p0->channel,
03227                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03228                p0->subs[SUB_REAL].inthreeway, p0->channel,
03229                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03230                p1->subs[SUB_REAL].inthreeway);
03231          }
03232          nothingok = 0;
03233       }
03234    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03235       if (p1->subs[SUB_THREEWAY].inthreeway) {
03236          master = p1;
03237          slave = p0;
03238          nothingok = 0;
03239       }
03240    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03241       if (p0->subs[SUB_THREEWAY].inthreeway) {
03242          master = p0;
03243          slave = p1;
03244          nothingok = 0;
03245       }
03246    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03247       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03248          don't put us in anything */
03249       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03250          master = p1;
03251          slave = p0;
03252          nothingok = 0;
03253       }
03254    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03255       /* Same as previous */
03256       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03257          master = p0;
03258          slave = p1;
03259          nothingok = 0;
03260       }
03261    }
03262    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03263       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03264    if (master && slave) {
03265       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03266          in an active threeway call with a channel that is ringing, we should
03267          indicate ringing. */
03268       if ((oi1 == SUB_THREEWAY) && 
03269           p1->subs[SUB_THREEWAY].inthreeway && 
03270           p1->subs[SUB_REAL].owner && 
03271           p1->subs[SUB_REAL].inthreeway && 
03272           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03273          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03274          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03275          os1 = p1->subs[SUB_REAL].owner->_state;
03276       } else {
03277          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03278          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03279       }
03280       if ((oi0 == SUB_THREEWAY) && 
03281           p0->subs[SUB_THREEWAY].inthreeway && 
03282           p0->subs[SUB_REAL].owner && 
03283           p0->subs[SUB_REAL].inthreeway && 
03284           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03285          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03286          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03287          os0 = p0->subs[SUB_REAL].owner->_state;
03288       } else {
03289          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03290          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03291       }
03292       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03293          if (!p0->echocanbridged || !p1->echocanbridged) {
03294             /* Disable echo cancellation if appropriate */
03295             zt_disable_ec(p0);
03296             zt_disable_ec(p1);
03297          }
03298       }
03299       zt_link(slave, master);
03300       master->inconference = inconf;
03301    } else if (!nothingok)
03302       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03303 
03304    update_conf(p0);
03305    update_conf(p1);
03306    t0 = p0->subs[SUB_REAL].inthreeway;
03307    t1 = p1->subs[SUB_REAL].inthreeway;
03308 
03309    ast_mutex_unlock(&p0->lock);
03310    ast_mutex_unlock(&p1->lock);
03311 
03312    ast_mutex_unlock(&c0->lock);
03313    ast_mutex_unlock(&c1->lock);
03314 
03315    /* Native bridge failed */
03316    if ((!master || !slave) && !nothingok) {
03317       zt_enable_ec(p0);
03318       zt_enable_ec(p1);
03319       return AST_BRIDGE_FAILED;
03320    }
03321    
03322    if (option_verbose > 2) 
03323       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03324 
03325    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03326       disable_dtmf_detect(op0);
03327 
03328    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03329       disable_dtmf_detect(op1);
03330 
03331    for (;;) {
03332       struct ast_channel *c0_priority[2] = {c0, c1};
03333       struct ast_channel *c1_priority[2] = {c1, c0};
03334 
03335       /* Here's our main loop...  Start by locking things, looking for private parts, 
03336          and then balking if anything is wrong */
03337       ast_mutex_lock(&c0->lock);
03338       ast_mutex_lock(&c1->lock);
03339       p0 = c0->tech_pvt;
03340       p1 = c1->tech_pvt;
03341 
03342       if (op0 == p0)
03343          i0 = zt_get_index(c0, p0, 1);
03344       if (op1 == p1)
03345          i1 = zt_get_index(c1, p1, 1);
03346       ast_mutex_unlock(&c0->lock);
03347       ast_mutex_unlock(&c1->lock);
03348 
03349       if (!timeoutms || 
03350           (op0 != p0) ||
03351           (op1 != p1) || 
03352           (ofd0 != c0->fds[0]) || 
03353           (ofd1 != c1->fds[0]) ||
03354           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03355           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03356           (oc0 != p0->owner) || 
03357           (oc1 != p1->owner) ||
03358           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03359           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03360           (oi0 != i0) ||
03361           (oi1 != i1)) {
03362          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03363             op0->channel, oi0, op1->channel, oi1);
03364          res = AST_BRIDGE_RETRY;
03365          goto return_from_bridge;
03366       }
03367 
03368 #ifdef PRI_2BCT
03369       q931c0 = p0->call;
03370       q931c1 = p1->call;
03371       if (p0->transfer && p1->transfer 
03372           && q931c0 && q931c1 
03373           && !triedtopribridge) {
03374          pri_channel_bridge(q931c0, q931c1);
03375          triedtopribridge = 1;
03376       }
03377 #endif
03378 
03379       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03380       if (!who) {
03381          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03382          continue;
03383       }
03384       f = ast_read(who);
03385       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03386          *fo = f;
03387          *rc = who;
03388          res = AST_BRIDGE_COMPLETE;
03389          goto return_from_bridge;
03390       }
03391       if (f->frametype == AST_FRAME_DTMF) {
03392          if ((who == c0) && p0->pulsedial) {
03393             ast_write(c1, f);
03394          } else if ((who == c1) && p1->pulsedial) {
03395             ast_write(c0, f);
03396          } else {
03397             *fo = f;
03398             *rc = who;
03399             res = AST_BRIDGE_COMPLETE;
03400             goto return_from_bridge;
03401          }
03402       }
03403       ast_frfree(f);
03404       
03405       /* Swap who gets priority */
03406       priority = !priority;
03407    }
03408 
03409 return_from_bridge:
03410    if (op0 == p0)
03411       zt_enable_ec(p0);
03412 
03413    if (op1 == p1)
03414       zt_enable_ec(p1);
03415 
03416    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03417       enable_dtmf_detect(op0);
03418 
03419    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03420       enable_dtmf_detect(op1);
03421 
03422    zt_unlink(slave, master, 1);
03423 
03424    return res;
03425 }
03426 
03427 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03428 {
03429    struct zt_pvt *p = newchan->tech_pvt;
03430    int x;
03431    ast_mutex_lock(&p->lock);
03432    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03433    if (p->owner == oldchan) {
03434       p->owner = newchan;
03435    }
03436    for (x = 0; x < 3; x++)
03437       if (p->subs[x].owner == oldchan) {
03438          if (!x)
03439             zt_unlink(NULL, p, 0);
03440          p->subs[x].owner = newchan;
03441       }
03442    if (newchan->_state == AST_STATE_RINGING) 
03443       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03444    update_conf(p);
03445    ast_mutex_unlock(&p->lock);
03446    return 0;
03447 }
03448 
03449 static int zt_ring_phone(struct zt_pvt *p)
03450 {
03451    int x;
03452    int res;
03453    /* Make sure our transmit state is on hook */
03454    x = 0;
03455    x = ZT_ONHOOK;
03456    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03457    do {
03458       x = ZT_RING;
03459       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03460       if (res) {
03461          switch (errno) {
03462          case EBUSY:
03463          case EINTR:
03464             /* Wait just in case */
03465             usleep(10000);
03466             continue;
03467          case EINPROGRESS:
03468             res = 0;
03469             break;
03470          default:
03471             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03472             res = 0;
03473          }
03474       }
03475    } while (res);
03476    return res;
03477 }
03478 
03479 static void *ss_thread(void *data);
03480 
03481 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03482 
03483 static int attempt_transfer(struct zt_pvt *p)
03484 {
03485    /* In order to transfer, we need at least one of the channels to
03486       actually be in a call bridge.  We can't conference two applications
03487       together (but then, why would we want to?) */
03488    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03489       /* The three-way person we're about to transfer to could still be in MOH, so
03490          stop if now if appropriate */
03491       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03492          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03493       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03494          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03495       }
03496       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03497          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03498       }
03499       if (p->subs[SUB_REAL].owner->cdr) {
03500          /* Move CDR from second channel to current one */
03501          p->subs[SUB_THREEWAY].owner->cdr =
03502             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03503          p->subs[SUB_REAL].owner->cdr = NULL;
03504       }
03505       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03506          /* Move CDR from second channel's bridge to current one */
03507          p->subs[SUB_THREEWAY].owner->cdr =
03508             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03509          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03510       }
03511        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03512          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03513                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03514          return -1;
03515       }
03516       /* Orphan the channel after releasing the lock */
03517       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03518       unalloc_sub(p, SUB_THREEWAY);
03519    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03520       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03521       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03522          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03523       }
03524       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03525          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03526       }
03527       if (p->subs[SUB_THREEWAY].owner->cdr) {
03528          /* Move CDR from second channel to current one */
03529          p->subs[SUB_REAL].owner->cdr = 
03530             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03531          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03532       }
03533       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03534          /* Move CDR from second channel's bridge to current one */
03535          p->subs[SUB_REAL].owner->cdr = 
03536             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03537          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03538       }
03539       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03540          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03541                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03542          return -1;
03543       }
03544       /* Three-way is now the REAL */
03545       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03546       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03547       unalloc_sub(p, SUB_THREEWAY);
03548       /* Tell the caller not to hangup */
03549       return 1;
03550    } else {
03551       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03552                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03553       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03554       return -1;
03555    }
03556    return 0;
03557 }
03558 
03559 static int check_for_conference(struct zt_pvt *p)
03560 {
03561    ZT_CONFINFO ci;
03562    /* Fine if we already have a master, etc */
03563    if (p->master || (p->confno > -1))
03564       return 0;
03565    memset(&ci, 0, sizeof(ci));
03566    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03567       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03568       return 0;
03569    }
03570    /* If we have no master and don't have a confno, then 
03571       if we're in a conference, it's probably a MeetMe room or
03572       some such, so don't let us 3-way out! */
03573    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03574       if (option_verbose > 2) 
03575          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03576       return 1;
03577    }
03578    return 0;
03579 }
03580 
03581 static int get_alarms(struct zt_pvt *p)
03582 {
03583    int res;
03584    ZT_SPANINFO zi;
03585    memset(&zi, 0, sizeof(zi));
03586    zi.spanno = p->span;
03587    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03588    if (res < 0) {
03589       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03590       return 0;
03591    }
03592    return zi.alarms;
03593 }
03594 
03595 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03596 {
03597    struct zt_pvt *p = ast->tech_pvt;
03598    struct ast_frame *f = *dest;
03599 
03600    if (option_debug)
03601       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03602 
03603    if (p->confirmanswer) {
03604       if (option_debug)
03605          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03606       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03607          of a DTMF digit */
03608       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03609       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03610       *dest = &p->subs[index].f;
03611       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03612       p->confirmanswer = 0;
03613    } else if (p->callwaitcas) {
03614       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03615          if (option_debug)
03616             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03617          if (p->cidspill)
03618             free(p->cidspill);
03619          send_cwcidspill(p);
03620       }
03621       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03622          p->callwaitcas = 0;
03623       p->subs[index].f.frametype = AST_FRAME_NULL;
03624       p->subs[index].f.subclass = 0;
03625       *dest = &p->subs[index].f;
03626    } else if (f->subclass == 'f') {
03627       /* Fax tone -- Handle and return NULL */
03628       if ((p->callprogress & 0x6) && !p->faxhandled) {
03629          p->faxhandled++;
03630          if (strcmp(ast->exten, "fax")) {
03631             const char *target_context = S_OR(ast->macrocontext, ast->context);
03632 
03633             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03634                if (option_verbose > 2)
03635                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03636                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03637                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03638                if (ast_async_goto(ast, target_context, "fax", 1))
03639                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03640             } else
03641                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03642          } else if (option_debug)
03643             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03644       } else if (option_debug)
03645             ast_log(LOG_DEBUG, "Fax already handled\n");
03646       zt_confmute(p, 0);
03647       p->subs[index].f.frametype = AST_FRAME_NULL;
03648       p->subs[index].f.subclass = 0;
03649       *dest = &p->subs[index].f;
03650    } else if (f->subclass == 'm') {
03651       /* Confmute request */
03652       zt_confmute(p, 1);
03653       p->subs[index].f.frametype = AST_FRAME_NULL;
03654       p->subs[index].f.subclass = 0;
03655       *dest = &p->subs[index].f;    
03656    } else if (f->subclass == 'u') {
03657       /* Unmute */
03658       zt_confmute(p, 0);
03659       p->subs[index].f.frametype = AST_FRAME_NULL;
03660       p->subs[index].f.subclass = 0;
03661       *dest = &p->subs[index].f;    
03662    } else
03663       zt_confmute(p, 0);
03664 }
03665          
03666 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03667 {
03668    int res, x;
03669    int index, mysig;
03670    char *c;
03671    struct zt_pvt *p = ast->tech_pvt;
03672    pthread_t threadid;
03673    pthread_attr_t attr;
03674    struct ast_channel *chan;
03675    struct ast_frame *f;
03676 
03677    index = zt_get_index(ast, p, 0);
03678    mysig = p->sig;
03679    if (p->outsigmod > -1)
03680       mysig = p->outsigmod;
03681    p->subs[index].f.frametype = AST_FRAME_NULL;
03682    p->subs[index].f.subclass = 0;
03683    p->subs[index].f.datalen = 0;
03684    p->subs[index].f.samples = 0;
03685    p->subs[index].f.mallocd = 0;
03686    p->subs[index].f.offset = 0;
03687    p->subs[index].f.src = "zt_handle_event";
03688    p->subs[index].f.data = NULL;
03689    f = &p->subs[index].f;
03690 
03691    if (index < 0)
03692       return &p->subs[index].f;
03693    if (p->fake_event) {
03694       res = p->fake_event;
03695       p->fake_event = 0;
03696    } else
03697       res = zt_get_event(p->subs[index].zfd);
03698 
03699    if (option_debug)
03700       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03701 
03702    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03703       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03704 
03705       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03706 #ifdef HAVE_PRI
03707       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03708          /* absorb event */
03709       } else {
03710 #endif
03711          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03712          p->subs[index].f.subclass = res & 0xff;
03713 #ifdef HAVE_PRI
03714       }
03715 #endif
03716       zt_handle_dtmfup(ast, index, &f);
03717       return f;
03718    }
03719 
03720    if (res & ZT_EVENT_DTMFDOWN) {
03721       if (option_debug)
03722          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03723       /* Mute conference */
03724       zt_confmute(p, 1);
03725       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03726       p->subs[index].f.subclass = res & 0xff;
03727       return &p->subs[index].f;
03728    }
03729 
03730    switch (res) {
03731 #ifdef ZT_EVENT_EC_DISABLED
03732       case ZT_EVENT_EC_DISABLED:
03733          if (option_verbose > 2) 
03734             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03735          p->echocanon = 0;
03736          break;
03737 #endif
03738       case ZT_EVENT_BITSCHANGED:
03739          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03740       case ZT_EVENT_PULSE_START:
03741          /* Stop tone if there's a pulse start and the PBX isn't started */
03742          if (!ast->pbx)
03743             tone_zone_play_tone(p->subs[index].zfd, -1);
03744          break;   
03745       case ZT_EVENT_DIALCOMPLETE:
03746          if (p->inalarm) break;
03747          if ((p->radio || (p->oprmode < 0))) break;
03748          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03749             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03750             return NULL;
03751          }
03752          if (!x) { /* if not still dialing in driver */
03753             zt_enable_ec(p);
03754             if (p->echobreak) {
03755                zt_train_ec(p);
03756                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03757                p->dop.op = ZT_DIAL_OP_REPLACE;
03758                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03759                p->echobreak = 0;
03760             } else {
03761                p->dialing = 0;
03762                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03763                   /* if thru with dialing after offhook */
03764                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03765                      ast_setstate(ast, AST_STATE_UP);
03766                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03767                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03768                      break;
03769                   } else { /* if to state wait for offhook to dial rest */
03770                      /* we now wait for off hook */
03771                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03772                   }
03773                }
03774                if (ast->_state == AST_STATE_DIALING) {
03775                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03776                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03777                   } 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)))) {
03778                      ast_setstate(ast, AST_STATE_RINGING);
03779                   } else if (!p->answeronpolarityswitch) {
03780                      ast_setstate(ast, AST_STATE_UP);
03781                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03782                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03783                   }
03784                }
03785             }
03786          }
03787          break;
03788       case ZT_EVENT_ALARM:
03789 #ifdef HAVE_PRI
03790          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03791             /* T309 is not enabled : hangup calls when alarm occurs */
03792             if (p->call) {
03793                if (p->pri && p->pri->pri) {
03794                   if (!pri_grab(p, p->pri)) {
03795                      pri_hangup(p->pri->pri, p->call, -1);
03796                      pri_destroycall(p->pri->pri, p->call);
03797                      p->call = NULL;
03798                      pri_rel(p->pri);
03799                   } else
03800                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03801                } else
03802                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03803             }
03804             if (p->owner)
03805                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03806          }
03807          if (p->bearer)
03808             p->bearer->inalarm = 1;
03809          else
03810 #endif
03811          p->inalarm = 1;
03812          res = get_alarms(p);
03813          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
03814          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03815                         "Alarm: %s\r\n"
03816                         "Channel: %d\r\n",
03817                         alarm2str(res), p->channel);
03818 #ifdef HAVE_LIBPRI
03819          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
03820             /* fall through intentionally */
03821          } else {
03822             break;
03823          }
03824 #endif
03825       case ZT_EVENT_ONHOOK:
03826          if (p->radio) {
03827             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03828             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03829             break;
03830          }
03831          if (p->oprmode < 0)
03832          {
03833             if (p->oprmode != -1) break;
03834             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03835             {
03836                /* Make sure it starts ringing */
03837                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03838                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
03839                save_conference(p->oprpeer);
03840                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03841             }
03842             break;
03843          }
03844          switch (p->sig) {
03845          case SIG_FXOLS:
03846          case SIG_FXOGS:
03847          case SIG_FXOKS:
03848             p->onhooktime = time(NULL);
03849             p->msgstate = -1;
03850             /* Check for some special conditions regarding call waiting */
03851             if (index == SUB_REAL) {
03852                /* The normal line was hung up */
03853                if (p->subs[SUB_CALLWAIT].owner) {
03854                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03855                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03856                   if (option_verbose > 2) 
03857                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03858                   unalloc_sub(p, SUB_CALLWAIT); 
03859 #if 0
03860                   p->subs[index].needanswer = 0;
03861                   p->subs[index].needringing = 0;
03862 #endif                  
03863                   p->callwaitingrepeat = 0;
03864                   p->cidcwexpire = 0;
03865                   p->owner = NULL;
03866                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03867                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03868                      p->dialing = 1;
03869                   zt_ring_phone(p);
03870                } else if (p->subs[SUB_THREEWAY].owner) {
03871                   unsigned int mssinceflash;
03872                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03873                      the private structure -- not especially easy or clean */
03874                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03875                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03876                      ast_mutex_unlock(&p->lock);
03877                      ast_mutex_unlock(&ast->lock);
03878                      usleep(1);
03879                      /* We can grab ast and p in that order, without worry.  We should make sure
03880                         nothing seriously bad has happened though like some sort of bizarre double
03881                         masquerade! */
03882                      ast_mutex_lock(&ast->lock);
03883                      ast_mutex_lock(&p->lock);
03884                      if (p->owner != ast) {
03885                         ast_log(LOG_WARNING, "This isn't good...\n");
03886                         return NULL;
03887                      }
03888                   }
03889                   if (!p->subs[SUB_THREEWAY].owner) {
03890                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03891                      return NULL;
03892                   }
03893                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03894                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03895                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03896                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03897                         hanging up.  Hangup both channels now */
03898                      if (p->subs[SUB_THREEWAY].owner)
03899                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03900                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03901                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03902                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03903                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03904                      if (p->transfer) {
03905                         /* In any case this isn't a threeway call anymore */
03906                         p->subs[SUB_REAL].inthreeway = 0;
03907                         p->subs[SUB_THREEWAY].inthreeway = 0;
03908                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03909                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03910                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03911                            /* Swap subs and dis-own channel */
03912                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03913                            p->owner = NULL;
03914                            /* Ring the phone */
03915                            zt_ring_phone(p);
03916                         } else {
03917                            if ((res = attempt_transfer(p)) < 0) {
03918                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03919                               if (p->subs[SUB_THREEWAY].owner)
03920                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03921                            } else if (res) {
03922                               /* Don't actually hang up at this point */
03923                               if (p->subs[SUB_THREEWAY].owner)
03924                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03925                               break;
03926                            }
03927                         }
03928                      } else {
03929                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03930                         if (p->subs[SUB_THREEWAY].owner)
03931                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03932                      }
03933                   } else {
03934                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03935                      /* Swap subs and dis-own channel */
03936                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03937                      p->owner = NULL;
03938                      /* Ring the phone */
03939                      zt_ring_phone(p);
03940                   }
03941                }
03942             } else {
03943                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03944             }
03945             /* Fall through */
03946          default:
03947             zt_disable_ec(p);
03948             return NULL;
03949          }
03950          break;
03951       case ZT_EVENT_RINGOFFHOOK:
03952          if (p->inalarm) break;
03953          if (p->oprmode < 0)
03954          {
03955             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03956             {
03957                /* Make sure it stops ringing */
03958                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03959                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
03960                restore_conference(p->oprpeer);
03961             }
03962             break;
03963          }
03964          if (p->radio)
03965          {
03966             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03967             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
03968             break;
03969          }
03970          /* for E911, its supposed to wait for offhook then dial
03971             the second half of the dial string */
03972          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
03973             c = strchr(p->dialdest, '/');
03974             if (c)
03975                c++;
03976             else
03977                c = p->dialdest;
03978             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
03979             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
03980             if (strlen(p->dop.dialstr) > 4) {
03981                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
03982                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
03983                p->echorest[sizeof(p->echorest) - 1] = '\0';
03984                p->echobreak = 1;
03985                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
03986             } else
03987                p->echobreak = 0;
03988             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
03989                x = ZT_ONHOOK;
03990                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03991                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
03992                return NULL;
03993                }
03994             p->dialing = 1;
03995             return &p->subs[index].f;
03996          }
03997          switch (p->sig) {
03998          case SIG_FXOLS:
03999          case SIG_FXOGS:
04000          case SIG_FXOKS:
04001             switch (ast->_state) {
04002             case AST_STATE_RINGING:
04003                zt_enable_ec(p);
04004                zt_train_ec(p);
04005                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04006                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04007                /* Make sure it stops ringing */
04008                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04009                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04010                if (p->cidspill) {
04011                   /* Cancel any running CallerID spill */
04012                   free(p->cidspill);
04013                   p->cidspill = NULL;
04014                }
04015                p->dialing = 0;
04016                p->callwaitcas = 0;
04017                if (p->confirmanswer) {
04018                   /* Ignore answer if "confirm answer" is enabled */
04019                   p->subs[index].f.frametype = AST_FRAME_NULL;
04020                   p->subs[index].f.subclass = 0;
04021                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04022                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04023                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04024                   if (res < 0) {
04025                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04026                      p->dop.dialstr[0] = '\0';
04027                      return NULL;
04028                   } else {
04029                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04030                      p->subs[index].f.frametype = AST_FRAME_NULL;
04031                      p->subs[index].f.subclass = 0;
04032                      p->dialing = 1;
04033                   }
04034                   p->dop.dialstr[0] = '\0';
04035                   ast_setstate(ast, AST_STATE_DIALING);
04036                } else
04037                   ast_setstate(ast, AST_STATE_UP);
04038                return &p->subs[index].f;
04039             case AST_STATE_DOWN:
04040                ast_setstate(ast, AST_STATE_RING);
04041                ast->rings = 1;
04042                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04043                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04044                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04045                return &p->subs[index].f;
04046             case AST_STATE_UP:
04047                /* Make sure it stops ringing */
04048                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04049                /* Okay -- probably call waiting*/
04050                if (ast_bridged_channel(p->owner))
04051                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04052                p->subs[index].needunhold = 1;
04053                break;
04054             case AST_STATE_RESERVED:
04055                /* Start up dialtone */
04056                if (has_voicemail(p))
04057                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04058                else
04059                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04060                break;
04061             default:
04062                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04063             }
04064             break;
04065          case SIG_FXSLS:
04066          case SIG_FXSGS:
04067          case SIG_FXSKS:
04068             if (ast->_state == AST_STATE_RING) {
04069                p->ringt = p->ringt_base;
04070             }
04071 
04072             /* If we get a ring then we cannot be in 
04073              * reversed polarity. So we reset to idle */
04074             if (option_debug)
04075                ast_log(LOG_DEBUG, "Setting IDLE polarity due "
04076                   "to ring. Old polarity was %d\n", 
04077                   p->polarity);
04078             p->polarity = POLARITY_IDLE;
04079 
04080             /* Fall through */
04081          case SIG_EM:
04082          case SIG_EM_E1:
04083          case SIG_EMWINK:
04084          case SIG_FEATD:
04085          case SIG_FEATDMF:
04086          case SIG_FEATDMF_TA:
04087          case SIG_E911:
04088          case SIG_FGC_CAMA:
04089          case SIG_FGC_CAMAMF:
04090          case SIG_FEATB:
04091          case SIG_SF:
04092          case SIG_SFWINK:
04093          case SIG_SF_FEATD:
04094          case SIG_SF_FEATDMF:
04095          case SIG_SF_FEATB:
04096             if (ast->_state == AST_STATE_PRERING)
04097                ast_setstate(ast, AST_STATE_RING);
04098             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04099                if (option_debug)
04100                   ast_log(LOG_DEBUG, "Ring detected\n");
04101                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04102                p->subs[index].f.subclass = AST_CONTROL_RING;
04103             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04104                if (option_debug)
04105                   ast_log(LOG_DEBUG, "Line answered\n");
04106                if (p->confirmanswer) {
04107                   p->subs[index].f.frametype = AST_FRAME_NULL;
04108                   p->subs[index].f.subclass = 0;
04109                } else {
04110                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04111                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04112                   ast_setstate(ast, AST_STATE_UP);
04113                }
04114             } else if (ast->_state != AST_STATE_RING)
04115                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04116             break;
04117          default:
04118             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04119          }
04120          break;
04121 #ifdef ZT_EVENT_RINGBEGIN
04122       case ZT_EVENT_RINGBEGIN:
04123          switch (p->sig) {
04124          case SIG_FXSLS:
04125          case SIG_FXSGS:
04126          case SIG_FXSKS:
04127             if (ast->_state == AST_STATE_RING) {
04128                p->ringt = p->ringt_base;
04129             }
04130             break;
04131          }
04132          break;
04133 #endif         
04134       case ZT_EVENT_RINGEROFF:
04135          if (p->inalarm) break;
04136          if ((p->radio || (p->oprmode < 0))) break;
04137          ast->rings++;
04138          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04139             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04140             free(p->cidspill);
04141             p->cidspill = NULL;
04142             p->callwaitcas = 0;
04143          }
04144          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04145          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04146          break;
04147       case ZT_EVENT_RINGERON:
04148          break;
04149       case ZT_EVENT_NOALARM:
04150          p->inalarm = 0;
04151 #ifdef HAVE_PRI
04152          /* Extremely unlikely but just in case */
04153          if (p->bearer)
04154             p->bearer->inalarm = 0;
04155 #endif            
04156          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04157          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04158                         "Channel: %d\r\n", p->channel);
04159          break;
04160       case ZT_EVENT_WINKFLASH:
04161          if (p->inalarm) break;
04162          if (p->radio) break;
04163          if (p->oprmode < 0) break;
04164          if (p->oprmode > 1)
04165          {
04166             struct zt_params par;
04167 
04168             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04169             {
04170                if (!par.rxisoffhook)
04171                {
04172                   /* Make sure it stops ringing */
04173                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04174                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04175                   save_conference(p);
04176                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04177                }
04178             }
04179             break;
04180          }
04181          /* Remember last time we got a flash-hook */
04182          gettimeofday(&p->flashtime, NULL);
04183          switch (mysig) {
04184          case SIG_FXOLS:
04185          case SIG_FXOGS:
04186          case SIG_FXOKS:
04187             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04188                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04189             p->callwaitcas = 0;
04190 
04191             if (index != SUB_REAL) {
04192                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04193                goto winkflashdone;
04194             }
04195             
04196             if (p->subs[SUB_CALLWAIT].owner) {
04197                /* Swap to call-wait */
04198                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04199                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04200                p->owner = p->subs[SUB_REAL].owner;
04201                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04202                if (p->owner->_state == AST_STATE_RINGING) {
04203                   ast_setstate(p->owner, AST_STATE_UP);
04204                   p->subs[SUB_REAL].needanswer = 1;
04205                }
04206                p->callwaitingrepeat = 0;
04207                p->cidcwexpire = 0;
04208                /* Start music on hold if appropriate */
04209                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04210                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04211                      S_OR(p->mohsuggest, NULL),
04212                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04213                }
04214                p->subs[SUB_CALLWAIT].needhold = 1;
04215                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04216                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04217                      S_OR(p->mohsuggest, NULL),
04218                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04219                }
04220                p->subs[SUB_REAL].needunhold = 1;
04221             } else if (!p->subs[SUB_THREEWAY].owner) {
04222                char cid_num[256];
04223                char cid_name[256];
04224 
04225                if (!p->threewaycalling) {
04226                   /* Just send a flash if no 3-way calling */
04227                   p->subs[SUB_REAL].needflash = 1;
04228                   goto winkflashdone;
04229                } else if (!check_for_conference(p)) {
04230                   if (p->zaptrcallerid && p->owner) {
04231                      if (p->owner->cid.cid_num)
04232                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04233                      if (p->owner->cid.cid_name)
04234                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04235                   }
04236                   /* XXX This section needs much more error checking!!! XXX */
04237                   /* Start a 3-way call if feasible */
04238                   if (!((ast->pbx) ||
04239                         (ast->_state == AST_STATE_UP) ||
04240                         (ast->_state == AST_STATE_RING))) {
04241                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04242                         goto winkflashdone;
04243                   }
04244                   if (alloc_sub(p, SUB_THREEWAY)) {
04245                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04246                      goto winkflashdone;
04247                   }
04248                   /* Make new channel */
04249                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04250                   if (p->zaptrcallerid) {
04251                      if (!p->origcid_num)
04252                         p->origcid_num = ast_strdup(p->cid_num);
04253                      if (!p->origcid_name)
04254                         p->origcid_name = ast_strdup(p->cid_name);
04255                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04256                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04257                   }
04258                   /* Swap things around between the three-way and real call */
04259                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04260                   /* Disable echo canceller for better dialing */
04261                   zt_disable_ec(p);
04262                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04263                   if (res)
04264                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04265                   p->owner = chan;
04266                   pthread_attr_init(&attr);
04267                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04268                   if (!chan) {
04269                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04270                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04271                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04272                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04273                      zt_enable_ec(p);
04274                      ast_hangup(chan);
04275                   } else {
04276                      if (option_verbose > 2) 
04277                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04278                      /* Start music on hold if appropriate */
04279                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04280                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04281                            S_OR(p->mohsuggest, NULL),
04282                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04283                      }
04284                      p->subs[SUB_THREEWAY].needhold = 1;
04285                   }
04286                   pthread_attr_destroy(&attr);
04287                }
04288             } else {
04289                /* Already have a 3 way call */
04290                if (p->subs[SUB_THREEWAY].inthreeway) {
04291                   /* Call is already up, drop the last person */
04292                   if (option_debug)
04293                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04294                   /* If the primary call isn't answered yet, use it */
04295                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04296                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04297                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04298                      p->owner = p->subs[SUB_REAL].owner;
04299                   }
04300                   /* Drop the last call and stop the conference */
04301                   if (option_verbose > 2)
04302                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04303                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04304                   p->subs[SUB_REAL].inthreeway = 0;
04305                   p->subs[SUB_THREEWAY].inthreeway = 0;
04306                } else {
04307                   /* Lets see what we're up to */
04308                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04309                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04310                      int otherindex = SUB_THREEWAY;
04311 
04312                      if (option_verbose > 2)
04313                         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);
04314                      /* Put them in the threeway, and flip */
04315                      p->subs[SUB_THREEWAY].inthreeway = 1;
04316                      p->subs[SUB_REAL].inthreeway = 1;
04317                      if (ast->_state == AST_STATE_UP) {
04318                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04319                         otherindex = SUB_REAL;
04320                      }
04321                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04322                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04323                      p->subs[otherindex].needunhold = 1;
04324                      p->owner = p->subs[SUB_REAL].owner;
04325                      if (ast->_state == AST_STATE_RINGING) {
04326                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04327                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04328                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04329                      }
04330                   } else {
04331                      if (option_verbose > 2)
04332                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04333                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04334                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04335                      p->owner = p->subs[SUB_REAL].owner;
04336                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04337                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04338                      p->subs[SUB_REAL].needunhold = 1;
04339                      zt_enable_ec(p);
04340                   }
04341                      
04342                }
04343             }
04344          winkflashdone:              
04345             update_conf(p);
04346             break;
04347          case SIG_EM:
04348          case SIG_EM_E1:
04349          case SIG_EMWINK:
04350          case SIG_FEATD:
04351          case SIG_SF:
04352          case SIG_SFWINK:
04353          case SIG_SF_FEATD:
04354          case SIG_FXSLS:
04355          case SIG_FXSGS:
04356             if (p->dialing)
04357                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04358             else
04359                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04360             break;
04361          case SIG_FEATDMF_TA:
04362             switch (p->whichwink) {
04363             case 0:
04364                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04365                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04366                break;
04367             case 1:
04368                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04369                break;
04370             case 2:
04371                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04372                return NULL;
04373             }
04374             p->whichwink++;
04375             /* Fall through */
04376          case SIG_FEATDMF:
04377          case SIG_E911:
04378          case SIG_FGC_CAMAMF:
04379          case SIG_FGC_CAMA:
04380          case SIG_FEATB:
04381          case SIG_SF_FEATDMF:
04382          case SIG_SF_FEATB:
04383             /* FGD MF *Must* wait for wink */
04384             if (!ast_strlen_zero(p->dop.dialstr))
04385                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04386             else if (res < 0) {
04387                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04388                p->dop.dialstr[0] = '\0';
04389                return NULL;
04390             } else 
04391                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04392             p->dop.dialstr[0] = '\0';
04393             break;
04394          default:
04395             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04396          }
04397          break;
04398       case ZT_EVENT_HOOKCOMPLETE:
04399          if (p->inalarm) break;
04400          if ((p->radio || (p->oprmode < 0))) break;
04401          switch (mysig) {
04402          case SIG_FXSLS:  /* only interesting for FXS */
04403          case SIG_FXSGS:
04404          case SIG_FXSKS:
04405          case SIG_EM:
04406          case SIG_EM_E1:
04407          case SIG_EMWINK:
04408          case SIG_FEATD:
04409          case SIG_SF:
04410          case SIG_SFWINK:
04411          case SIG_SF_FEATD:
04412             if (!ast_strlen_zero(p->dop.dialstr)) 
04413                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04414             else if (res < 0) {
04415                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04416                p->dop.dialstr[0] = '\0';
04417                return NULL;
04418             } else 
04419                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04420             p->dop.dialstr[0] = '\0';
04421             p->dop.op = ZT_DIAL_OP_REPLACE;
04422             break;
04423          case SIG_FEATDMF:
04424          case SIG_FEATDMF_TA:
04425          case SIG_E911:
04426          case SIG_FGC_CAMA:
04427          case SIG_FGC_CAMAMF:
04428          case SIG_FEATB:
04429          case SIG_SF_FEATDMF:
04430          case SIG_SF_FEATB:
04431             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04432             break;
04433          default:
04434             break;
04435          }
04436          break;
04437       case ZT_EVENT_POLARITY:
04438          /*
04439           * If we get a Polarity Switch event, check to see
04440           * if we should change the polarity state and
04441           * mark the channel as UP or if this is an indication
04442           * of remote end disconnect.
04443           */
04444          if (p->polarity == POLARITY_IDLE) {
04445             p->polarity = POLARITY_REV;
04446             if (p->answeronpolarityswitch &&
04447                 ((ast->_state == AST_STATE_DIALING) ||
04448                 (ast->_state == AST_STATE_RINGING))) {
04449                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04450                ast_setstate(p->owner, AST_STATE_UP);
04451                if (p->hanguponpolarityswitch) {
04452                   gettimeofday(&p->polaritydelaytv, NULL);
04453                }
04454             } else
04455                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04456          } 
04457          /* Removed else statement from here as it was preventing hangups from ever happening*/
04458          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04459          if (p->hanguponpolarityswitch &&
04460             (p->polarityonanswerdelay > 0) &&
04461                 (p->polarity == POLARITY_REV) &&
04462             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04463                                 /* Added log_debug information below to provide a better indication of what is going on */
04464             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) );
04465          
04466             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04467                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04468                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04469                p->polarity = POLARITY_IDLE;
04470             } else {
04471                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);
04472             }
04473          } else {
04474             p->polarity = POLARITY_IDLE;
04475             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04476          }
04477                         /* Added more log_debug information below to provide a better indication of what is going on */
04478          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) );
04479          break;
04480       default:
04481          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04482    }
04483    return &p->subs[index].f;
04484 }
04485 
04486 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04487 {
04488    struct zt_pvt *p = ast->tech_pvt;
04489    int res;
04490    int usedindex=-1;
04491    int index;
04492    struct ast_frame *f;
04493 
04494 
04495    index = zt_get_index(ast, p, 1);
04496    
04497    p->subs[index].f.frametype = AST_FRAME_NULL;
04498    p->subs[index].f.datalen = 0;
04499    p->subs[index].f.samples = 0;
04500    p->subs[index].f.mallocd = 0;
04501    p->subs[index].f.offset = 0;
04502    p->subs[index].f.subclass = 0;
04503    p->subs[index].f.delivery = ast_tv(0,0);
04504    p->subs[index].f.src = "zt_exception";
04505    p->subs[index].f.data = NULL;
04506    
04507    
04508    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04509       /* If nobody owns us, absorb the event appropriately, otherwise
04510          we loop indefinitely.  This occurs when, during call waiting, the
04511          other end hangs up our channel so that it no longer exists, but we
04512          have neither FLASH'd nor ONHOOK'd to signify our desire to
04513          change to the other channel. */
04514       if (p->fake_event) {
04515          res = p->fake_event;
04516          p->fake_event = 0;
04517       } else
04518          res = zt_get_event(p->subs[SUB_REAL].zfd);
04519       /* Switch to real if there is one and this isn't something really silly... */
04520       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04521          (res != ZT_EVENT_HOOKCOMPLETE)) {
04522          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04523          p->owner = p->subs[SUB_REAL].owner;
04524          if (p->owner && ast_bridged_channel(p->owner))
04525             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04526          p->subs[SUB_REAL].needunhold = 1;
04527       }
04528       switch (res) {
04529       case ZT_EVENT_ONHOOK:
04530          zt_disable_ec(p);
04531          if (p->owner) {
04532             if (option_verbose > 2) 
04533                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04534             zt_ring_phone(p);
04535             p->callwaitingrepeat = 0;
04536             p->cidcwexpire = 0;
04537          } else
04538             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04539          update_conf(p);
04540          break;
04541       case ZT_EVENT_RINGOFFHOOK:
04542          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04543          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04544             p->subs[SUB_REAL].needanswer = 1;
04545             p->dialing = 0;
04546          }
04547          break;
04548       case ZT_EVENT_HOOKCOMPLETE:
04549       case ZT_EVENT_RINGERON:
04550       case ZT_EVENT_RINGEROFF:
04551          /* Do nothing */
04552          break;
04553       case ZT_EVENT_WINKFLASH:
04554          gettimeofday(&p->flashtime, NULL);
04555          if (p->owner) {
04556             if (option_verbose > 2) 
04557                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04558             if (p->owner->_state != AST_STATE_UP) {
04559                /* Answer if necessary */
04560                usedindex = zt_get_index(p->owner, p, 0);
04561                if (usedindex > -1) {
04562                   p->subs[usedindex].needanswer = 1;
04563                }
04564                ast_setstate(p->owner, AST_STATE_UP);
04565             }
04566             p->callwaitingrepeat = 0;
04567             p->cidcwexpire = 0;
04568             if (ast_bridged_channel(p->owner))
04569                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04570             p->subs[SUB_REAL].needunhold = 1;
04571          } else
04572             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04573          update_conf(p);
04574          break;
04575       default:
04576          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04577       }
04578       f = &p->subs[index].f;
04579       return f;
04580    }
04581    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04582       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04583    /* If it's not us, return NULL immediately */
04584    if (ast != p->owner) {
04585       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04586       f = &p->subs[index].f;
04587       return f;
04588    }
04589    f = zt_handle_event(ast);
04590    return f;
04591 }
04592 
04593 static struct ast_frame *zt_exception(struct ast_channel *ast)
04594 {
04595    struct zt_pvt *p = ast->tech_pvt;
04596    struct ast_frame *f;
04597    ast_mutex_lock(&p->lock);
04598    f = __zt_exception(ast);
04599    ast_mutex_unlock(&p->lock);
04600    return f;
04601 }
04602 
04603 static struct ast_frame  *zt_read(struct ast_channel *ast)
04604 {
04605    struct zt_pvt *p = ast->tech_pvt;
04606    int res;
04607    int index;
04608    void *readbuf;
04609    struct ast_frame *f;
04610    
04611 
04612    ast_mutex_lock(&p->lock);
04613    
04614    index = zt_get_index(ast, p, 0);
04615    
04616    /* Hang up if we don't really exist */
04617    if (index < 0) {
04618       ast_log(LOG_WARNING, "We dont exist?\n");
04619       ast_mutex_unlock(&p->lock);
04620       return NULL;
04621    }
04622    
04623    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04624 
04625    p->subs[index].f.frametype = AST_FRAME_NULL;
04626    p->subs[index].f.datalen = 0;
04627    p->subs[index].f.samples = 0;
04628    p->subs[index].f.mallocd = 0;
04629    p->subs[index].f.offset = 0;
04630    p->subs[index].f.subclass = 0;
04631    p->subs[index].f.delivery = ast_tv(0,0);
04632    p->subs[index].f.src = "zt_read";
04633    p->subs[index].f.data = NULL;
04634    
04635    /* make sure it sends initial key state as first frame */
04636    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04637    {
04638       ZT_PARAMS ps;
04639 
04640       ps.channo = p->channel;
04641       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04642          ast_mutex_unlock(&p->lock);
04643          return NULL;
04644       }
04645       p->firstradio = 1;
04646       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04647       if (ps.rxisoffhook)
04648       {
04649          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04650       }
04651       else
04652       {
04653          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04654       }
04655       ast_mutex_unlock(&p->lock);
04656       return &p->subs[index].f;
04657    }
04658    if (p->ringt == 1) {
04659       ast_mutex_unlock(&p->lock);
04660       return NULL;
04661    }
04662    else if (p->ringt > 0) 
04663       p->ringt--;
04664 
04665    if (p->subs[index].needringing) {
04666       /* Send ringing frame if requested */
04667       p->subs[index].needringing = 0;
04668       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04669       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04670       ast_setstate(ast, AST_STATE_RINGING);
04671       ast_mutex_unlock(&p->lock);
04672       return &p->subs[index].f;
04673    }
04674 
04675    if (p->subs[index].needbusy) {
04676       /* Send busy frame if requested */
04677       p->subs[index].needbusy = 0;
04678       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04679       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04680       ast_mutex_unlock(&p->lock);
04681       return &p->subs[index].f;
04682    }
04683 
04684    if (p->subs[index].needcongestion) {
04685       /* Send congestion frame if requested */
04686       p->subs[index].needcongestion = 0;
04687       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04688       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04689       ast_mutex_unlock(&p->lock);
04690       return &p->subs[index].f;
04691    }
04692 
04693    if (p->subs[index].needcallerid) {
04694       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04695                      S_OR(p->lastcid_name, NULL),
04696                      S_OR(p->lastcid_num, NULL)
04697                      );
04698       p->subs[index].needcallerid = 0;
04699    }
04700    
04701    if (p->subs[index].needanswer) {
04702       /* Send answer frame if requested */
04703       p->subs[index].needanswer = 0;
04704       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04705       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04706       ast_mutex_unlock(&p->lock);
04707       return &p->subs[index].f;
04708    }  
04709    
04710    if (p->subs[index].needflash) {
04711       /* Send answer frame if requested */
04712       p->subs[index].needflash = 0;
04713       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04714       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04715       ast_mutex_unlock(&p->lock);
04716       return &p->subs[index].f;
04717    }  
04718    
04719    if (p->subs[index].needhold) {
04720       /* Send answer frame if requested */
04721       p->subs[index].needhold = 0;
04722       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04723       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04724       ast_mutex_unlock(&p->lock);
04725       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04726       return &p->subs[index].f;
04727    }  
04728    
04729    if (p->subs[index].needunhold) {
04730       /* Send answer frame if requested */
04731       p->subs[index].needunhold = 0;
04732       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04733       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04734       ast_mutex_unlock(&p->lock);
04735       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04736       return &p->subs[index].f;
04737    }  
04738    
04739    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04740       if (!p->subs[index].linear) {
04741          p->subs[index].linear = 1;
04742          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04743          if (res) 
04744             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04745       }
04746    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04747          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04748       if (p->subs[index].linear) {
04749          p->subs[index].linear = 0;
04750          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04751          if (res) 
04752             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04753       }
04754    } else {
04755       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04756       ast_mutex_unlock(&p->lock);
04757       return NULL;
04758    }
04759    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04760    CHECK_BLOCKING(ast);
04761    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04762    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04763    /* Check for hangup */
04764    if (res < 0) {
04765       f = NULL;
04766       if (res == -1)  {
04767          if (errno == EAGAIN) {
04768             /* Return "NULL" frame if there is nobody there */
04769             ast_mutex_unlock(&p->lock);
04770             return &p->subs[index].f;
04771          } else if (errno == ELAST) {
04772             f = __zt_exception(ast);
04773          } else
04774             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04775       }
04776       ast_mutex_unlock(&p->lock);
04777       return f;
04778    }
04779    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04780       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04781       f = __zt_exception(ast);
04782       ast_mutex_unlock(&p->lock);
04783       return f;
04784    }
04785    if (p->tdd) { /* if in TDD mode, see if we receive that */
04786       int c;
04787 
04788       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04789       if (c < 0) {
04790          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04791          ast_mutex_unlock(&p->lock);
04792          return NULL;
04793       }
04794       if (c) { /* if a char to return */
04795          p->subs[index].f.subclass = 0;
04796          p->subs[index].f.frametype = AST_FRAME_TEXT;
04797          p->subs[index].f.mallocd = 0;
04798          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04799          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04800          p->subs[index].f.datalen = 1;
04801          *((char *) p->subs[index].f.data) = c;
04802          ast_mutex_unlock(&p->lock);
04803          return &p->subs[index].f;
04804       }
04805    }
04806    if (p->callwaitingrepeat)
04807       p->callwaitingrepeat--;
04808    if (p->cidcwexpire)
04809       p->cidcwexpire--;
04810    /* Repeat callwaiting */
04811    if (p->callwaitingrepeat == 1) {
04812       p->callwaitrings++;
04813       zt_callwait(ast);
04814    }
04815    /* Expire CID/CW */
04816    if (p->cidcwexpire == 1) {
04817       if (option_verbose > 2)
04818          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04819       restore_conference(p);
04820    }
04821    if (p->subs[index].linear) {
04822       p->subs[index].f.datalen = READ_SIZE * 2;
04823    } else 
04824       p->subs[index].f.datalen = READ_SIZE;
04825 
04826    /* Handle CallerID Transmission */
04827    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04828       send_callerid(p);
04829    }
04830 
04831    p->subs[index].f.frametype = AST_FRAME_VOICE;
04832    p->subs[index].f.subclass = ast->rawreadformat;
04833    p->subs[index].f.samples = READ_SIZE;
04834    p->subs[index].f.mallocd = 0;
04835    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04836    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
04837 #if 0
04838    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04839 #endif   
04840    if (p->dialing || /* Transmitting something */
04841       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04842       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04843       ) {
04844       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04845          don't send anything */
04846       p->subs[index].f.frametype = AST_FRAME_NULL;
04847       p->subs[index].f.subclass = 0;
04848       p->subs[index].f.samples = 0;
04849       p->subs[index].f.mallocd = 0;
04850       p->subs[index].f.offset = 0;
04851       p->subs[index].f.data = NULL;
04852       p->subs[index].f.datalen= 0;
04853    }
04854    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04855       /* Perform busy detection. etc on the zap line */
04856       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04857       if (f) {
04858          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04859             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04860                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04861                   a busy  */
04862                f = NULL;
04863             }
04864          } else if (f->frametype == AST_FRAME_DTMF) {
04865 #ifdef HAVE_PRI
04866             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04867                /* Don't accept in-band DTMF when in overlap dial mode */
04868                f->frametype = AST_FRAME_NULL;
04869                f->subclass = 0;
04870             }
04871 #endif            
04872             /* DSP clears us of being pulse */
04873             p->pulsedial = 0;
04874          }
04875       }
04876    } else 
04877       f = &p->subs[index].f; 
04878 
04879    if (f && (f->frametype == AST_FRAME_DTMF))
04880       zt_handle_dtmfup(ast, index, &f);
04881 
04882    /* If we have a fake_event, trigger exception to handle it */
04883    if (p->fake_event)
04884       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04885 
04886    ast_mutex_unlock(&p->lock);
04887    return f;
04888 }
04889 
04890 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
04891 {
04892    int sent=0;
04893    int size;
04894    int res;
04895    int fd;
04896    fd = p->subs[index].zfd;
04897    while (len) {
04898       size = len;
04899       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04900          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04901       res = write(fd, buf, size);
04902       if (res != size) {
04903          if (option_debug)
04904             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04905          return sent;
04906       }
04907       len -= size;
04908       buf += size;
04909    }
04910    return sent;
04911 }
04912 
04913 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
04914 {
04915    struct zt_pvt *p = ast->tech_pvt;
04916    int res;
04917    unsigned char outbuf[4096];
04918    int index;
04919    index = zt_get_index(ast, p, 0);
04920    if (index < 0) {
04921       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04922       return -1;
04923    }
04924 
04925 #if 0
04926 #ifdef HAVE_PRI
04927    ast_mutex_lock(&p->lock);
04928    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04929       if (p->pri->pri) {      
04930          if (!pri_grab(p, p->pri)) {
04931                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04932                pri_rel(p->pri);
04933          } else
04934                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04935       }
04936       p->proceeding=1;
04937    }
04938    ast_mutex_unlock(&p->lock);
04939 #endif
04940 #endif
04941    /* Write a frame of (presumably voice) data */
04942    if (frame->frametype != AST_FRAME_VOICE) {
04943       if (frame->frametype != AST_FRAME_IMAGE)
04944          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04945       return 0;
04946    }
04947    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04948        (frame->subclass != AST_FORMAT_ULAW) &&
04949        (frame->subclass != AST_FORMAT_ALAW)) {
04950       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04951       return -1;
04952    }
04953    if (p->dialing) {
04954       if (option_debug)
04955          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
04956       return 0;
04957    }
04958    if (!p->owner) {
04959       if (option_debug)
04960          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
04961       return 0;
04962    }
04963    if (p->cidspill) {
04964       if (option_debug)
04965          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
04966       return 0;
04967    }
04968    /* Return if it's not valid data */
04969    if (!frame->data || !frame->datalen)
04970       return 0;
04971    if (frame->datalen > sizeof(outbuf) * 2) {
04972       ast_log(LOG_WARNING, "Frame too large\n");
04973       return 0;
04974    }
04975 
04976    if (frame->subclass == AST_FORMAT_SLINEAR) {
04977       if (!p->subs[index].linear) {
04978          p->subs[index].linear = 1;
04979          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04980          if (res)
04981             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
04982       }
04983       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
04984    } else {
04985       /* x-law already */
04986       if (p->subs[index].linear) {
04987          p->subs[index].linear = 0;
04988          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04989          if (res)
04990             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
04991       }
04992       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
04993    }
04994    if (res < 0) {
04995       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
04996       return -1;
04997    } 
04998    return 0;
04999 }
05000 
05001 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05002 {
05003    struct zt_pvt *p = chan->tech_pvt;
05004    int res=-1;
05005    int index;
05006    int func = ZT_FLASH;
05007    ast_mutex_lock(&p->lock);
05008    index = zt_get_index(chan, p, 0);
05009    if (option_debug)
05010       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05011    if (index == SUB_REAL) {
05012       switch (condition) {
05013       case AST_CONTROL_BUSY:
05014 #ifdef HAVE_PRI
05015          if (p->priindication_oob && p->sig == SIG_PRI) {
05016             chan->hangupcause = AST_CAUSE_USER_BUSY;
05017             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05018             res = 0;
05019          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05020             if (p->pri->pri) {      
05021                if (!pri_grab(p, p->pri)) {
05022                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05023                   pri_rel(p->pri);
05024                }
05025                else
05026                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05027             }
05028             p->progress = 1;
05029             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05030          } else
05031 #endif
05032             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05033          break;
05034       case AST_CONTROL_RINGING:
05035 #ifdef HAVE_PRI
05036          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05037             if (p->pri->pri) {      
05038                if (!pri_grab(p, p->pri)) {
05039                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05040                   pri_rel(p->pri);
05041                }
05042                else
05043                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05044             }
05045             p->alerting = 1;
05046          }
05047 #endif
05048          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05049          if (chan->_state != AST_STATE_UP) {
05050             if ((chan->_state != AST_STATE_RING) ||
05051                ((p->sig != SIG_FXSKS) &&
05052                 (p->sig != SIG_FXSLS) &&
05053                 (p->sig != SIG_FXSGS)))
05054                ast_setstate(chan, AST_STATE_RINGING);
05055          }
05056          break;
05057       case AST_CONTROL_PROCEEDING:
05058          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05059 #ifdef HAVE_PRI
05060          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05061             if (p->pri->pri) {      
05062                if (!pri_grab(p, p->pri)) {
05063                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05064                   pri_rel(p->pri);
05065                }
05066                else
05067                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05068             }
05069             p->proceeding = 1;
05070          }
05071 #endif
05072          /* don't continue in ast_indicate */
05073          res = 0;
05074          break;
05075       case AST_CONTROL_PROGRESS:
05076          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05077 #ifdef HAVE_PRI
05078          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05079          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05080             if (p->pri->pri) {      
05081                if (!pri_grab(p, p->pri)) {
05082                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05083                   pri_rel(p->pri);
05084                }
05085                else
05086                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05087             }
05088             p->progress = 1;
05089          }
05090 #endif
05091          /* don't continue in ast_indicate */
05092          res = 0;
05093          break;
05094       case AST_CONTROL_CONGESTION:
05095          chan->hangupcause = AST_CAUSE_CONGESTION;
05096 #ifdef HAVE_PRI
05097          if (p->priindication_oob && p->sig == SIG_PRI) {
05098             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05099             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05100             res = 0;
05101          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05102             if (p->pri) {     
05103                if (!pri_grab(p, p->pri)) {
05104                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05105                   pri_rel(p->pri);
05106                } else
05107                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05108             }
05109             p->progress = 1;
05110             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05111          } else
05112 #endif
05113             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05114          break;
05115       case AST_CONTROL_HOLD:
05116 #ifdef HAVE_PRI
05117          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05118             if (!pri_grab(p, p->pri)) {
05119                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05120                pri_rel(p->pri);
05121             } else
05122                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05123          } else
05124 #endif
05125             ast_moh_start(chan, data, p->mohinterpret);
05126          break;
05127       case AST_CONTROL_UNHOLD:
05128 #ifdef HAVE_PRI
05129          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05130             if (!pri_grab(p, p->pri)) {
05131                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05132                pri_rel(p->pri);
05133             } else
05134                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05135          } else
05136 #endif
05137             ast_moh_stop(chan);
05138          break;
05139       case AST_CONTROL_RADIO_KEY:
05140          if (p->radio) 
05141              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05142          res = 0;
05143          break;
05144       case AST_CONTROL_RADIO_UNKEY:
05145          if (p->radio)
05146              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05147          res = 0;
05148          break;
05149       case AST_CONTROL_FLASH:
05150          /* flash hookswitch */
05151          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05152             /* Clear out the dial buffer */
05153             p->dop.dialstr[0] = '\0';
05154             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05155                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05156                   chan->name, strerror(errno));
05157             } else
05158                res = 0;
05159          } else
05160             res = 0;
05161          break;
05162       case -1:
05163          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05164          break;
05165       }
05166    } else
05167       res = 0;
05168    ast_mutex_unlock(&p->lock);
05169    return res;
05170 }
05171 
05172 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05173 {
05174    struct ast_channel *tmp;
05175    int deflaw;
05176    int res;
05177    int x,y;
05178    int features;
05179    char *b2 = NULL;
05180    ZT_PARAMS ps;
05181    if (i->subs[index].owner) {
05182       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05183       return NULL;
05184    }
05185    y = 1;
05186    do {
05187       if (b2)
05188          free(b2);
05189 #ifdef HAVE_PRI
05190       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05191          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05192       else
05193 #endif
05194       if (i->channel == CHAN_PSEUDO)
05195          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05196       else  
05197          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05198       for (x = 0; x < 3; x++) {
05199          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05200             break;
05201       }
05202       y++;
05203    } while (x < 3);
05204    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05205    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05206       free(b2);
05207    if (!tmp)
05208       return NULL;
05209    tmp->tech = &zap_tech;
05210    ps.channo = i->channel;
05211    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05212    if (res) {
05213       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05214       ps.curlaw = ZT_LAW_MULAW;
05215    }
05216    if (ps.curlaw == ZT_LAW_ALAW)
05217       deflaw = AST_FORMAT_ALAW;
05218    else
05219       deflaw = AST_FORMAT_ULAW;
05220    if (law) {
05221       if (law == ZT_LAW_ALAW)
05222          deflaw = AST_FORMAT_ALAW;
05223       else
05224          deflaw = AST_FORMAT_ULAW;
05225    }
05226    tmp->fds[0] = i->subs[index].zfd;
05227    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05228    /* Start out assuming ulaw since it's smaller :) */
05229    tmp->rawreadformat = deflaw;
05230    tmp->readformat = deflaw;
05231    tmp->rawwriteformat = deflaw;
05232    tmp->writeformat = deflaw;
05233    i->subs[index].linear = 0;
05234    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05235    features = 0;
05236    if (index == SUB_REAL) {
05237       if (i->busydetect && CANBUSYDETECT(i))
05238          features |= DSP_FEATURE_BUSY_DETECT;
05239       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05240          features |= DSP_FEATURE_CALL_PROGRESS;
05241       if ((!i->outgoing && (i->callprogress & 4)) || 
05242           (i->outgoing && (i->callprogress & 2))) {
05243          features |= DSP_FEATURE_FAX_DETECT;
05244       }
05245 #ifdef ZT_TONEDETECT
05246       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05247       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05248 #endif      
05249          i->hardwaredtmf = 0;
05250          features |= DSP_FEATURE_DTMF_DETECT;
05251 #ifdef ZT_TONEDETECT
05252       } else if (NEED_MFDETECT(i)) {
05253          i->hardwaredtmf = 1;
05254          features |= DSP_FEATURE_DTMF_DETECT;
05255       }
05256 #endif
05257    }
05258    if (features) {
05259       if (i->dsp) {
05260          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05261       } else {
05262          if (i->channel != CHAN_PSEUDO)
05263             i->dsp = ast_dsp_new();
05264          else
05265             i->dsp = NULL;
05266          if (i->dsp) {
05267             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05268 #ifdef HAVE_PRI
05269             /* We cannot do progress detection until receives PROGRESS message */
05270             if (i->outgoing && (i->sig == SIG_PRI)) {
05271                /* Remember requested DSP features, don't treat
05272                   talking as ANSWER */
05273                features = 0;
05274             }
05275 #endif
05276             ast_dsp_set_features(i->dsp, features);
05277             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05278             if (!ast_strlen_zero(progzone))
05279                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05280             if (i->busydetect && CANBUSYDETECT(i)) {
05281                ast_dsp_set_busy_count(i->dsp, i->busycount);
05282                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05283             }
05284          }
05285       }
05286    }
05287       
05288    if (state == AST_STATE_RING)
05289       tmp->rings = 1;
05290    tmp->tech_pvt = i;
05291    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05292       /* Only FXO signalled stuff can be picked up */
05293       tmp->callgroup = i->callgroup;
05294       tmp->pickupgroup = i->pickupgroup;
05295    }
05296    if (!ast_strlen_zero(i->language))
05297       ast_string_field_set(tmp, language, i->language);
05298    if (!i->owner)
05299       i->owner = tmp;
05300    if (!ast_strlen_zero(i->accountcode))
05301       ast_string_field_set(tmp, accountcode, i->accountcode);
05302    if (i->amaflags)
05303       tmp->amaflags = i->amaflags;
05304    i->subs[index].owner = tmp;
05305    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05306    ast_string_field_set(tmp, call_forward, i->call_forward);
05307    /* If we've been told "no ADSI" then enforce it */
05308    if (!i->adsi)
05309       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05310    if (!ast_strlen_zero(i->exten))
05311       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05312    if (!ast_strlen_zero(i->rdnis))
05313       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05314    if (!ast_strlen_zero(i->dnid))
05315       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05316 
05317    /* Don't use ast_set_callerid() here because it will
05318     * generate a needless NewCallerID event */
05319 #ifdef PRI_ANI
05320    tmp->cid.cid_num = ast_strdup(i->cid_num);
05321    tmp->cid.cid_name = ast_strdup(i->cid_name);
05322    if (!ast_strlen_zero(i->cid_ani))
05323       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05324    else  
05325       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05326 #else
05327    tmp->cid.cid_num = ast_strdup(i->cid_num);
05328    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05329    tmp->cid.cid_name = ast_strdup(i->cid_name);
05330 #endif
05331    tmp->cid.cid_pres = i->callingpres;
05332    tmp->cid.cid_ton = i->cid_ton;
05333 #ifdef HAVE_PRI
05334    tmp->transfercapability = transfercapability;
05335    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05336    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05337       i->digital = 1;
05338    /* Assume calls are not idle calls unless we're told differently */
05339    i->isidlecall = 0;
05340    i->alreadyhungup = 0;
05341 #endif
05342    /* clear the fake event in case we posted one before we had ast_channel */
05343    i->fake_event = 0;
05344    /* Assure there is no confmute on this channel */
05345    zt_confmute(i, 0);
05346    /* Configure the new channel jb */
05347    ast_jb_configure(tmp, &global_jbconf);
05348    if (startpbx) {
05349       if (ast_pbx_start(tmp)) {
05350          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05351          ast_hangup(tmp);
05352          i->owner = NULL;
05353          return NULL;
05354       }
05355    }
05356 
05357    ast_module_ref(ast_module_info->self);
05358    
05359    return tmp;
05360 }
05361 
05362 
05363 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05364 {
05365    char c;
05366 
05367    *str = 0; /* start with empty output buffer */
05368    for (;;)
05369    {
05370       /* Wait for the first digit (up to specified ms). */
05371       c = ast_waitfordigit(chan, ms);
05372       /* if timeout, hangup or error, return as such */
05373       if (c < 1)
05374          return c;
05375       *str++ = c;
05376       *str = 0;
05377       if (strchr(term, c))
05378          return 1;
05379    }
05380 }
05381 
05382 static int zt_wink(struct zt_pvt *p, int index)
05383 {
05384    int j;
05385    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05386    for (;;)
05387    {
05388          /* set bits of interest */
05389       j = ZT_IOMUX_SIGEVENT;
05390           /* wait for some happening */
05391       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05392          /* exit loop if we have it */
05393       if (j & ZT_IOMUX_SIGEVENT) break;
05394    }
05395      /* get the event info */
05396    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05397    return 0;
05398 }
05399 
05400 static void *ss_thread(void *data)
05401 {
05402    struct ast_channel *chan = data;
05403    struct zt_pvt *p = chan->tech_pvt;
05404    char exten[AST_MAX_EXTENSION] = "";
05405    char exten2[AST_MAX_EXTENSION] = "";
05406    unsigned char buf[256];
05407    char dtmfcid[300];
05408    char dtmfbuf[300];
05409    struct callerid_state *cs = NULL;
05410    char *name = NULL, *number = NULL;
05411    int distMatches;
05412    int curRingData[3];
05413    int receivedRingT;
05414    int counter1;
05415    int counter;
05416    int samples = 0;
05417    struct ast_smdi_md_message *smdi_msg = NULL;
05418    int flags;
05419    int i;
05420    int timeout;
05421    int getforward = 0;
05422    char *s1, *s2;
05423    int len = 0;
05424    int res;
05425    int index;
05426 
05427    /* in the bizarre case where the channel has become a zombie before we
05428       even get started here, abort safely
05429    */
05430    if (!p) {
05431       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05432       ast_hangup(chan);
05433       return NULL;
05434    }
05435 
05436    if (option_verbose > 2) 
05437       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05438    index = zt_get_index(chan, p, 1);
05439    if (index < 0) {
05440       ast_log(LOG_WARNING, "Huh?\n");
05441       ast_hangup(chan);
05442       return NULL;
05443    }
05444    if (p->dsp)
05445       ast_dsp_digitreset(p->dsp);
05446    switch (p->sig) {
05447 #ifdef HAVE_PRI
05448    case SIG_PRI:
05449       /* Now loop looking for an extension */
05450       ast_copy_string(exten, p->exten, sizeof(exten));
05451       len = strlen(exten);
05452       res = 0;
05453       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05454          if (len && !ast_ignore_pattern(chan->context, exten))
05455             tone_zone_play_tone(p->subs[index].zfd, -1);
05456          else
05457             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05458          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05459             timeout = matchdigittimeout;
05460          else
05461             timeout = gendigittimeout;
05462          res = ast_waitfordigit(chan, timeout);
05463          if (res < 0) {
05464             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05465             ast_hangup(chan);
05466             return NULL;
05467          } else if (res) {
05468             exten[len++] = res;
05469             exten[len] = '\0';
05470          } else
05471             break;
05472       }
05473       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05474       if (ast_strlen_zero(exten)) {
05475          if (option_verbose > 2)
05476             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05477          exten[0] = 's';
05478          exten[1] = '\0';
05479       }
05480       tone_zone_play_tone(p->subs[index].zfd, -1);
05481       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05482          /* Start the real PBX */
05483          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05484          if (p->dsp) ast_dsp_digitreset(p->dsp);
05485          zt_enable_ec(p);
05486          ast_setstate(chan, AST_STATE_RING);
05487          res = ast_pbx_run(chan);
05488          if (res) {
05489             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05490          }
05491       } else {
05492          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05493          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05494          ast_hangup(chan);
05495          p->exten[0] = '\0';
05496          /* Since we send release complete here, we won't get one */
05497          p->call = NULL;
05498       }
05499       return NULL;
05500       break;
05501 #endif
05502    case SIG_FEATD:
05503    case SIG_FEATDMF:
05504    case SIG_FEATDMF_TA:
05505    case SIG_E911:
05506    case SIG_FGC_CAMAMF:
05507    case SIG_FEATB:
05508    case SIG_EMWINK:
05509    case SIG_SF_FEATD:
05510    case SIG_SF_FEATDMF:
05511    case SIG_SF_FEATB:
05512    case SIG_SFWINK:
05513       if (zt_wink(p, index))  
05514          return NULL;
05515       /* Fall through */
05516    case SIG_EM:
05517    case SIG_EM_E1:
05518    case SIG_SF:
05519    case SIG_FGC_CAMA:
05520       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05521       if (p->dsp)
05522          ast_dsp_digitreset(p->dsp);
05523       /* set digit mode appropriately */
05524       if (p->dsp) {
05525          if (NEED_MFDETECT(p))
05526             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05527          else 
05528             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05529       }
05530       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05531       /* Wait for the first digit only if immediate=no */
05532       if (!p->immediate)
05533          /* Wait for the first digit (up to 5 seconds). */
05534          res = ast_waitfordigit(chan, 5000);
05535       else
05536          res = 0;
05537       if (res > 0) {
05538          /* save first char */
05539          dtmfbuf[0] = res;
05540          switch (p->sig) {
05541          case SIG_FEATD:
05542          case SIG_SF_FEATD:
05543             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05544             if (res > 0)
05545                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05546             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05547             break;
05548          case SIG_FEATDMF_TA:
05549             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05550             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05551             if (zt_wink(p, index)) return NULL;
05552             dtmfbuf[0] = 0;
05553             /* Wait for the first digit (up to 5 seconds). */
05554             res = ast_waitfordigit(chan, 5000);
05555             if (res <= 0) break;
05556             dtmfbuf[0] = res;
05557             /* fall through intentionally */
05558          case SIG_FEATDMF:
05559          case SIG_E911:
05560          case SIG_FGC_CAMAMF:
05561          case SIG_SF_FEATDMF:
05562             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05563             /* if international caca, do it again to get real ANO */
05564             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05565             {
05566                if (zt_wink(p, index)) return NULL;
05567                dtmfbuf[0] = 0;
05568                /* Wait for the first digit (up to 5 seconds). */
05569                res = ast_waitfordigit(chan, 5000);
05570                if (res <= 0) break;
05571                dtmfbuf[0] = res;
05572                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05573             }
05574             if (res > 0) {
05575                /* if E911, take off hook */
05576                if (p->sig == SIG_E911)
05577                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05578                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05579             }
05580             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05581             break;
05582          case SIG_FEATB:
05583          case SIG_SF_FEATB:
05584             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05585             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05586             break;
05587          case SIG_EMWINK:
05588             /* if we received a '*', we are actually receiving Feature Group D
05589                dial syntax, so use that mode; otherwise, fall through to normal
05590                mode
05591             */
05592             if (res == '*') {
05593                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05594                if (res > 0)
05595                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05596                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05597                break;
05598             }
05599          default:
05600             /* If we got the first digit, get the rest */
05601             len = 1;
05602             dtmfbuf[len] = '\0';
05603             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05604                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05605                   timeout = matchdigittimeout;
05606                } else {
05607                   timeout = gendigittimeout;
05608                }
05609                res = ast_waitfordigit(chan, timeout);
05610                if (res < 0) {
05611                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05612                   ast_hangup(chan);
05613                   return NULL;
05614                } else if (res) {
05615                   dtmfbuf[len++] = res;
05616                   dtmfbuf[len] = '\0';
05617                } else {
05618                   break;
05619                }
05620             }
05621             break;
05622          }
05623       }
05624       if (res == -1) {
05625          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05626          ast_hangup(chan);
05627          return NULL;
05628       } else if (res < 0) {
05629          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05630          ast_hangup(chan);
05631          return NULL;
05632       }
05633 
05634       if (p->sig == SIG_FGC_CAMA) {
05635          char anibuf[100];
05636 
05637          if (ast_safe_sleep(chan,1000) == -1) {
05638                            ast_hangup(chan);
05639                            return NULL;
05640          }
05641                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05642                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05643                         res = my_getsigstr(chan, anibuf, "#", 10000);
05644                         if ((res > 0) && (strlen(anibuf) > 2)) {
05645             if (anibuf[strlen(anibuf) - 1] == '#')
05646                anibuf[strlen(anibuf) - 1] = 0;
05647             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05648          }
05649                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05650       }
05651 
05652       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05653       if (ast_strlen_zero(exten))
05654          ast_copy_string(exten, "s", sizeof(exten));
05655       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05656          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05657          if (exten[0] == '*') {
05658             char *stringp=NULL;
05659             ast_copy_string(exten2, exten, sizeof(exten2));
05660             /* Parse out extension and callerid */
05661             stringp=exten2 +1;
05662             s1 = strsep(&stringp, "*");
05663             s2 = strsep(&stringp, "*");
05664             if (s2) {
05665                if (!ast_strlen_zero(p->cid_num))
05666                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05667                else
05668                   ast_set_callerid(chan, s1, NULL, s1);
05669                ast_copy_string(exten, s2, sizeof(exten));
05670             } else
05671                ast_copy_string(exten, s1, sizeof(exten));
05672          } else if (p->sig == SIG_FEATD)
05673             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05674       }
05675       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05676          if (exten[0] == '*') {
05677             char *stringp=NULL;
05678             ast_copy_string(exten2, exten, sizeof(exten2));
05679             /* Parse out extension and callerid */
05680             stringp=exten2 +1;
05681             s1 = strsep(&stringp, "#");
05682             s2 = strsep(&stringp, "#");
05683             if (s2) {
05684                if (!ast_strlen_zero(p->cid_num))
05685                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05686                else
05687                   if (*(s1 + 2))
05688                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05689                ast_copy_string(exten, s2 + 1, sizeof(exten));
05690             } else
05691                ast_copy_string(exten, s1 + 2, sizeof(exten));
05692          } else
05693             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05694       }
05695       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05696          if (exten[0] == '*') {
05697             char *stringp=NULL;
05698             ast_copy_string(exten2, exten, sizeof(exten2));
05699             /* Parse out extension and callerid */
05700             stringp=exten2 +1;
05701             s1 = strsep(&stringp, "#");
05702             s2 = strsep(&stringp, "#");
05703             if (s2 && (*(s2 + 1) == '0')) {
05704                if (*(s2 + 2))
05705                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05706             }
05707             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05708             else ast_copy_string(exten, "911", sizeof(exten));
05709          } else
05710             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05711       }
05712       if (p->sig == SIG_FEATB) {
05713          if (exten[0] == '*') {
05714             char *stringp=NULL;
05715             ast_copy_string(exten2, exten, sizeof(exten2));
05716             /* Parse out extension and callerid */
05717             stringp=exten2 +1;
05718             s1 = strsep(&stringp, "#");
05719             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05720          } else
05721             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05722       }
05723       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05724          zt_wink(p, index);
05725                         /* some switches require a minimum guard time between
05726                            the last FGD wink and something that answers
05727                            immediately. This ensures it */
05728                         if (ast_safe_sleep(chan,100)) return NULL;
05729       }
05730       zt_enable_ec(p);
05731       if (NEED_MFDETECT(p)) {
05732          if (p->dsp) {
05733             if (!p->hardwaredtmf)
05734                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05735             else {
05736                ast_dsp_free(p->dsp);
05737                p->dsp = NULL;
05738             }
05739          }
05740       }
05741 
05742       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05743          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05744          if (p->dsp) ast_dsp_digitreset(p->dsp);
05745          res = ast_pbx_run(chan);
05746          if (res) {
05747             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05748             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05749          }
05750          return NULL;
05751       } else {
05752          if (option_verbose > 2)
05753             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05754          sleep(2);
05755          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05756          if (res < 0)
05757             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05758          else
05759             sleep(1);
05760          res = ast_streamfile(chan, "ss-noservice", chan->language);
05761          if (res >= 0)
05762             ast_waitstream(chan, "");
05763          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05764          ast_hangup(chan);
05765          return NULL;
05766       }
05767       break;
05768    case SIG_FXOLS:
05769    case SIG_FXOGS:
05770    case SIG_FXOKS:
05771       /* Read the first digit */
05772       timeout = firstdigittimeout;
05773       /* If starting a threeway call, never timeout on the first digit so someone
05774          can use flash-hook as a "hold" feature */
05775       if (p->subs[SUB_THREEWAY].owner) 
05776          timeout = 999999;
05777       while (len < AST_MAX_EXTENSION-1) {
05778          /* Read digit unless it's supposed to be immediate, in which case the
05779             only answer is 's' */
05780          if (p->immediate) 
05781             res = 's';
05782          else
05783             res = ast_waitfordigit(chan, timeout);
05784          timeout = 0;
05785          if (res < 0) {
05786             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05787             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05788             ast_hangup(chan);
05789             return NULL;
05790          } else if (res)  {
05791             exten[len++]=res;
05792             exten[len] = '\0';
05793          }
05794          if (!ast_ignore_pattern(chan->context, exten))
05795             tone_zone_play_tone(p->subs[index].zfd, -1);
05796          else
05797             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05798          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05799             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05800                if (getforward) {
05801                   /* Record this as the forwarding extension */
05802                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05803                   if (option_verbose > 2)
05804                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05805                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05806                   if (res)
05807                      break;
05808                   usleep(500000);
05809                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05810                   sleep(1);
05811                   memset(exten, 0, sizeof(exten));
05812                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05813                   len = 0;
05814                   getforward = 0;
05815                } else  {
05816                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05817                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05818                   if (!ast_strlen_zero(p->cid_num)) {
05819                      if (!p->hidecallerid)
05820                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05821                      else
05822                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05823                   }
05824                   if (!ast_strlen_zero(p->cid_name)) {
05825                      if (!p->hidecallerid)
05826                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05827                   }
05828                   ast_setstate(chan, AST_STATE_RING);
05829                   zt_enable_ec(p);
05830                   res = ast_pbx_run(chan);
05831                   if (res) {
05832                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05833                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05834                   }
05835                   return NULL;
05836                }
05837             } else {
05838                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05839                   so just set the timeout to matchdigittimeout and wait some more */
05840                timeout = matchdigittimeout;
05841             }
05842          } else if (res == 0) {
05843             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05844             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05845             zt_wait_event(p->subs[index].zfd);
05846             ast_hangup(chan);
05847             return NULL;
05848          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05849             if (option_verbose > 2) 
05850                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05851             /* Disable call waiting if enabled */
05852             p->callwaiting = 0;
05853             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05854             if (res) {
05855                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05856                   chan->name, strerror(errno));
05857             }
05858             len = 0;
05859             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05860             memset(exten, 0, sizeof(exten));
05861             timeout = firstdigittimeout;
05862                
05863          } else if (!strcmp(exten,ast_pickup_ext())) {
05864             /* Scan all channels and see if any there
05865              * ringing channqels with that have call groups
05866              * that equal this channels pickup group  
05867              */
05868             if (index == SUB_REAL) {
05869                /* Switch us from Third call to Call Wait */
05870                if (p->subs[SUB_THREEWAY].owner) {
05871                   /* If you make a threeway call and the *8# a call, it should actually 
05872                      look like a callwait */
05873                   alloc_sub(p, SUB_CALLWAIT);   
05874                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05875                   unalloc_sub(p, SUB_THREEWAY);
05876                }
05877                zt_enable_ec(p);
05878                if (ast_pickup_call(chan)) {
05879                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05880                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05881                   zt_wait_event(p->subs[index].zfd);
05882                }
05883                ast_hangup(chan);
05884                return NULL;
05885             } else {
05886                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05887                ast_hangup(chan);
05888                return NULL;
05889             }
05890             
05891          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05892             if (option_verbose > 2) 
05893                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05894             /* Disable Caller*ID if enabled */
05895             p->hidecallerid = 1;
05896             if (chan->cid.cid_num)
05897                free(chan->cid.cid_num);
05898             chan->cid.cid_num = NULL;
05899             if (chan->cid.cid_name)
05900                free(chan->cid.cid_name);
05901             chan->cid.cid_name = NULL;
05902             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05903             if (res) {
05904                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05905                   chan->name, strerror(errno));
05906             }
05907             len = 0;
05908             memset(exten, 0, sizeof(exten));
05909             timeout = firstdigittimeout;
05910          } else if (p->callreturn && !strcmp(exten, "*69")) {
05911             res = 0;
05912             if (!ast_strlen_zero(p->lastcid_num)) {
05913                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05914             }
05915             if (!res)
05916                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05917             break;
05918          } else if (!strcmp(exten, "*78")) {
05919             /* Do not disturb */
05920             if (option_verbose > 2)
05921                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05922             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05923                      "Channel: Zap/%d\r\n"
05924                      "Status: enabled\r\n", p->channel);
05925             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05926             p->dnd = 1;
05927             getforward = 0;
05928             memset(exten, 0, sizeof(exten));
05929             len = 0;
05930          } else if (!strcmp(exten, "*79")) {
05931             /* Do not disturb */
05932             if (option_verbose > 2)
05933                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05934             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05935                      "Channel: Zap/%d\r\n"
05936                      "Status: disabled\r\n", p->channel);
05937             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05938             p->dnd = 0;
05939             getforward = 0;
05940             memset(exten, 0, sizeof(exten));
05941             len = 0;
05942          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05943             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05944             getforward = 1;
05945             memset(exten, 0, sizeof(exten));
05946             len = 0;
05947          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05948             if (option_verbose > 2)
05949                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05950             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05951             memset(p->call_forward, 0, sizeof(p->call_forward));
05952             getforward = 0;
05953             memset(exten, 0, sizeof(exten));
05954             len = 0;
05955          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
05956                   p->subs[SUB_THREEWAY].owner &&
05957                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05958             /* This is a three way call, the main call being a real channel, 
05959                and we're parking the first call. */
05960             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
05961             if (option_verbose > 2)
05962                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
05963             break;
05964          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
05965             if (option_verbose > 2)
05966                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
05967             res = ast_db_put("blacklist", p->lastcid_num, "1");
05968             if (!res) {
05969                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05970                memset(exten, 0, sizeof(exten));
05971                len = 0;
05972             }
05973          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
05974             if (option_verbose > 2) 
05975                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
05976             /* Enable Caller*ID if enabled */
05977             p->hidecallerid = 0;
05978             if (chan->cid.cid_num)
05979                free(chan->cid.cid_num);
05980             chan->cid.cid_num = NULL;
05981             if (chan->cid.cid_name)
05982                free(chan->cid.cid_name);
05983             chan->cid.cid_name = NULL;
05984             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
05985             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05986             if (res) {
05987                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05988                   chan->name, strerror(errno));
05989             }
05990             len = 0;
05991             memset(exten, 0, sizeof(exten));
05992             timeout = firstdigittimeout;
05993          } else if (!strcmp(exten, "*0")) {
05994             struct ast_channel *nbridge = 
05995                p->subs[SUB_THREEWAY].owner;
05996             struct zt_pvt *pbridge = NULL;
05997               /* set up the private struct of the bridged one, if any */
05998             if (nbridge && ast_bridged_channel(nbridge)) 
05999                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06000             if (nbridge && pbridge && 
06001                 (nbridge->tech == &zap_tech) && 
06002                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06003                 ISTRUNK(pbridge)) {
06004                int func = ZT_FLASH;
06005                /* Clear out the dial buffer */
06006                p->dop.dialstr[0] = '\0';
06007                /* flash hookswitch */
06008                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06009                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06010                      nbridge->name, strerror(errno));
06011                }
06012                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06013                unalloc_sub(p, SUB_THREEWAY);
06014                p->owner = p->subs[SUB_REAL].owner;
06015                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06016                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06017                ast_hangup(chan);
06018                return NULL;
06019             } else {
06020                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06021                zt_wait_event(p->subs[index].zfd);
06022                tone_zone_play_tone(p->subs[index].zfd, -1);
06023                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06024                unalloc_sub(p, SUB_THREEWAY);
06025                p->owner = p->subs[SUB_REAL].owner;
06026                ast_hangup(chan);
06027                return NULL;
06028             }              
06029          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06030                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06031             if (option_debug)
06032                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);
06033             break;
06034          }
06035          if (!timeout)
06036             timeout = gendigittimeout;
06037          if (len && !ast_ignore_pattern(chan->context, exten))
06038             tone_zone_play_tone(p->subs[index].zfd, -1);
06039       }
06040       break;
06041    case SIG_FXSLS:
06042    case SIG_FXSGS:
06043    case SIG_FXSKS:
06044 #ifdef HAVE_PRI
06045       if (p->pri) {
06046          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06047          struct ast_frame *f;
06048          int res;
06049          time_t start;
06050 
06051          time(&start);
06052          ast_setstate(chan, AST_STATE_RING);
06053          while (time(NULL) < start + 3) {
06054             res = ast_waitfor(chan, 1000);
06055             if (res) {
06056                f = ast_read(chan);
06057                if (!f) {
06058                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06059                   ast_hangup(chan);
06060                   return NULL;
06061                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06062                   res = 1;
06063                } else
06064                   res = 0;
06065                ast_frfree(f);
06066                if (res) {
06067                   ast_log(LOG_DEBUG, "Got ring!\n");
06068                   res = 0;
06069                   break;
06070                }
06071             }
06072          }
06073       }
06074 #endif
06075       /* check for SMDI messages */
06076       if (p->use_smdi && p->smdi_iface) {
06077          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06078 
06079          if (smdi_msg != NULL) {
06080             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06081 
06082             if (smdi_msg->type == 'B')
06083                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06084             else if (smdi_msg->type == 'N')
06085                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06086 
06087             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06088          } else {
06089             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06090          }
06091       }
06092 
06093       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06094             number = smdi_msg->calling_st;
06095 
06096       /* If we want caller id, we're in a prering state due to a polarity reversal
06097        * and we're set to use a polarity reversal to trigger the start of caller id,
06098        * grab the caller id and wait for ringing to start... */
06099       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06100          /* If set to use DTMF CID signalling, listen for DTMF */
06101          if (p->cid_signalling == CID_SIG_DTMF) {
06102             int i = 0;
06103             cs = NULL;
06104             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06105                "channel %s\n", chan->name);
06106             zt_setlinear(p->subs[index].zfd, 0);
06107             res = 2000;
06108             for (;;) {
06109                struct ast_frame *f;
06110                res = ast_waitfor(chan, res);
06111                if (res <= 0) {
06112                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06113                      "Exiting simple switch\n");
06114                   ast_hangup(chan);
06115                   return NULL;
06116                } 
06117                f = ast_read(chan);
06118                if (f->frametype == AST_FRAME_DTMF) {
06119                   dtmfbuf[i++] = f->subclass;
06120                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06121                   res = 2000;
06122                }
06123                ast_frfree(f);
06124                if (chan->_state == AST_STATE_RING ||
06125                    chan->_state == AST_STATE_RINGING) 
06126                   break; /* Got ring */
06127             }
06128             dtmfbuf[i] = '\0';
06129             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06130             /* Got cid and ring. */
06131             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06132             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06133             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06134                dtmfcid, flags);
06135             /* If first byte is NULL, we have no cid */
06136             if (!ast_strlen_zero(dtmfcid)) 
06137                number = dtmfcid;
06138             else
06139                number = NULL;
06140          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06141          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06142             cs = callerid_new(p->cid_signalling);
06143             if (cs) {
06144                samples = 0;
06145 #if 1
06146                bump_gains(p);
06147 #endif            
06148                /* Take out of linear mode for Caller*ID processing */
06149                zt_setlinear(p->subs[index].zfd, 0);
06150                
06151                /* First we wait and listen for the Caller*ID */
06152                for (;;) {  
06153                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06154                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06155                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06156                      callerid_free(cs);
06157                      ast_hangup(chan);
06158                      return NULL;
06159                   }
06160                   if (i & ZT_IOMUX_SIGEVENT) {
06161                      res = zt_get_event(p->subs[index].zfd);
06162                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06163 
06164                      if (p->cid_signalling == CID_SIG_V23_JP) {
06165 #ifdef ZT_EVENT_RINGBEGIN
06166                         if (res == ZT_EVENT_RINGBEGIN) {
06167                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06168                            usleep(1);
06169                         }
06170 #endif
06171                      } else {
06172                         res = 0;
06173                         break;
06174                      }
06175                   } else if (i & ZT_IOMUX_READ) {
06176                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06177                      if (res < 0) {
06178                         if (errno != ELAST) {
06179                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06180                            callerid_free(cs);
06181                            ast_hangup(chan);
06182                            return NULL;
06183                         }
06184                         break;
06185                      }
06186                      samples += res;
06187 
06188                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06189                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06190                      } else {
06191                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06192                      }
06193 
06194                      if (res < 0) {
06195                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06196                         break;
06197                      } else if (res)
06198                         break;
06199                      else if (samples > (8000 * 10))
06200                         break;
06201                   }
06202                }
06203                if (res == 1) {
06204                   callerid_get(cs, &name, &number, &flags);
06205                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06206                }
06207                if (res < 0) {
06208                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06209                }
06210 
06211                if (p->cid_signalling == CID_SIG_V23_JP) {
06212                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06213                   usleep(1);
06214                   res = 4000;
06215                } else {
06216 
06217                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06218                   res = 2000;
06219                }
06220 
06221                for (;;) {
06222                   struct ast_frame *f;
06223                   res = ast_waitfor(chan, res);
06224                   if (res <= 0) {
06225                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06226                         "Exiting simple switch\n");
06227                      ast_hangup(chan);
06228                      return NULL;
06229                   } 
06230                   f = ast_read(chan);
06231                   ast_frfree(f);
06232                   if (chan->_state == AST_STATE_RING ||
06233                       chan->_state == AST_STATE_RINGING) 
06234                      break; /* Got ring */
06235                }
06236    
06237                /* We must have a ring by now, so, if configured, lets try to listen for
06238                 * distinctive ringing */ 
06239                if (p->usedistinctiveringdetection == 1) {
06240                   len = 0;
06241                   distMatches = 0;
06242                   /* Clear the current ring data array so we dont have old data in it. */
06243                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06244                      curRingData[receivedRingT] = 0;
06245                   receivedRingT = 0;
06246                   counter = 0;
06247                   counter1 = 0;
06248                   /* Check to see if context is what it should be, if not set to be. */
06249                   if (strcmp(p->context,p->defcontext) != 0) {
06250                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06251                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06252                   }
06253       
06254                   for (;;) {  
06255                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06256                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06257                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06258                         callerid_free(cs);
06259                         ast_hangup(chan);
06260                         return NULL;
06261                      }
06262                      if (i & ZT_IOMUX_SIGEVENT) {
06263                         res = zt_get_event(p->subs[index].zfd);
06264                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06265                         res = 0;
06266                         /* Let us detect distinctive ring */
06267       
06268                         curRingData[receivedRingT] = p->ringt;
06269       
06270                         if (p->ringt < p->ringt_base/2)
06271                            break;
06272                         /* Increment the ringT counter so we can match it against
06273                            values in zapata.conf for distinctive ring */
06274                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06275                            break;
06276                      } else if (i & ZT_IOMUX_READ) {
06277                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06278                         if (res < 0) {
06279                            if (errno != ELAST) {
06280                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06281                               callerid_free(cs);
06282                               ast_hangup(chan);
06283                               return NULL;
06284                            }
06285                            break;
06286                         }
06287                         if (p->ringt) 
06288                            p->ringt--;
06289                         if (p->ringt == 1) {
06290                            res = -1;
06291                            break;
06292                         }
06293                      }
06294                   }
06295                   if (option_verbose > 2)
06296                      /* this only shows up if you have n of the dring patterns filled in */
06297                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06298    
06299                   for (counter = 0; counter < 3; counter++) {
06300                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06301                      channel */
06302                      distMatches = 0;
06303                      for (counter1 = 0; counter1 < 3; counter1++) {
06304                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06305                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06306                            distMatches++;
06307                         }
06308                      }
06309                      if (distMatches == 3) {
06310                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06311                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06312                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06313                         if (option_verbose > 2)
06314                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06315                         break;
06316                      }
06317                   }
06318                }
06319                /* Restore linear mode (if appropriate) for Caller*ID processing */
06320                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06321 #if 1
06322                restore_gains(p);
06323 #endif            
06324             } else
06325                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06326          } else {
06327             ast_log(LOG_WARNING, "Channel %s in prering "
06328                "state, but I have nothing to do. "
06329                "Terminating simple switch, should be "
06330                "restarted by the actual ring.\n", 
06331                chan->name);
06332             ast_hangup(chan);
06333             return NULL;
06334          }
06335       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06336          /* FSK Bell202 callerID */
06337          cs = callerid_new(p->cid_signalling);
06338          if (cs) {
06339 #if 1
06340             bump_gains(p);
06341 #endif            
06342             samples = 0;
06343             len = 0;
06344             distMatches = 0;
06345             /* Clear the current ring data array so we dont have old data in it. */
06346             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06347                curRingData[receivedRingT] = 0;
06348             receivedRingT = 0;
06349             counter = 0;
06350             counter1 = 0;
06351             /* Check to see if context is what it should be, if not set to be. */
06352             if (strcmp(p->context,p->defcontext) != 0) {
06353                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06354                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06355             }
06356 
06357             /* Take out of linear mode for Caller*ID processing */
06358             zt_setlinear(p->subs[index].zfd, 0);
06359             for (;;) {  
06360                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06361                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06362                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06363                   callerid_free(cs);
06364                   ast_hangup(chan);
06365                   return NULL;
06366                }
06367                if (i & ZT_IOMUX_SIGEVENT) {
06368                   res = zt_get_event(p->subs[index].zfd);
06369                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06370                   res = 0;
06371                   /* Let us detect callerid when the telco uses distinctive ring */
06372 
06373                   curRingData[receivedRingT] = p->ringt;
06374 
06375                   if (p->ringt < p->ringt_base/2)
06376                      break;
06377                   /* Increment the ringT counter so we can match it against
06378                      values in zapata.conf for distinctive ring */
06379                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06380                      break;
06381                } else if (i & ZT_IOMUX_READ) {
06382                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06383                   if (res < 0) {
06384                      if (errno != ELAST) {
06385                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06386                         callerid_free(cs);
06387                         ast_hangup(chan);
06388                         return NULL;
06389                      }
06390                      break;
06391                   }
06392                   if (p->ringt) 
06393                      p->ringt--;
06394                   if (p->ringt == 1) {
06395                      res = -1;
06396                      break;
06397                   }
06398                   samples += res;
06399                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06400                   if (res < 0) {
06401                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06402                      break;
06403                   } else if (res)
06404                      break;
06405                   else if (samples > (8000 * 10))
06406                      break;
06407                }
06408             }
06409             if (res == 1) {
06410                callerid_get(cs, &name, &number, &flags);
06411                if (option_debug)
06412                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06413             }
06414             if (distinctiveringaftercid == 1) {
06415                /* Clear the current ring data array so we dont have old data in it. */
06416                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06417                   curRingData[receivedRingT] = 0;
06418                }
06419                receivedRingT = 0;
06420                if (option_verbose > 2)
06421                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06422                for (;;) {
06423                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06424                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06425                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06426                      callerid_free(cs);
06427                      ast_hangup(chan);
06428                      return NULL;
06429                   }
06430                   if (i & ZT_IOMUX_SIGEVENT) {
06431                      res = zt_get_event(p->subs[index].zfd);
06432                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06433                      res = 0;
06434                      /* Let us detect callerid when the telco uses distinctive ring */
06435 
06436                      curRingData[receivedRingT] = p->ringt;
06437 
06438                      if (p->ringt < p->ringt_base/2)
06439                         break;
06440                      /* Increment the ringT counter so we can match it against
06441                         values in zapata.conf for distinctive ring */
06442                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06443                         break;
06444                   } else if (i & ZT_IOMUX_READ) {
06445                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06446                      if (res < 0) {
06447                         if (errno != ELAST) {
06448                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06449                            callerid_free(cs);
06450                            ast_hangup(chan);
06451                            return NULL;
06452                         }
06453                         break;
06454                      }
06455                   if (p->ringt)
06456                      p->ringt--;
06457                      if (p->ringt == 1) {
06458                         res = -1;
06459                         break;
06460                      }
06461                   }
06462                }
06463             }
06464             if (p->usedistinctiveringdetection == 1) {
06465                if (option_verbose > 2)
06466                   /* this only shows up if you have n of the dring patterns filled in */
06467                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06468 
06469                for (counter = 0; counter < 3; counter++) {
06470                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06471                   channel */
06472                   if (option_verbose > 2)
06473                      /* this only shows up if you have n of the dring patterns filled in */
06474                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06475                         p->drings.ringnum[counter].ring[0],
06476                         p->drings.ringnum[counter].ring[1],
06477                         p->drings.ringnum[counter].ring[2]);
06478                   distMatches = 0;
06479                   for (counter1 = 0; counter1 < 3; counter1++) {
06480                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06481                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06482                         distMatches++;
06483                      }
06484                   }
06485                   if (distMatches == 3) {
06486                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06487                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06488                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06489                      if (option_verbose > 2)
06490                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06491                      break;
06492                   }
06493                }
06494             }
06495             /* Restore linear mode (if appropriate) for Caller*ID processing */
06496             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06497 #if 1
06498             restore_gains(p);
06499 #endif            
06500             if (res < 0) {
06501                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06502             }
06503          } else
06504             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06505       }
06506       else
06507          cs = NULL;
06508 
06509       if (number)
06510          ast_shrink_phone_number(number);
06511       ast_set_callerid(chan, number, name, number);
06512 
06513       if (smdi_msg)
06514          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06515 
06516       if (cs)
06517          callerid_free(cs);
06518 
06519       ast_setstate(chan, AST_STATE_RING);
06520       chan->rings = 1;
06521       p->ringt = p->ringt_base;
06522       res = ast_pbx_run(chan);
06523       if (res) {
06524          ast_hangup(chan);
06525          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06526       }
06527       return NULL;
06528    default:
06529       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06530       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06531       if (res < 0)
06532             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06533    }
06534    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06535    if (res < 0)
06536          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06537    ast_hangup(chan);
06538    return NULL;
06539 }
06540 
06541 /* destroy a zaptel channel, identified by its number */
06542 static int zap_destroy_channel_bynum(int channel)
06543 {
06544    struct zt_pvt *tmp = NULL;
06545    struct zt_pvt *prev = NULL;
06546 
06547    tmp = iflist;
06548    while (tmp) {
06549       if (tmp->channel == channel) {
06550          destroy_channel(prev, tmp, 1);
06551          return RESULT_SUCCESS;
06552       }
06553       prev = tmp;
06554       tmp = tmp->next;
06555    }
06556    return RESULT_FAILURE;
06557 }
06558 
06559 static int handle_init_event(struct zt_pvt *i, int event)
06560 {
06561    int res;
06562    pthread_t threadid;
06563    pthread_attr_t attr;
06564    struct ast_channel *chan;
06565    pthread_attr_init(&attr);
06566    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06567    /* Handle an event on a given channel for the monitor thread. */
06568    switch (event) {
06569    case ZT_EVENT_NONE:
06570    case ZT_EVENT_BITSCHANGED:
06571       break;
06572    case ZT_EVENT_WINKFLASH:
06573    case ZT_EVENT_RINGOFFHOOK:
06574       if (i->inalarm) break;
06575       if (i->radio) break;
06576       /* Got a ring/answer.  What kind of channel are we? */
06577       switch (i->sig) {
06578       case SIG_FXOLS:
06579       case SIG_FXOGS:
06580       case SIG_FXOKS:
06581          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06582          if (res && (errno == EBUSY))
06583             break;
06584          if (i->cidspill) {
06585             /* Cancel VMWI spill */
06586             free(i->cidspill);
06587             i->cidspill = NULL;
06588          }
06589          if (i->immediate) {
06590             zt_enable_ec(i);
06591             /* The channel is immediately up.  Start right away */
06592             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06593             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06594             if (!chan) {
06595                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06596                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06597                if (res < 0)
06598                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06599             }
06600          } else {
06601             /* Check for callerid, digits, etc */
06602             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06603             if (chan) {
06604                if (has_voicemail(i))
06605                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06606                else
06607                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06608                if (res < 0) 
06609                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06610                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06611                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06612                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06613                   if (res < 0)
06614                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06615                   ast_hangup(chan);
06616                }
06617             } else
06618                ast_log(LOG_WARNING, "Unable to create channel\n");
06619          }
06620          break;
06621       case SIG_FXSLS:
06622       case SIG_FXSGS:
06623       case SIG_FXSKS:
06624             i->ringt = i->ringt_base;
06625             /* Fall through */
06626       case SIG_EMWINK:
06627       case SIG_FEATD:
06628       case SIG_FEATDMF:
06629       case SIG_FEATDMF_TA:
06630       case SIG_E911:
06631       case SIG_FGC_CAMA:
06632       case SIG_FGC_CAMAMF:
06633       case SIG_FEATB:
06634       case SIG_EM:
06635       case SIG_EM_E1:
06636       case SIG_SFWINK:
06637       case SIG_SF_FEATD:
06638       case SIG_SF_FEATDMF:
06639       case SIG_SF_FEATB:
06640       case SIG_SF:
06641             /* Check for callerid, digits, etc */
06642             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06643             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06644                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06645                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06646                if (res < 0)
06647                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06648                ast_hangup(chan);
06649             } else if (!chan) {
06650                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06651             }
06652             break;
06653       default:
06654          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06655          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06656          if (res < 0)
06657                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06658          return -1;
06659       }
06660       break;
06661    case ZT_EVENT_NOALARM:
06662       i->inalarm = 0;
06663       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06664       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06665          "Channel: %d\r\n", i->channel);
06666       break;
06667    case ZT_EVENT_ALARM:
06668       i->inalarm = 1;
06669       res = get_alarms(i);
06670       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06671       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06672          "Alarm: %s\r\n"
06673          "Channel: %d\r\n",
06674          alarm2str(res), i->channel);
06675       /* fall thru intentionally */
06676    case ZT_EVENT_ONHOOK:
06677       if (i->radio)
06678          break;
06679       /* Back on hook.  Hang up. */
06680       switch (i->sig) {
06681       case SIG_FXOLS:
06682       case SIG_FXOGS:
06683       case SIG_FEATD:
06684       case SIG_FEATDMF:
06685       case SIG_FEATDMF_TA:
06686       case SIG_E911:
06687       case SIG_FGC_CAMA:
06688       case SIG_FGC_CAMAMF:
06689       case SIG_FEATB:
06690       case SIG_EM:
06691       case SIG_EM_E1:
06692       case SIG_EMWINK:
06693       case SIG_SF_FEATD:
06694       case SIG_SF_FEATDMF:
06695       case SIG_SF_FEATB:
06696       case SIG_SF:
06697       case SIG_SFWINK:
06698       case SIG_FXSLS:
06699       case SIG_FXSGS:
06700       case SIG_FXSKS:
06701       case SIG_GR303FXSKS:
06702          zt_disable_ec(i);
06703          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06704          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06705          break;
06706       case SIG_GR303FXOKS:
06707       case SIG_FXOKS:
06708          zt_disable_ec(i);
06709          /* Diddle the battery for the zhone */
06710 #ifdef ZHONE_HACK
06711          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06712          usleep(1);
06713 #endif         
06714          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06715          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06716          break;
06717       case SIG_PRI:
06718          zt_disable_ec(i);
06719          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06720          break;
06721       default:
06722          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06723          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06724          return -1;
06725       }
06726       break;
06727    case ZT_EVENT_POLARITY:
06728       switch (i->sig) {
06729       case SIG_FXSLS:
06730       case SIG_FXSKS:
06731       case SIG_FXSGS:
06732          if (i->cid_start == CID_START_POLARITY) {
06733             i->polarity = POLARITY_REV;
06734             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06735                    "CID detection on channel %d\n",
06736                    i->channel);
06737             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06738             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06739                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06740             }
06741          }
06742          break;
06743       default:
06744          ast_log(LOG_WARNING, "handle_init_event detected "
06745             "polarity reversal on non-FXO (SIG_FXS) "
06746             "interface %d\n", i->channel);
06747       }
06748       break;
06749    case ZT_EVENT_REMOVED: /* destroy channel */
06750       ast_log(LOG_NOTICE, 
06751             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
06752             i->channel);
06753       zap_destroy_channel_bynum(i->channel);
06754       break;
06755    }
06756    pthread_attr_destroy(&attr);
06757    return 0;
06758 }
06759 
06760 static void *do_monitor(void *data)
06761 {
06762    int count, res, res2, spoint, pollres=0;
06763    struct zt_pvt *i;
06764    struct zt_pvt *last = NULL;
06765    time_t thispass = 0, lastpass = 0;
06766    int found;
06767    char buf[1024];
06768    struct pollfd *pfds=NULL;
06769    int lastalloc = -1;
06770    /* This thread monitors all the frame relay interfaces which are not yet in use
06771       (and thus do not have a separate thread) indefinitely */
06772    /* From here on out, we die whenever asked */
06773 #if 0
06774    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06775       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06776       return NULL;
06777    }
06778    ast_log(LOG_DEBUG, "Monitor starting...\n");
06779 #endif
06780    for (;;) {
06781       /* Lock the interface list */
06782       ast_mutex_lock(&iflock);
06783       if (!pfds || (lastalloc != ifcount)) {
06784          if (pfds)
06785             free(pfds);
06786          if (ifcount) {
06787             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
06788                ast_mutex_unlock(&iflock);
06789                return NULL;
06790             }
06791          }
06792          lastalloc = ifcount;
06793       }
06794       /* Build the stuff we're going to poll on, that is the socket of every
06795          zt_pvt that does not have an associated owner channel */
06796       count = 0;
06797       i = iflist;
06798       while (i) {
06799          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06800             if (!i->owner && !i->subs[SUB_REAL].owner) {
06801                /* This needs to be watched, as it lacks an owner */
06802                pfds[count].fd = i->subs[SUB_REAL].zfd;
06803                pfds[count].events = POLLPRI;
06804                pfds[count].revents = 0;
06805                /* Message waiting or r2 channels also get watched for reading */
06806                if (i->cidspill)
06807                   pfds[count].events |= POLLIN;
06808                count++;
06809             }
06810          }
06811          i = i->next;
06812       }
06813       /* Okay, now that we know what to do, release the interface lock */
06814       ast_mutex_unlock(&iflock);
06815       
06816       pthread_testcancel();
06817       /* Wait at least a second for something to happen */
06818       res = poll(pfds, count, 1000);
06819       pthread_testcancel();
06820       /* Okay, poll has finished.  Let's see what happened.  */
06821       if (res < 0) {
06822          if ((errno != EAGAIN) && (errno != EINTR))
06823             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06824          continue;
06825       }
06826       /* Alright, lock the interface list again, and let's look and see what has
06827          happened */
06828       ast_mutex_lock(&iflock);
06829       found = 0;
06830       spoint = 0;
06831       lastpass = thispass;
06832       thispass = time(NULL);
06833       i = iflist;
06834       while (i) {
06835          if (thispass != lastpass) {
06836             if (!found && ((i == last) || ((i == iflist) && !last))) {
06837                last = i;
06838                if (last) {
06839                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06840                      (last->sig & __ZT_SIG_FXO)) {
06841                      res = ast_app_has_voicemail(last->mailbox, NULL);
06842                      if (last->msgstate != res) {
06843                         int x;
06844                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06845                         x = ZT_FLUSH_BOTH;
06846                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06847                         if (res2)
06848                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06849                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
06850                            /* Turn on on hook transfer for 4 seconds */
06851                            x = 4000;
06852                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06853                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06854                            last->cidpos = 0;
06855                            last->msgstate = res;
06856                            last->onhooktime = thispass;
06857                         }
06858                         found ++;
06859                      }
06860                   }
06861                   last = last->next;
06862                }
06863             }
06864          }
06865          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06866             if (i->radio && !i->owner)
06867             {
06868                res = zt_get_event(i->subs[SUB_REAL].zfd);
06869                if (res)
06870                {
06871                   if (option_debug)
06872                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06873                   /* Don't hold iflock while handling init events */
06874                   ast_mutex_unlock(&iflock);
06875                   handle_init_event(i, res);
06876                   ast_mutex_lock(&iflock);   
06877                }
06878                i = i->next;
06879                continue;
06880             }              
06881             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06882             if (pollres & POLLIN) {
06883                if (i->owner || i->subs[SUB_REAL].owner) {
06884 #ifdef HAVE_PRI
06885                   if (!i->pri)
06886 #endif                  
06887                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06888                   i = i->next;
06889                   continue;
06890                }
06891                if (!i->cidspill) {
06892                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06893                   i = i->next;
06894                   continue;
06895                }
06896                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06897                if (res > 0) {
06898                   /* We read some number of bytes.  Write an equal amount of data */
06899                   if (res > i->cidlen - i->cidpos) 
06900                      res = i->cidlen - i->cidpos;
06901                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06902                   if (res2 > 0) {
06903                      i->cidpos += res2;
06904                      if (i->cidpos >= i->cidlen) {
06905                         free(i->cidspill);
06906                         i->cidspill = 0;
06907                         i->cidpos = 0;
06908                         i->cidlen = 0;
06909                      }
06910                   } else {
06911                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06912                      i->msgstate = -1;
06913                   }
06914                } else {
06915                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06916                }
06917                if (option_debug)
06918                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06919                /* Don't hold iflock while handling init events -- race with chlock */
06920                ast_mutex_unlock(&iflock);
06921                handle_init_event(i, res);
06922                ast_mutex_lock(&iflock);   
06923             }
06924             if (pollres & POLLPRI) {
06925                if (i->owner || i->subs[SUB_REAL].owner) {
06926 #ifdef HAVE_PRI
06927                   if (!i->pri)
06928 #endif                  
06929                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06930                   i = i->next;
06931                   continue;
06932                }
06933                res = zt_get_event(i->subs[SUB_REAL].zfd);
06934                if (option_debug)
06935                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06936                /* Don't hold iflock while handling init events */
06937                ast_mutex_unlock(&iflock);
06938                handle_init_event(i, res);
06939                ast_mutex_lock(&iflock);   
06940             }
06941          }
06942          i=i->next;
06943       }
06944       ast_mutex_unlock(&iflock);
06945    }
06946    /* Never reached */
06947    return NULL;
06948    
06949 }
06950 
06951 static int restart_monitor(void)
06952 {
06953    pthread_attr_t attr;
06954    pthread_attr_init(&attr);
06955    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06956    /* If we're supposed to be stopped -- stay stopped */
06957    if (monitor_thread == AST_PTHREADT_STOP)
06958       return 0;
06959    ast_mutex_lock(&monlock);
06960    if (monitor_thread == pthread_self()) {
06961       ast_mutex_unlock(&monlock);
06962       ast_log(LOG_WARNING, "Cannot kill myself\n");
06963       return -1;
06964    }
06965    if (monitor_thread != AST_PTHREADT_NULL) {
06966       /* Wake up the thread */
06967       pthread_kill(monitor_thread, SIGURG);
06968    } else {
06969       /* Start a new monitor */
06970       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06971          ast_mutex_unlock(&monlock);
06972          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06973          pthread_attr_destroy(&attr);
06974          return -1;
06975       }
06976    }
06977    ast_mutex_unlock(&monlock);
06978    pthread_attr_destroy(&attr);
06979    return 0;
06980 }
06981 
06982 #ifdef HAVE_PRI
06983 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
06984 {
06985    int x;
06986    int trunkgroup;
06987    /* Get appropriate trunk group if there is one */
06988    trunkgroup = pris[*span].mastertrunkgroup;
06989    if (trunkgroup) {
06990       /* Select a specific trunk group */
06991       for (x = 0; x < NUM_SPANS; x++) {
06992          if (pris[x].trunkgroup == trunkgroup) {
06993             *span = x;
06994             return 0;
06995          }
06996       }
06997       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
06998       *span = -1;
06999    } else {
07000       if (pris[*span].trunkgroup) {
07001          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07002          *span = -1;
07003       } else if (pris[*span].mastertrunkgroup) {
07004          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07005          *span = -1;
07006       } else {
07007          if (si->totalchans == 31) { /* if it's an E1 */
07008             pris[*span].dchannels[0] = 16 + offset;
07009          } else {
07010             pris[*span].dchannels[0] = 24 + offset;
07011          }
07012          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07013          pris[*span].offset = offset;
07014          pris[*span].span = *span + 1;
07015       }
07016    }
07017    return 0;
07018 }
07019 
07020 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07021 {
07022    struct zt_spaninfo si;
07023    ZT_PARAMS p;
07024    int fd;
07025    int span;
07026    int ospan=0;
07027    int x,y;
07028    for (x = 0; x < NUM_SPANS; x++) {
07029       if (pris[x].trunkgroup == trunkgroup) {
07030          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07031          return -1;
07032       }
07033    }
07034    for (y = 0; y < NUM_DCHANS; y++) {
07035       if (!channels[y]) 
07036          break;
07037       memset(&si, 0, sizeof(si));
07038       memset(&p, 0, sizeof(p));
07039       fd = open("/dev/zap/channel", O_RDWR);
07040       if (fd < 0) {
07041          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07042          return -1;
07043       }
07044       x = channels[y];
07045       if (ioctl(fd, ZT_SPECIFY, &x)) {
07046          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07047          zt_close(fd);
07048          return -1;
07049       }
07050       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07051          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07052          return -1;
07053       }
07054       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07055          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07056          zt_close(fd);
07057          return -1;
07058       }
07059       span = p.spanno - 1;
07060       if (pris[span].trunkgroup) {
07061          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07062          zt_close(fd);
07063          return -1;
07064       }
07065       if (pris[span].pvts[0]) {
07066          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07067          zt_close(fd);
07068          return -1;
07069       }
07070       if (!y) {
07071          pris[span].trunkgroup = trunkgroup;
07072          pris[span].offset = channels[y] - p.chanpos;
07073          ospan = span;
07074       }
07075       pris[ospan].dchannels[y] = channels[y];
07076       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07077       pris[span].span = span + 1;
07078       zt_close(fd);
07079    }
07080    return 0;   
07081 }
07082 
07083 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07084 {
07085    if (pris[span].mastertrunkgroup) {
07086       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);
07087       return -1;
07088    }
07089    pris[span].mastertrunkgroup = trunkgroup;
07090    pris[span].prilogicalspan = logicalspan;
07091    return 0;
07092 }
07093 
07094 #endif
07095 
07096 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
07097 {
07098    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07099    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07100    char fn[80];
07101 #if 1
07102    struct zt_bufferinfo bi;
07103 #endif
07104    struct zt_spaninfo si;
07105    int res;
07106    int span=0;
07107    int here = 0;
07108    int x;
07109    struct zt_pvt **wlist;
07110    struct zt_pvt **wend;
07111    ZT_PARAMS p;
07112 
07113    wlist = &iflist;
07114    wend = &ifend;
07115 
07116 #ifdef HAVE_PRI
07117    if (pri) {
07118       wlist = &pri->crvs;
07119       wend = &pri->crvend;
07120    }
07121 #endif
07122 
07123    tmp2 = *wlist;
07124    prev = NULL;
07125 
07126    while (tmp2) {
07127       if (!tmp2->destroy) {
07128          if (tmp2->channel == channel) {
07129             tmp = tmp2;
07130             here = 1;
07131             break;
07132          }
07133          if (tmp2->channel > channel) {
07134             break;
07135          }
07136       }
07137       prev = tmp2;
07138       tmp2 = tmp2->next;
07139    }
07140 
07141    if (!here && !reloading) {
07142       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07143          destroy_zt_pvt(&tmp);
07144          return NULL;
07145       }
07146       ast_mutex_init(&tmp->lock);
07147       ifcount++;
07148       for (x = 0; x < 3; x++)
07149          tmp->subs[x].zfd = -1;
07150       tmp->channel = channel;
07151    }
07152 
07153    if (tmp) {
07154       if (!here) {
07155          if ((channel != CHAN_PSEUDO) && !pri) {
07156             snprintf(fn, sizeof(fn), "%d", channel);
07157             /* Open non-blocking */
07158             if (!here)
07159                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07160             /* Allocate a zapata structure */
07161             if (tmp->subs[SUB_REAL].zfd < 0) {
07162                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);
07163                destroy_zt_pvt(&tmp);
07164                return NULL;
07165             }
07166             memset(&p, 0, sizeof(p));
07167             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07168             if (res < 0) {
07169                ast_log(LOG_ERROR, "Unable to get parameters\n");
07170                destroy_zt_pvt(&tmp);
07171                return NULL;
07172             }
07173             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07174                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));
07175                destroy_zt_pvt(&tmp);
07176                return NULL;
07177             }
07178             tmp->law = p.curlaw;
07179             tmp->span = p.spanno;
07180             span = p.spanno - 1;
07181          } else {
07182             if (channel == CHAN_PSEUDO)
07183                conf.chan.sig = 0;
07184             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07185                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07186                return NULL;
07187             }
07188          }
07189 #ifdef HAVE_PRI
07190          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07191             int offset;
07192             int myswitchtype;
07193             int matchesdchan;
07194             int x,y;
07195             offset = 0;
07196             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07197                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07198                destroy_zt_pvt(&tmp);
07199                return NULL;
07200             }
07201             if (span >= NUM_SPANS) {
07202                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07203                destroy_zt_pvt(&tmp);
07204                return NULL;
07205             } else {
07206                si.spanno = 0;
07207                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07208                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07209                   destroy_zt_pvt(&tmp);
07210                   return NULL;
07211                }
07212                /* Store the logical span first based upon the real span */
07213                tmp->logicalspan = pris[span].prilogicalspan;
07214                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07215                if (span < 0) {
07216                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07217                   destroy_zt_pvt(&tmp);
07218                   return NULL;
07219                }
07220                if (conf.chan.sig == SIG_PRI)
07221                   myswitchtype = conf.pri.switchtype;
07222                else
07223                   myswitchtype = PRI_SWITCH_GR303_TMC;
07224                /* Make sure this isn't a d-channel */
07225                matchesdchan=0;
07226                for (x = 0; x < NUM_SPANS; x++) {
07227                   for (y = 0; y < NUM_DCHANS; y++) {
07228                      if (pris[x].dchannels[y] == tmp->channel) {
07229                         matchesdchan = 1;
07230                         break;
07231                      }
07232                   }
07233                }
07234                offset = p.chanpos;
07235                if (!matchesdchan) {
07236                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07237                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07238                      destroy_zt_pvt(&tmp);
07239                      return NULL;
07240                   }
07241                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07242                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07243                      destroy_zt_pvt(&tmp);
07244                      return NULL;
07245                   }
07246                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07247                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07248                      destroy_zt_pvt(&tmp);
07249                      return NULL;
07250                   }
07251                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07252                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07253                      destroy_zt_pvt(&tmp);
07254                      return NULL;
07255                   }
07256                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07257                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07258                      destroy_zt_pvt(&tmp);
07259                      return NULL;
07260                   }
07261                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07262                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07263                      destroy_zt_pvt(&tmp);
07264                      return NULL;
07265                   }
07266                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07267                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07268                      destroy_zt_pvt(&tmp);
07269                      return NULL;
07270                   }
07271                   if (pris[span].numchans >= MAX_CHANNELS) {
07272                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07273                         pris[span].trunkgroup);
07274                      destroy_zt_pvt(&tmp);
07275                      return NULL;
07276                   }
07277                   pris[span].nodetype = conf.pri.nodetype;
07278                   pris[span].switchtype = myswitchtype;
07279                   pris[span].nsf = conf.pri.nsf;
07280                   pris[span].dialplan = conf.pri.dialplan;
07281                   pris[span].localdialplan = conf.pri.localdialplan;
07282                   pris[span].pvts[pris[span].numchans++] = tmp;
07283                   pris[span].minunused = conf.pri.minunused;
07284                   pris[span].minidle = conf.pri.minidle;
07285                   pris[span].overlapdial = conf.pri.overlapdial;
07286                   pris[span].facilityenable = conf.pri.facilityenable;
07287                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07288                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07289                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07290                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07291                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07292                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07293                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07294                   pris[span].resetinterval = conf.pri.resetinterval;
07295                   
07296                   tmp->pri = &pris[span];
07297                   tmp->prioffset = offset;
07298                   tmp->call = NULL;
07299                } else {
07300                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07301                   destroy_zt_pvt(&tmp);
07302                   return NULL;
07303                }
07304             }
07305          } else {
07306             tmp->prioffset = 0;
07307          }
07308 #endif
07309       } else {
07310          conf.chan.sig = tmp->sig;
07311          conf.chan.radio = tmp->radio;
07312          memset(&p, 0, sizeof(p));
07313          if (tmp->subs[SUB_REAL].zfd > -1)
07314             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07315       }
07316       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07317       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07318           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07319          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07320            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07321           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07322          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07323            (conf.chan.sig == SIG_SF_FEATB)) {
07324          p.starttime = 250;
07325       }
07326       if (conf.chan.radio) {
07327          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07328          p.channo = channel;
07329          p.rxwinktime = 1;
07330          p.rxflashtime = 1;
07331          p.starttime = 1;
07332          p.debouncetime = 5;
07333       }
07334       if (!conf.chan.radio) {
07335          p.channo = channel;
07336          /* Override timing settings based on config file */
07337          if (conf.timing.prewinktime >= 0)
07338             p.prewinktime = conf.timing.prewinktime;
07339          if (conf.timing.preflashtime >= 0)
07340             p.preflashtime = conf.timing.preflashtime;
07341          if (conf.timing.winktime >= 0)
07342             p.winktime = conf.timing.winktime;
07343          if (conf.timing.flashtime >= 0)
07344             p.flashtime = conf.timing.flashtime;
07345          if (conf.timing.starttime >= 0)
07346             p.starttime = conf.timing.starttime;
07347          if (conf.timing.rxwinktime >= 0)
07348             p.rxwinktime = conf.timing.rxwinktime;
07349          if (conf.timing.rxflashtime >= 0)
07350             p.rxflashtime = conf.timing.rxflashtime;
07351          if (conf.timing.debouncetime >= 0)
07352             p.debouncetime = conf.timing.debouncetime;
07353       }
07354       
07355       /* dont set parms on a pseudo-channel (or CRV) */
07356       if (tmp->subs[SUB_REAL].zfd >= 0)
07357       {
07358          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07359          if (res < 0) {
07360             ast_log(LOG_ERROR, "Unable to set parameters\n");
07361             destroy_zt_pvt(&tmp);
07362             return NULL;
07363          }
07364       }
07365 #if 1
07366       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07367          memset(&bi, 0, sizeof(bi));
07368          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07369          if (!res) {
07370             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07371             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07372             bi.numbufs = numbufs;
07373             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07374             if (res < 0) {
07375                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07376             }
07377          } else
07378             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07379       }
07380 #endif
07381       tmp->immediate = conf.chan.immediate;
07382       tmp->transfertobusy = conf.chan.transfertobusy;
07383       tmp->sig = conf.chan.sig;
07384       tmp->outsigmod = conf.chan.outsigmod;
07385       tmp->radio = conf.chan.radio;
07386       tmp->ringt_base = ringt_base;
07387       tmp->firstradio = 0;
07388       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07389          tmp->permcallwaiting = conf.chan.callwaiting;
07390       else
07391          tmp->permcallwaiting = 0;
07392       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07393       tmp->destroy = 0;
07394       tmp->drings = drings;
07395       tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection;
07396       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07397       tmp->threewaycalling = conf.chan.threewaycalling;
07398       tmp->adsi = conf.chan.adsi;
07399       tmp->use_smdi = conf.chan.use_smdi;
07400       tmp->permhidecallerid = conf.chan.hidecallerid;
07401       tmp->callreturn = conf.chan.callreturn;
07402       tmp->echocancel = conf.chan.echocancel;
07403       tmp->echotraining = conf.chan.echotraining;
07404       tmp->pulse = conf.chan.pulse;
07405       tmp->echocanbridged = conf.chan.echocanbridged;
07406       tmp->busydetect = conf.chan.busydetect;
07407       tmp->busycount = conf.chan.busycount;
07408       tmp->busy_tonelength = conf.chan.busy_tonelength;
07409       tmp->busy_quietlength = conf.chan.busy_quietlength;
07410       tmp->callprogress = conf.chan.callprogress;
07411       tmp->cancallforward = conf.chan.cancallforward;
07412       tmp->dtmfrelax = conf.chan.dtmfrelax;
07413       tmp->callwaiting = tmp->permcallwaiting;
07414       tmp->hidecallerid = tmp->permhidecallerid;
07415       tmp->channel = channel;
07416       tmp->stripmsd = conf.chan.stripmsd;
07417       tmp->use_callerid = conf.chan.use_callerid;
07418       tmp->cid_signalling = conf.chan.cid_signalling;
07419       tmp->cid_start = conf.chan.cid_start;
07420       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07421       tmp->restrictcid = conf.chan.restrictcid;
07422       tmp->use_callingpres = conf.chan.use_callingpres;
07423       tmp->priindication_oob = conf.chan.priindication_oob;
07424       tmp->priexclusive = conf.chan.priexclusive;
07425       if (tmp->usedistinctiveringdetection) {
07426          if (!tmp->use_callerid) {
07427             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07428             tmp->use_callerid = 1;
07429          }
07430       }
07431 
07432       if (tmp->cid_signalling == CID_SIG_SMDI) {
07433          if (!tmp->use_smdi) {
07434             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07435             tmp->use_smdi = 1;
07436          }
07437       }
07438       if (tmp->use_smdi) {
07439          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07440          if (!(tmp->smdi_iface)) {
07441             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07442             tmp->use_smdi = 0;
07443          }
07444       }
07445 
07446       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07447       tmp->amaflags = conf.chan.amaflags;
07448       if (!here) {
07449          tmp->confno = -1;
07450          tmp->propconfno = -1;
07451       }
07452       tmp->canpark = conf.chan.canpark;
07453       tmp->transfer = conf.chan.transfer;
07454       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07455       ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
07456       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07457       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07458       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07459       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07460       tmp->cid_ton = 0;
07461       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07462       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07463       tmp->msgstate = -1;
07464       tmp->group = conf.chan.group;
07465       tmp->callgroup = conf.chan.callgroup;
07466       tmp->pickupgroup= conf.chan.pickupgroup;
07467       tmp->rxgain = conf.chan.rxgain;
07468       tmp->txgain = conf.chan.txgain;
07469       tmp->tonezone = conf.chan.tonezone;
07470       tmp->onhooktime = time(NULL);
07471       if (tmp->subs[SUB_REAL].zfd > -1) {
07472          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07473          if (tmp->dsp)
07474             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07475          update_conf(tmp);
07476          if (!here) {
07477             if (conf.chan.sig != SIG_PRI)
07478                /* Hang it up to be sure it's good */
07479                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07480          }
07481          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07482 #ifdef HAVE_PRI
07483          /* the dchannel is down so put the channel in alarm */
07484          if (tmp->pri && !pri_is_up(tmp->pri))
07485             tmp->inalarm = 1;
07486          else
07487             tmp->inalarm = 0;
07488 #endif            
07489          memset(&si, 0, sizeof(si));
07490          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07491             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07492             destroy_zt_pvt(&tmp);
07493             return NULL;
07494          }
07495          if (si.alarms) tmp->inalarm = 1;
07496       }
07497 
07498       tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
07499       tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
07500       tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
07501       tmp->sendcalleridafter = conf.chan.sendcalleridafter;
07502 
07503    }
07504    if (tmp && !here) {
07505       /* nothing on the iflist */
07506       if (!*wlist) {
07507          *wlist = tmp;
07508          tmp->prev = NULL;
07509          tmp->next = NULL;
07510          *wend = tmp;
07511       } else {
07512          /* at least one member on the iflist */
07513          struct zt_pvt *working = *wlist;
07514 
07515          /* check if we maybe have to put it on the begining */
07516          if (working->channel > tmp->channel) {
07517             tmp->next = *wlist;
07518             tmp->prev = NULL;
07519             (*wlist)->prev = tmp;
07520             *wlist = tmp;
07521          } else {
07522          /* go through all the members and put the member in the right place */
07523             while (working) {
07524                /* in the middle */
07525                if (working->next) {
07526                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07527                      tmp->next = working->next;
07528                      tmp->prev = working;
07529                      working->next->prev = tmp;
07530                      working->next = tmp;
07531                      break;
07532                   }
07533                } else {
07534                /* the last */
07535                   if (working->channel < tmp->channel) {
07536                      working->next = tmp;
07537                      tmp->next = NULL;
07538                      tmp->prev = working;
07539                      *wend = tmp;
07540                      break;
07541                   }
07542                }
07543                working = working->next;
07544             }
07545          }
07546       }
07547    }
07548    return tmp;
07549 }
07550 
07551 static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
07552 {
07553    int res;
07554    ZT_PARAMS par;
07555 
07556    /* First, check group matching */
07557    if (groupmatch) {
07558       if ((p->group & groupmatch) != groupmatch)
07559          return 0;
07560       *groupmatched = 1;
07561    }
07562    /* Check to see if we have a channel match */
07563    if (channelmatch != -1) {
07564       if (p->channel != channelmatch)
07565          return 0;
07566       *channelmatched = 1;
07567    }
07568    /* We're at least busy at this point */
07569    if (busy) {
07570       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07571          *busy = 1;
07572    }
07573    /* If do not disturb, definitely not */
07574    if (p->dnd)
07575       return 0;
07576    /* If guard time, definitely not */
07577    if (p->guardtime && (time(NULL) < p->guardtime)) 
07578       return 0;
07579       
07580    /* If no owner definitely available */
07581    if (!p->owner) {
07582 #ifdef HAVE_PRI
07583       /* Trust PRI */
07584       if (p->pri) {
07585          if (p->resetting || p->call)
07586             return 0;
07587          else
07588             return 1;
07589       }
07590 #endif
07591       if (!(p->radio || (p->oprmode < 0)))
07592       {
07593          if (!p->sig || (p->sig == SIG_FXSLS))
07594             return 1;
07595          /* Check hook state */
07596          if (p->subs[SUB_REAL].zfd > -1)
07597             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07598          else {
07599             /* Assume not off hook on CVRS */
07600             res = 0;
07601             par.rxisoffhook = 0;
07602          }
07603          if (res) {
07604             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07605          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07606             /* When "onhook" that means no battery on the line, and thus
07607               it is out of service..., if it's on a TDM card... If it's a channel
07608               bank, there is no telling... */
07609             if (par.rxbits > -1)
07610                return 1;
07611             if (par.rxisoffhook)
07612                return 1;
07613             else
07614 #ifdef ZAP_CHECK_HOOKSTATE
07615                return 0;
07616 #else
07617                return 1;
07618 #endif
07619          } else if (par.rxisoffhook) {
07620             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07621             /* Not available when the other end is off hook */
07622             return 0;
07623          }
07624       }
07625       return 1;
07626    }
07627 
07628    /* If it's not an FXO, forget about call wait */
07629    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07630       return 0;
07631 
07632    if (!p->callwaiting) {
07633       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07634       return 0;
07635    }
07636 
07637    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07638       /* If there is already a call waiting call, then we can't take a second one */
07639       return 0;
07640    }
07641    
07642    if ((p->owner->_state != AST_STATE_UP) &&
07643        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07644       /* If the current call is not up, then don't allow the call */
07645       return 0;
07646    }
07647    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07648       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07649       return 0;
07650    }
07651    /* We're cool */
07652    return 1;
07653 }
07654 
07655 static struct zt_pvt *chandup(struct zt_pvt *src)
07656 {
07657    struct zt_pvt *p;
07658    ZT_BUFFERINFO bi;
07659    int res;
07660    
07661    if ((p = ast_malloc(sizeof(*p)))) {
07662       memcpy(p, src, sizeof(struct zt_pvt));
07663       ast_mutex_init(&p->lock);
07664       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07665       /* Allocate a zapata structure */
07666       if (p->subs[SUB_REAL].zfd < 0) {
07667          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07668          destroy_zt_pvt(&p);
07669          return NULL;
07670       }
07671       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07672       if (!res) {
07673          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07674          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07675          bi.numbufs = numbufs;
07676          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07677          if (res < 0) {
07678             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07679          }
07680       } else
07681          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07682    }
07683    p->destroy = 1;
07684    p->next = iflist;
07685    iflist = p;
07686    return p;
07687 }
07688    
07689 
07690 #ifdef HAVE_PRI
07691 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
07692 {
07693    int x;
07694    if (backwards)
07695       x = pri->numchans;
07696    else
07697       x = 0;
07698    for (;;) {
07699       if (backwards && (x < 0))
07700          break;
07701       if (!backwards && (x >= pri->numchans))
07702          break;
07703       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
07704          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
07705             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
07706          return x;
07707       }
07708       if (backwards)
07709          x--;
07710       else
07711          x++;
07712    }
07713    return -1;
07714 }
07715 #endif
07716 
07717 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
07718 {
07719    int groupmatch = 0;
07720    int channelmatch = -1;
07721    int roundrobin = 0;
07722    int callwait = 0;
07723    int busy = 0;
07724    struct zt_pvt *p;
07725    struct ast_channel *tmp = NULL;
07726    char *dest=NULL;
07727    int x;
07728    char *s;
07729    char opt=0;
07730    int res=0, y=0;
07731    int backwards = 0;
07732 #ifdef HAVE_PRI
07733    int crv;
07734    int bearer = -1;
07735    int trunkgroup;
07736    struct zt_pri *pri=NULL;
07737 #endif   
07738    struct zt_pvt *exit, *start, *end;
07739    ast_mutex_t *lock;
07740    int channelmatched = 0;
07741    int groupmatched = 0;
07742    
07743    /* Assume we're locking the iflock */
07744    lock = &iflock;
07745    start = iflist;
07746    end = ifend;
07747    if (data) {
07748       dest = ast_strdupa((char *)data);
07749    } else {
07750       ast_log(LOG_WARNING, "Channel requested with no data\n");
07751       return NULL;
07752    }
07753    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07754       /* Retrieve the group number */
07755       char *stringp=NULL;
07756       stringp=dest + 1;
07757       s = strsep(&stringp, "/");
07758       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07759          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07760          return NULL;
07761       }
07762       groupmatch = 1 << x;
07763       if (toupper(dest[0]) == 'G') {
07764          if (dest[0] == 'G') {
07765             backwards = 1;
07766             p = ifend;
07767          } else
07768             p = iflist;
07769       } else {
07770          if (dest[0] == 'R') {
07771             backwards = 1;
07772             p = round_robin[x]?round_robin[x]->prev:ifend;
07773             if (!p)
07774                p = ifend;
07775          } else {
07776             p = round_robin[x]?round_robin[x]->next:iflist;
07777             if (!p)
07778                p = iflist;
07779          }
07780          roundrobin = 1;
07781       }
07782    } else {
07783       char *stringp=NULL;
07784       stringp=dest;
07785       s = strsep(&stringp, "/");
07786       p = iflist;
07787       if (!strcasecmp(s, "pseudo")) {
07788          /* Special case for pseudo */
07789          x = CHAN_PSEUDO;
07790          channelmatch = x;
07791       } 
07792 #ifdef HAVE_PRI
07793       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07794          if ((trunkgroup < 1) || (crv < 1)) {
07795             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07796             return NULL;
07797          }
07798          res--;
07799          for (x = 0; x < NUM_SPANS; x++) {
07800             if (pris[x].trunkgroup == trunkgroup) {
07801                pri = pris + x;
07802                lock = &pri->lock;
07803                start = pri->crvs;
07804                end = pri->crvend;
07805                break;
07806             }
07807          }
07808          if (!pri) {
07809             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07810             return NULL;
07811          }
07812          channelmatch = crv;
07813          p = pris[x].crvs;
07814       }
07815 #endif   
07816       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07817          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07818          return NULL;
07819       } else {
07820          channelmatch = x;
07821       }
07822    }
07823    /* Search for an unowned channel */
07824    ast_mutex_lock(lock);
07825    exit = p;
07826    while (p && !tmp) {
07827       if (roundrobin)
07828          round_robin[x] = p;
07829 #if 0
07830       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07831 #endif
07832 
07833       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07834          if (option_debug)
07835             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07836             if (p->inalarm) 
07837                goto next;
07838 
07839          callwait = (p->owner != NULL);
07840 #ifdef HAVE_PRI
07841          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07842             if (p->sig != SIG_FXSKS) {
07843                /* Gotta find an actual channel to use for this
07844                   CRV if this isn't a callwait */
07845                bearer = pri_find_empty_chan(pri, 0);
07846                if (bearer < 0) {
07847                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07848                   p = NULL;
07849                   break;
07850                }
07851                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07852             } else {
07853                if (alloc_sub(p, 0)) {
07854                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07855                   p = NULL;
07856                   break;
07857                } else
07858                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07859                p->pri = pri;
07860             }
07861          }
07862 #endif         
07863          if (p->channel == CHAN_PSEUDO) {
07864             p = chandup(p);
07865             if (!p) {
07866                break;
07867             }
07868          }
07869          if (p->owner) {
07870             if (alloc_sub(p, SUB_CALLWAIT)) {
07871                p = NULL;
07872                break;
07873             }
07874          }
07875          p->outgoing = 1;
07876          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07877 #ifdef HAVE_PRI
07878          if (p->bearer) {
07879             /* Log owner to bearer channel, too */
07880             p->bearer->owner = tmp;
07881          }
07882 #endif         
07883          /* Make special notes */
07884          if (res > 1) {
07885             if (opt == 'c') {
07886                /* Confirm answer */
07887                p->confirmanswer = 1;
07888             } else if (opt == 'r') {
07889                /* Distinctive ring */
07890                if (res < 3)
07891                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07892                else
07893                   p->distinctivering = y;
07894             } else if (opt == 'd') {
07895                /* If this is an ISDN call, make it digital */
07896                p->digital = 1;
07897                if (tmp)
07898                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07899             } else {
07900                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07901             }
07902          }
07903          /* Note if the call is a call waiting call */
07904          if (tmp && callwait)
07905             tmp->cdrflags |= AST_CDR_CALLWAIT;
07906          break;
07907       }
07908 next:
07909       if (backwards) {
07910          p = p->prev;
07911          if (!p)
07912             p = end;
07913       } else {
07914          p = p->next;
07915          if (!p)
07916             p = start;
07917       }
07918       /* stop when you roll to the one that we started from */
07919       if (p == exit)
07920          break;
07921    }
07922    ast_mutex_unlock(lock);
07923    restart_monitor();
07924    if (callwait)
07925       *cause = AST_CAUSE_BUSY;
07926    else if (!tmp) {
07927       if (channelmatched) {
07928          if (busy)
07929             *cause = AST_CAUSE_BUSY;
07930       } else if (groupmatched) {
07931          *cause = AST_CAUSE_CONGESTION;
07932       }
07933    }
07934       
07935    return tmp;
07936 }
07937 
07938 
07939 #ifdef HAVE_PRI
07940 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
07941 {
07942    struct zt_pvt *p;
07943    p = pri->crvs;
07944    while (p) {
07945       if (p->channel == crv)
07946          return p;
07947       p = p->next;
07948    }
07949    return NULL;
07950 }
07951 
07952 
07953 static int pri_find_principle(struct zt_pri *pri, int channel)
07954 {
07955    int x;
07956    int span = PRI_SPAN(channel);
07957    int spanfd;
07958    ZT_PARAMS param;
07959    int principle = -1;
07960    int explicit = PRI_EXPLICIT(channel);
07961    channel = PRI_CHANNEL(channel);
07962 
07963    if (!explicit) {
07964       spanfd = pri_active_dchan_fd(pri);
07965       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
07966          return -1;
07967       span = pris[param.spanno - 1].prilogicalspan;
07968    }
07969 
07970    for (x = 0; x < pri->numchans; x++) {
07971       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
07972          principle = x;
07973          break;
07974       }
07975    }
07976    
07977    return principle;
07978 }
07979 
07980 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
07981 {
07982    int x;
07983    struct zt_pvt *crv;
07984    if (!c) {
07985       if (principle < 0)
07986          return -1;
07987       return principle;
07988    }
07989    if ((principle > -1) && 
07990       (principle < pri->numchans) && 
07991       (pri->pvts[principle]) && 
07992       (pri->pvts[principle]->call == c))
07993       return principle;
07994    /* First, check for other bearers */
07995    for (x = 0; x < pri->numchans; x++) {
07996       if (!pri->pvts[x])
07997          continue;
07998       if (pri->pvts[x]->call == c) {
07999          /* Found our call */
08000          if (principle != x) {
08001             if (option_verbose > 2)
08002                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08003                   pri->pvts[x]->channel, pri->pvts[principle]->channel);
08004             if (pri->pvts[principle]->owner) {
08005                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08006                   pri->pvts[x]->channel, pri->pvts[principle]->channel, pri->pvts[principle]->channel);
08007                return -1;
08008             }
08009             /* Fix it all up now */
08010             pri->pvts[principle]->owner = pri->pvts[x]->owner;
08011             if (pri->pvts[principle]->owner) {
08012                ast_string_field_build(pri->pvts[principle]->owner, name, 
08013                             "Zap/%d:%d-%d", pri->trunkgroup,
08014                             pri->pvts[principle]->channel, 1);
08015                pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
08016                pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
08017                pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
08018             } else
08019                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);
08020             pri->pvts[principle]->call = pri->pvts[x]->call;
08021             /* Free up the old channel, now not in use */
08022             pri->pvts[x]->subs[SUB_REAL].owner = NULL;
08023             pri->pvts[x]->owner = NULL;
08024             pri->pvts[x]->call = NULL;
08025          }
08026          return principle;
08027       }
08028    }
08029    /* Now check for a CRV with no bearer */
08030    crv = pri->crvs;
08031    while (crv) {
08032       if (crv->call == c) {
08033          /* This is our match...  Perform some basic checks */
08034          if (crv->bearer)
08035             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08036          else if (pri->pvts[principle]->owner) 
08037             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08038          else {
08039             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08040                wakeup the potential sleeper */
08041             zt_close(crv->subs[SUB_REAL].zfd);
08042             pri->pvts[principle]->call = crv->call;
08043             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08044             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08045                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08046                            pri->trunkgroup, crv->channel);
08047             wakeup_sub(crv, SUB_REAL, pri);
08048          }
08049          return principle;
08050       }
08051       crv = crv->next;
08052    }
08053    ast_log(LOG_WARNING, "Call specified, but not found?\n");
08054    return -1;
08055 }
08056 
08057 static void *do_idle_thread(void *vchan)
08058 {
08059    struct ast_channel *chan = vchan;
08060    struct zt_pvt *pvt = chan->tech_pvt;
08061    struct ast_frame *f;
08062    char ex[80];
08063    /* Wait up to 30 seconds for an answer */
08064    int newms, ms = 30000;
08065    if (option_verbose > 2) 
08066       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08067    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08068    if (ast_call(chan, ex, 0)) {
08069       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08070       ast_hangup(chan);
08071       return NULL;
08072    }
08073    while ((newms = ast_waitfor(chan, ms)) > 0) {
08074       f = ast_read(chan);
08075       if (!f) {
08076          /* Got hangup */
08077          break;
08078       }
08079       if (f->frametype == AST_FRAME_CONTROL) {
08080          switch (f->subclass) {
08081          case AST_CONTROL_ANSWER:
08082             /* Launch the PBX */
08083             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08084             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08085             chan->priority = 1;
08086             if (option_verbose > 3) 
08087                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08088             ast_pbx_run(chan);
08089             /* It's already hungup, return immediately */
08090             return NULL;
08091          case AST_CONTROL_BUSY:
08092             if (option_verbose > 3) 
08093                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08094             break;
08095          case AST_CONTROL_CONGESTION:
08096             if (option_verbose > 3) 
08097                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08098             break;
08099          };
08100       }
08101       ast_frfree(f);
08102       ms = newms;
08103    }
08104    /* Hangup the channel since nothing happend */
08105    ast_hangup(chan);
08106    return NULL;
08107 }
08108 
08109 #ifndef PRI_RESTART
08110 #error "Upgrade your libpri"
08111 #endif
08112 static void zt_pri_message(struct pri *pri, char *s)
08113 {
08114    int x, y;
08115    int dchan = -1, span = -1;
08116    int dchancount = 0;
08117 
08118    if (pri) {
08119       for (x = 0; x < NUM_SPANS; x++) {
08120          for (y = 0; y < NUM_DCHANS; y++) {
08121             if (pris[x].dchans[y])
08122                dchancount++;
08123 
08124             if (pris[x].dchans[y] == pri)
08125                dchan = y;
08126          }
08127          if (dchan >= 0) {
08128             span = x;
08129             break;
08130          }
08131          dchancount = 0;
08132       }
08133       if ((dchan >= 0) && (span >= 0)) {
08134          if (dchancount > 1)
08135             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
08136          else
08137             ast_verbose("%s", s);
08138       } else
08139          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08140    } else
08141       ast_verbose("%s", s);
08142 
08143    ast_mutex_lock(&pridebugfdlock);
08144 
08145    if (pridebugfd >= 0)
08146       write(pridebugfd, s, strlen(s));
08147 
08148    ast_mutex_unlock(&pridebugfdlock);
08149 }
08150 
08151 static void zt_pri_error(struct pri *pri, char *s)
08152 {
08153    int x, y;
08154    int dchan = -1, span = -1;
08155    int dchancount = 0;
08156 
08157    if (pri) {
08158       for (x = 0; x < NUM_SPANS; x++) {
08159          for (y = 0; y < NUM_DCHANS; y++) {
08160             if (pris[x].dchans[y])
08161                dchancount++;
08162 
08163             if (pris[x].dchans[y] == pri)
08164                dchan = y;
08165          }
08166          if (dchan >= 0) {
08167             span = x;
08168             break;
08169          }
08170          dchancount = 0;
08171       }
08172       if ((dchan >= 0) && (span >= 0)) {
08173          if (dchancount > 1)
08174             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
08175          else
08176             ast_log(LOG_ERROR, "%s", s);
08177       } else
08178          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08179    } else
08180       ast_log(LOG_ERROR, "%s", s);
08181 
08182    ast_mutex_lock(&pridebugfdlock);
08183 
08184    if (pridebugfd >= 0)
08185       write(pridebugfd, s, strlen(s));
08186 
08187    ast_mutex_unlock(&pridebugfdlock);
08188 }
08189 
08190 static int pri_check_restart(struct zt_pri *pri)
08191 {
08192    do {
08193       pri->resetpos++;
08194    } while ((pri->resetpos < pri->numchans) &&
08195        (!pri->pvts[pri->resetpos] ||
08196         pri->pvts[pri->resetpos]->call ||
08197         pri->pvts[pri->resetpos]->resetting));
08198    if (pri->resetpos < pri->numchans) {
08199       /* Mark the channel as resetting and restart it */
08200       pri->pvts[pri->resetpos]->resetting = 1;
08201       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08202    } else {
08203       pri->resetting = 0;
08204       time(&pri->lastreset);
08205    }
08206    return 0;
08207 }
08208 
08209 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08210 {
08211    int x;
08212    int redo;
08213    ast_mutex_unlock(&pri->lock);
08214    ast_mutex_lock(&p->lock);
08215    do {
08216       redo = 0;
08217       for (x = 0; x < 3; x++) {
08218          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08219             redo++;
08220             ast_mutex_unlock(&p->lock);
08221             usleep(1);
08222             ast_mutex_lock(&p->lock);
08223          }
08224          if (p->subs[x].owner) {
08225             ast_queue_hangup(p->subs[x].owner);
08226             ast_mutex_unlock(&p->subs[x].owner->lock);
08227          }
08228       }
08229    } while (redo);
08230    ast_mutex_unlock(&p->lock);
08231    ast_mutex_lock(&pri->lock);
08232    return 0;
08233 }
08234 
08235 static char * redirectingreason2str(int redirectingreason)
08236 {
08237    switch (redirectingreason) {
08238    case 0:
08239       return "UNKNOWN";
08240    case 1:
08241       return "BUSY";
08242    case 2:
08243       return "NO_REPLY";
08244    case 0xF:
08245       return "UNCONDITIONAL";
08246    default:
08247       return "NOREDIRECT";
08248    }
08249 }
08250 
08251 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08252 {
08253    switch (plan) {
08254    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08255       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08256       break;
08257    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08258       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08259       break;
08260    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08261       snprintf(buf, size, "%s%s", pri->localprefix, number);
08262       break;
08263    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08264       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08265       break;
08266    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08267       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08268       break;
08269    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08270       snprintf(buf, size, "%s", number);
08271       break;
08272    }
08273 }
08274 
08275 static int zt_setlaw(int zfd, int law)
08276 {
08277    int res;
08278    res = ioctl(zfd, ZT_SETLAW, &law);
08279    if (res)
08280       return res;
08281    return 0;
08282 }
08283 
08284 static void *pri_dchannel(void *vpri)
08285 {
08286    struct zt_pri *pri = vpri;
08287    pri_event *e;
08288    struct pollfd fds[NUM_DCHANS];
08289    int res;
08290    int chanpos = 0;
08291    int x;
08292    int haveidles;
08293    int activeidles;
08294    int nextidle = -1;
08295    struct ast_channel *c;
08296    struct timeval tv, lowest, *next;
08297    struct timeval lastidle = { 0, 0 };
08298    int doidling=0;
08299    char *cc;
08300    char idlen[80];
08301    struct ast_channel *idle;
08302    pthread_t p;
08303    time_t t;
08304    int i, which=-1;
08305    int numdchans;
08306    int cause=0;
08307    struct zt_pvt *crv;
08308    pthread_t threadid;
08309    pthread_attr_t attr;
08310    char ani2str[6];
08311    char plancallingnum[256];
08312    char plancallingani[256];
08313    char calledtonstr[10];
08314    
08315    gettimeofday(&lastidle, NULL);
08316    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08317       /* Need to do idle dialing, check to be sure though */
08318       cc = strchr(pri->idleext, '@');
08319       if (cc) {
08320          *cc = '\0';
08321          cc++;
08322          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08323 #if 0
08324          /* Extensions may not be loaded yet */
08325          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08326             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08327          else
08328 #endif
08329             doidling = 1;
08330       } else
08331          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08332    }
08333    for (;;) {
08334       for (i = 0; i < NUM_DCHANS; i++) {
08335          if (!pri->dchannels[i])
08336             break;
08337          fds[i].fd = pri->fds[i];
08338          fds[i].events = POLLIN | POLLPRI;
08339          fds[i].revents = 0;
08340       }
08341       numdchans = i;
08342       time(&t);
08343       ast_mutex_lock(&pri->lock);
08344       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08345          if (pri->resetting && pri_is_up(pri)) {
08346             if (pri->resetpos < 0)
08347                pri_check_restart(pri);
08348          } else {
08349             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08350                pri->resetting = 1;
08351                pri->resetpos = -1;
08352             }
08353          }
08354       }
08355       /* Look for any idle channels if appropriate */
08356       if (doidling && pri_is_up(pri)) {
08357          nextidle = -1;
08358          haveidles = 0;
08359          activeidles = 0;
08360          for (x = pri->numchans; x >= 0; x--) {
08361             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08362                 !pri->pvts[x]->call) {
08363                if (haveidles < pri->minunused) {
08364                   haveidles++;
08365                } else if (!pri->pvts[x]->resetting) {
08366                   nextidle = x;
08367                   break;
08368                }
08369             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08370                activeidles++;
08371          }
08372          if (nextidle > -1) {
08373             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08374                /* Don't create a new idle call more than once per second */
08375                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08376                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08377                if (idle) {
08378                   pri->pvts[nextidle]->isidlecall = 1;
08379                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08380                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08381                      zt_hangup(idle);
08382                   }
08383                } else
08384                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08385                gettimeofday(&lastidle, NULL);
08386             }
08387          } else if ((haveidles < pri->minunused) &&
08388                (activeidles > pri->minidle)) {
08389             /* Mark something for hangup if there is something 
08390                that can be hungup */
08391             for (x = pri->numchans; x >= 0; x--) {
08392                /* find a candidate channel */
08393                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08394                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08395                   haveidles++;
08396                   /* Stop if we have enough idle channels or
08397                     can't spare any more active idle ones */
08398                   if ((haveidles >= pri->minunused) ||
08399                       (activeidles <= pri->minidle))
08400                      break;
08401                } 
08402             }
08403          }
08404       }
08405       /* Start with reasonable max */
08406       lowest = ast_tv(60, 0);
08407       for (i = 0; i < NUM_DCHANS; i++) {
08408          /* Find lowest available d-channel */
08409          if (!pri->dchannels[i])
08410             break;
08411          if ((next = pri_schedule_next(pri->dchans[i]))) {
08412             /* We need relative time here */
08413             tv = ast_tvsub(*next, ast_tvnow());
08414             if (tv.tv_sec < 0) {
08415                tv = ast_tv(0,0);
08416             }
08417             if (doidling || pri->resetting) {
08418                if (tv.tv_sec > 1) {
08419                   tv = ast_tv(1, 0);
08420                }
08421             } else {
08422                if (tv.tv_sec > 60) {
08423                   tv = ast_tv(60, 0);
08424                }
08425             }
08426          } else if (doidling || pri->resetting) {
08427             /* Make sure we stop at least once per second if we're
08428                monitoring idle channels */
08429             tv = ast_tv(1,0);
08430          } else {
08431             /* Don't poll for more than 60 seconds */
08432             tv = ast_tv(60, 0);
08433          }
08434          if (!i || ast_tvcmp(tv, lowest) < 0) {
08435             lowest = tv;
08436          }
08437       }
08438       ast_mutex_unlock(&pri->lock);
08439 
08440       e = NULL;
08441       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
08442 
08443       ast_mutex_lock(&pri->lock);
08444       if (!res) {
08445          for (which = 0; which < NUM_DCHANS; which++) {
08446             if (!pri->dchans[which])
08447                break;
08448             /* Just a timeout, run the scheduler */
08449             e = pri_schedule_run(pri->dchans[which]);
08450             if (e)
08451                break;
08452          }
08453       } else if (res > -1) {
08454          for (which = 0; which < NUM_DCHANS; which++) {
08455             if (!pri->dchans[which])
08456                break;
08457             if (fds[which].revents & POLLPRI) {
08458                /* Check for an event */
08459                x = 0;
08460                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
08461                if (x) 
08462                   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);
08463                /* Keep track of alarm state */  
08464                if (x == ZT_EVENT_ALARM) {
08465                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
08466                   pri_find_dchan(pri);
08467                } else if (x == ZT_EVENT_NOALARM) {
08468                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
08469                   pri_restart(pri->dchans[which]);
08470                }
08471             
08472                if (option_debug)
08473                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
08474             } else if (fds[which].revents & POLLIN) {
08475                e = pri_check_event(pri->dchans[which]);
08476             }
08477             if (e)
08478                break;
08479          }
08480       } else if (errno != EINTR)
08481          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
08482 
08483       if (e) {
08484          if (pri->debug)
08485             pri_dump_event(pri->dchans[which], e);
08486          if (e->e != PRI_EVENT_DCHAN_DOWN)
08487             pri->dchanavail[which] |= DCHAN_UP;
08488 
08489          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
08490             /* Must be an NFAS group that has the secondary dchan active */
08491             pri->pri = pri->dchans[which];
08492 
08493          switch (e->e) {
08494          case PRI_EVENT_DCHAN_UP:
08495             if (option_verbose > 1) 
08496                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
08497             pri->dchanavail[which] |= DCHAN_UP;
08498             if (!pri->pri) pri_find_dchan(pri);
08499 
08500             /* Note presense of D-channel */
08501             time(&pri->lastreset);
08502 
08503             /* Restart in 5 seconds */
08504             if (pri->resetinterval > -1) {
08505                pri->lastreset -= pri->resetinterval;
08506                pri->lastreset += 5;
08507             }
08508             pri->resetting = 0;
08509             /* Take the channels from inalarm condition */
08510             for (i = 0; i < pri->numchans; i++)
08511                if (pri->pvts[i]) {
08512                   pri->pvts[i]->inalarm = 0;
08513                }
08514             break;
08515          case PRI_EVENT_DCHAN_DOWN:
08516             if (option_verbose > 1) 
08517                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
08518             pri->dchanavail[which] &= ~DCHAN_UP;
08519             pri_find_dchan(pri);
08520             if (!pri_is_up(pri)) {
08521                pri->resetting = 0;
08522                /* Hangup active channels and put them in alarm mode */
08523                for (i = 0; i < pri->numchans; i++) {
08524                   struct zt_pvt *p = pri->pvts[i];
08525                   if (p) {
08526                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08527                         /* T309 is not enabled : hangup calls when alarm occurs */
08528                         if (p->call) {
08529                            if (p->pri && p->pri->pri) {
08530                               pri_hangup(p->pri->pri, p->call, -1);
08531                               pri_destroycall(p->pri->pri, p->call);
08532                               p->call = NULL;
08533                            } else
08534                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
08535                         }
08536                         if (p->realcall) {
08537                            pri_hangup_all(p->realcall, pri);
08538                         } else if (p->owner)
08539                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08540                      }
08541                      p->inalarm = 1;
08542                   }
08543                }
08544             }
08545             break;
08546          case PRI_EVENT_RESTART:
08547             if (e->restart.channel > -1) {
08548                chanpos = pri_find_principle(pri, e->restart.channel);
08549                if (chanpos < 0)
08550                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
08551                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08552                else {
08553                   if (option_verbose > 2)
08554                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
08555                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08556                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08557                   if (pri->pvts[chanpos]->call) {
08558                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
08559                      pri->pvts[chanpos]->call = NULL;
08560                   }
08561                   /* Force soft hangup if appropriate */
08562                   if (pri->pvts[chanpos]->realcall) 
08563                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08564                   else if (pri->pvts[chanpos]->owner)
08565                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08566                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08567                }
08568             } else {
08569                if (option_verbose > 2)
08570                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
08571                for (x = 0; x < pri->numchans; x++)
08572                   if (pri->pvts[x]) {
08573                      ast_mutex_lock(&pri->pvts[x]->lock);
08574                      if (pri->pvts[x]->call) {
08575                         pri_destroycall(pri->pri, pri->pvts[x]->call);
08576                         pri->pvts[x]->call = NULL;
08577                      }
08578                      if (pri->pvts[chanpos]->realcall) 
08579                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08580                      else if (pri->pvts[x]->owner)
08581                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08582                      ast_mutex_unlock(&pri->pvts[x]->lock);
08583                   }
08584             }
08585             break;
08586          case PRI_EVENT_KEYPAD_DIGIT:
08587             chanpos = pri_find_principle(pri, e->digit.channel);
08588             if (chanpos < 0) {
08589                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
08590                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
08591             } else {
08592                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
08593                if (chanpos > -1) {
08594                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08595                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
08596                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
08597                      /* how to do that */
08598                      int digitlen = strlen(e->digit.digits);
08599                      char digit;
08600                      int i;               
08601                      for (i = 0; i < digitlen; i++) { 
08602                         digit = e->digit.digits[i];
08603                         {
08604                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08605                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08606                         }
08607                      }
08608                   }
08609                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08610                }
08611             }
08612             break;
08613             
08614          case PRI_EVENT_INFO_RECEIVED:
08615             chanpos = pri_find_principle(pri, e->ring.channel);
08616             if (chanpos < 0) {
08617                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
08618                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08619             } else {
08620                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
08621                if (chanpos > -1) {
08622                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08623                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
08624                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
08625                      /* how to do that */
08626                      int digitlen = strlen(e->ring.callednum);
08627                      char digit;
08628                      int i;               
08629                      for (i = 0; i < digitlen; i++) { 
08630                         digit = e->ring.callednum[i];
08631                         {
08632                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08633                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08634                         }
08635                      }
08636                   }
08637                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08638                }
08639             }
08640             break;
08641          case PRI_EVENT_RING:
08642             crv = NULL;
08643             if (e->ring.channel == -1)
08644                chanpos = pri_find_empty_chan(pri, 1);
08645             else
08646                chanpos = pri_find_principle(pri, e->ring.channel);
08647             /* if no channel specified find one empty */
08648             if (chanpos < 0) {
08649                ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 
08650                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08651             } else {
08652                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08653                if (pri->pvts[chanpos]->owner) {
08654                   if (pri->pvts[chanpos]->call == e->ring.call) {
08655                      ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
08656                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08657                      break;
08658                   } else {
08659                      /* This is where we handle initial glare */
08660                      ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiating channel.\n", 
08661                      PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08662                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08663                      chanpos = -1;
08664                   }
08665                }
08666                if (chanpos > -1)
08667                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08668             }
08669             if ((chanpos < 0) && (e->ring.flexible))
08670                chanpos = pri_find_empty_chan(pri, 1);
08671             if (chanpos > -1) {
08672                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08673                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
08674                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
08675                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
08676                   if (crv)
08677                      ast_mutex_lock(&crv->lock);
08678                   if (!crv || crv->owner) {
08679                      pri->pvts[chanpos]->call = NULL;
08680                      if (crv) {
08681                         if (crv->owner)
08682                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08683                         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);
08684                      } else
08685                         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);
08686                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
08687                      if (crv)
08688                         ast_mutex_unlock(&crv->lock);
08689                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08690                      break;
08691                   }
08692                }
08693                pri->pvts[chanpos]->call = e->ring.call;
08694                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
08695                if (pri->pvts[chanpos]->use_callerid) {
08696                   ast_shrink_phone_number(plancallingnum);
08697                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
08698 #ifdef PRI_ANI
08699                   if (!ast_strlen_zero(e->ring.callingani)) {
08700                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
08701                      ast_shrink_phone_number(plancallingani);
08702                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
08703                   } else {
08704                      pri->pvts[chanpos]->cid_ani[0] = '\0';
08705                   }
08706 #endif
08707                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
08708                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
08709                } else {
08710                   pri->pvts[chanpos]->cid_num[0] = '\0';
08711                   pri->pvts[chanpos]->cid_ani[0] = '\0';
08712                   pri->pvts[chanpos]->cid_name[0] = '\0';
08713                   pri->pvts[chanpos]->cid_ton = 0;
08714                }
08715                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
08716                           e->ring.redirectingnum, e->ring.callingplanrdnis);
08717                /* If immediate=yes go to s|1 */
08718                if (pri->pvts[chanpos]->immediate) {
08719                   if (option_verbose > 2)
08720                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
08721                   pri->pvts[chanpos]->exten[0] = 's';
08722                   pri->pvts[chanpos]->exten[1] = '\0';
08723                }
08724                /* Get called number */
08725                else if (!ast_strlen_zero(e->ring.callednum)) {
08726                   ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
08727                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08728                } else
08729                   pri->pvts[chanpos]->exten[0] = '\0';
08730                /* Set DNID on all incoming calls -- even immediate */
08731                if (!ast_strlen_zero(e->ring.callednum))
08732                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08733                /* No number yet, but received "sending complete"? */
08734                if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
08735                   if (option_verbose > 2)
08736                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
08737                   pri->pvts[chanpos]->exten[0] = 's';
08738                   pri->pvts[chanpos]->exten[1] = '\0';
08739                }
08740                /* Make sure extension exists (or in overlap dial mode, can exist) */
08741                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
08742                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08743                   /* Setup law */
08744                   int law;
08745                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
08746                      /* Set to audio mode at this point */
08747                      law = 1;
08748                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08749                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
08750                   }
08751                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
08752                      law = ZT_LAW_ALAW;
08753                   else
08754                      law = ZT_LAW_MULAW;
08755                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
08756                   if (res < 0) 
08757                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
08758                   res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
08759                   if (res < 0)
08760                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
08761                   if (e->ring.complete || !pri->overlapdial) {
08762                      /* Just announce proceeding */
08763                      pri->pvts[chanpos]->proceeding = 1;
08764                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
08765                   } else {
08766                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
08767                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08768                      else
08769                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08770                   }
08771                   /* Get the use_callingpres state */
08772                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
08773                
08774                   /* Start PBX */
08775                   if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08776                      /* Release the PRI lock while we create the channel */
08777                      ast_mutex_unlock(&pri->lock);
08778                      if (crv) {
08779                         /* Set bearer and such */
08780                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
08781                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08782                         pri->pvts[chanpos]->owner = &inuse;
08783                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
08784                      } else {
08785                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08786                      }
08787                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
08788                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
08789                      }
08790                      if (e->ring.ani2 >= 0) {
08791                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
08792                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08793                      }
08794 
08795 #ifdef SUPPORT_USERUSER
08796                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
08797                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08798                      }
08799 #endif
08800 
08801                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08802                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08803                      if (e->ring.redirectingreason >= 0)
08804                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08805                      
08806                      ast_mutex_lock(&pri->lock);
08807                      pthread_attr_init(&attr);
08808                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08809                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
08810                         if (option_verbose > 2)
08811                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
08812                               plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
08813                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08814                      } else {
08815                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08816                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08817                         if (c)
08818                            ast_hangup(c);
08819                         else {
08820                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08821                            pri->pvts[chanpos]->call = NULL;
08822                         }
08823                      }
08824                      pthread_attr_destroy(&attr);
08825                   } else  {
08826                      ast_mutex_unlock(&pri->lock);
08827                      /* Release PRI lock while we create the channel */
08828                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
08829                      ast_mutex_lock(&pri->lock);
08830                      if (c) {
08831                         char calledtonstr[10];
08832                         if (e->ring.ani2 >= 0) {
08833                            snprintf(ani2str, 5, "%d", e->ring.ani2);
08834                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08835                         }
08836 
08837 #ifdef SUPPORT_USERUSER
08838                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
08839                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08840                         }
08841 #endif
08842 
08843                         if (e->ring.redirectingreason >= 0)
08844                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08845                      
08846                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08847                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08848                         if (option_verbose > 2)
08849                            ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
08850                               plancallingnum, pri->pvts[chanpos]->exten, 
08851                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08852                         zt_enable_ec(pri->pvts[chanpos]);
08853                      } else {
08854                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08855                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08856                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08857                         pri->pvts[chanpos]->call = NULL;
08858                      }
08859                   }
08860                } else {
08861                   if (option_verbose > 2)
08862                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
08863                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
08864                            pri->pvts[chanpos]->prioffset, pri->span);
08865                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
08866                   pri->pvts[chanpos]->call = NULL;
08867                   pri->pvts[chanpos]->exten[0] = '\0';
08868                }
08869                if (crv)
08870                   ast_mutex_unlock(&crv->lock);
08871                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08872             } else {
08873                if (e->ring.flexible)
08874                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
08875                else
08876                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
08877             }
08878             break;
08879          case PRI_EVENT_RINGING:
08880             chanpos = pri_find_principle(pri, e->ringing.channel);
08881             if (chanpos < 0) {
08882                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
08883                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08884             } else {
08885                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
08886                if (chanpos < 0) {
08887                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
08888                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08889                } else {
08890                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08891                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
08892                      zt_enable_ec(pri->pvts[chanpos]);
08893                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
08894                      pri->pvts[chanpos]->alerting = 1;
08895                   } else
08896                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
08897 #ifdef PRI_PROGRESS_MASK
08898                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08899 #else
08900                   if (e->ringing.progress == 8) {
08901 #endif
08902                      /* Now we can do call progress detection */
08903                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08904                         /* RINGING detection isn't required because we got ALERTING signal */
08905                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
08906                         pri->pvts[chanpos]->dsp_features = 0;
08907                      }
08908                   }
08909 
08910 #ifdef SUPPORT_USERUSER
08911                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
08912                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->ringing.useruserinfo);
08913                   }
08914 #endif
08915 
08916                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08917                }
08918             }
08919             break;
08920          case PRI_EVENT_PROGRESS:
08921             /* Get chan value if e->e is not PRI_EVNT_RINGING */
08922             chanpos = pri_find_principle(pri, e->proceeding.channel);
08923             if (chanpos > -1) {
08924 #ifdef PRI_PROGRESS_MASK
08925                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
08926 #else
08927                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
08928 #endif
08929                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
08930 
08931                   if (e->proceeding.cause > -1) {
08932                      if (option_verbose > 2)
08933                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
08934 
08935                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
08936                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
08937                         if (pri->pvts[chanpos]->owner) {
08938                            if (option_verbose > 2)
08939                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
08940 
08941                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
08942                            f.subclass = AST_CONTROL_BUSY;
08943                         }
08944                      }
08945                   }
08946                   
08947                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08948                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
08949                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08950                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08951 #ifdef PRI_PROGRESS_MASK
08952                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08953 #else
08954                   if (e->proceeding.progress == 8) {
08955 #endif
08956                      /* Now we can do call progress detection */
08957                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08958                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08959                         pri->pvts[chanpos]->dsp_features = 0;
08960                      }
08961                   }
08962                   pri->pvts[chanpos]->progress = 1;
08963                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08964                }
08965             }
08966             break;
08967          case PRI_EVENT_PROCEEDING:
08968             chanpos = pri_find_principle(pri, e->proceeding.channel);
08969             if (chanpos > -1) {
08970                if (!pri->pvts[chanpos]->proceeding) {
08971                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
08972                   
08973                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08974                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
08975                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08976                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08977 #ifdef PRI_PROGRESS_MASK
08978                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08979 #else
08980                   if (e->proceeding.progress == 8) {
08981 #endif
08982                      /* Now we can do call progress detection */
08983                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08984                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08985                         pri->pvts[chanpos]->dsp_features = 0;
08986                      }
08987                      /* Bring voice path up */
08988                      f.subclass = AST_CONTROL_PROGRESS;
08989                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
08990                   }
08991                   pri->pvts[chanpos]->proceeding = 1;
08992                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08993                }
08994             }
08995             break;
08996          case PRI_EVENT_FACNAME:
08997             chanpos = pri_find_principle(pri, e->facname.channel);
08998             if (chanpos < 0) {
08999                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09000                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09001             } else {
09002                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09003                if (chanpos < 0) {
09004                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09005                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09006                } else {
09007                   /* Re-use *69 field for PRI */
09008                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09009                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09010                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09011                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09012                   zt_enable_ec(pri->pvts[chanpos]);
09013                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09014                }
09015             }
09016             break;            
09017          case PRI_EVENT_ANSWER:
09018             chanpos = pri_find_principle(pri, e->answer.channel);
09019             if (chanpos < 0) {
09020                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09021                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09022             } else {
09023                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09024                if (chanpos < 0) {
09025                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09026                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09027                } else {
09028                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09029                   /* Now we can do call progress detection */
09030 
09031                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09032                    * By this time, we need DTMF detection and other features that were previously disabled
09033                    * -- Matt F */
09034                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09035                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09036                      pri->pvts[chanpos]->dsp_features = 0;
09037                   }
09038                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09039                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09040                      x = ZT_START;
09041                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09042                      if (res < 0) {
09043                         if (errno != EINPROGRESS) {
09044                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09045                         }
09046                      }
09047                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09048                      pri->pvts[chanpos]->dialing = 1;
09049                      /* Send any "w" waited stuff */
09050                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09051                      if (res < 0) {
09052                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09053                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09054                      } else 
09055                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
09056                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09057                   } else if (pri->pvts[chanpos]->confirmanswer) {
09058                      ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
09059                   } else {
09060                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
09061                      /* Enable echo cancellation if it's not on already */
09062                      zt_enable_ec(pri->pvts[chanpos]);
09063                   }
09064 
09065 #ifdef SUPPORT_USERUSER
09066                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
09067                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->answer.useruserinfo);
09068                   }
09069 #endif
09070 
09071                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09072                }
09073             }
09074             break;            
09075          case PRI_EVENT_HANGUP:
09076             chanpos = pri_find_principle(pri, e->hangup.channel);
09077             if (chanpos < 0) {
09078                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
09079                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09080             } else {
09081                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09082                if (chanpos > -1) {
09083                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09084                   if (!pri->pvts[chanpos]->alreadyhungup) {
09085                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
09086                      pri->pvts[chanpos]->alreadyhungup = 1;
09087                      if (pri->pvts[chanpos]->realcall) 
09088                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09089                      else if (pri->pvts[chanpos]->owner) {
09090                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
09091                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09092                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09093                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09094                         else {
09095                            switch (e->hangup.cause) {
09096                               case PRI_CAUSE_USER_BUSY:
09097                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09098                                  break;
09099                               case PRI_CAUSE_CALL_REJECTED:
09100                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09101                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09102                               case PRI_CAUSE_SWITCH_CONGESTION:
09103                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09104                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09105                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09106                                  break;
09107                               default:
09108                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09109                            }
09110                         }
09111                      }
09112                      if (option_verbose > 2) 
09113                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
09114                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
09115                   } else {
09116                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09117                      pri->pvts[chanpos]->call = NULL;
09118                   }
09119                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09120                      if (option_verbose > 2)
09121                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
09122                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09123                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09124                      pri->pvts[chanpos]->resetting = 1;
09125                   }
09126                   if (e->hangup.aoc_units > -1)
09127                      if (option_verbose > 2)
09128                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09129                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09130 
09131 #ifdef SUPPORT_USERUSER
09132                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09133                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09134                   }
09135 #endif
09136 
09137                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09138                } else {
09139                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
09140                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09141                }
09142             } 
09143             break;
09144 #ifndef PRI_EVENT_HANGUP_REQ
09145 #error please update libpri
09146 #endif
09147          case PRI_EVENT_HANGUP_REQ:
09148             chanpos = pri_find_principle(pri, e->hangup.channel);
09149             if (chanpos < 0) {
09150                ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
09151                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09152             } else {
09153                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09154                if (chanpos > -1) {
09155                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09156                   if (pri->pvts[chanpos]->realcall) 
09157                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09158                   else if (pri->pvts[chanpos]->owner) {
09159                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09160                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09161                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09162                      else {
09163                         switch (e->hangup.cause) {
09164                            case PRI_CAUSE_USER_BUSY:
09165                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09166                               break;
09167                            case PRI_CAUSE_CALL_REJECTED:
09168                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09169                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09170                            case PRI_CAUSE_SWITCH_CONGESTION:
09171                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09172                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09173                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09174                               break;
09175                            default:
09176                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09177                         }
09178                      }
09179                      if (option_verbose > 2) 
09180                         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);
09181                      if (e->hangup.aoc_units > -1)
09182                         if (option_verbose > 2)
09183                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09184                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09185                   } else {
09186                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09187                      pri->pvts[chanpos]->call = NULL;
09188                   }
09189                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09190                      if (option_verbose > 2)
09191                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
09192                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09193                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09194                      pri->pvts[chanpos]->resetting = 1;
09195                   }
09196 
09197 #ifdef SUPPORT_USERUSER
09198                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09199                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09200                   }
09201 #endif
09202 
09203                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09204                } else {
09205                   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);
09206                }
09207             } 
09208             break;
09209          case PRI_EVENT_HANGUP_ACK:
09210             chanpos = pri_find_principle(pri, e->hangup.channel);
09211             if (chanpos < 0) {
09212                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
09213                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09214             } else {
09215                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09216                if (chanpos > -1) {
09217                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09218                   pri->pvts[chanpos]->call = NULL;
09219                   pri->pvts[chanpos]->resetting = 0;
09220                   if (pri->pvts[chanpos]->owner) {
09221                      if (option_verbose > 2) 
09222                         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);
09223                   }
09224 
09225 #ifdef SUPPORT_USERUSER
09226                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09227                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09228                   }
09229 #endif
09230 
09231                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09232                }
09233             }
09234             break;
09235          case PRI_EVENT_CONFIG_ERR:
09236             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
09237             break;
09238          case PRI_EVENT_RESTART_ACK:
09239             chanpos = pri_find_principle(pri, e->restartack.channel);
09240             if (chanpos < 0) {
09241                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
09242                   channel number, so we have to figure it out...  This must be why
09243                   everybody resets exactly a channel at a time. */
09244                for (x = 0; x < pri->numchans; x++) {
09245                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
09246                      chanpos = x;
09247                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09248                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
09249                            pri->pvts[chanpos]->prioffset, pri->span);
09250                      if (pri->pvts[chanpos]->realcall) 
09251                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09252                      else if (pri->pvts[chanpos]->owner) {
09253                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
09254                            pri->pvts[chanpos]->prioffset, pri->span);
09255                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09256                      }
09257                      pri->pvts[chanpos]->resetting = 0;
09258                      if (option_verbose > 2)
09259                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09260                            pri->pvts[chanpos]->prioffset, pri->span);
09261                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09262                      if (pri->resetting)
09263                         pri_check_restart(pri);
09264                      break;
09265                   }
09266                }
09267                if (chanpos < 0) {
09268                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
09269                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09270                }
09271             } else {
09272                if (pri->pvts[chanpos]) {
09273                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09274                   if (pri->pvts[chanpos]->realcall) 
09275                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09276                   else if (pri->pvts[chanpos]->owner) {
09277                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
09278                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09279                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09280                   }
09281                   pri->pvts[chanpos]->resetting = 0;
09282                   if (option_verbose > 2)
09283                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09284                            pri->pvts[chanpos]->prioffset, pri->span);
09285                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09286                   if (pri->resetting)
09287                      pri_check_restart(pri);
09288                }
09289             }
09290             break;
09291          case PRI_EVENT_SETUP_ACK:
09292             chanpos = pri_find_principle(pri, e->setup_ack.channel);
09293             if (chanpos < 0) {
09294                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
09295                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
09296             } else {
09297                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
09298                if (chanpos > -1) {
09299                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09300                   pri->pvts[chanpos]->setup_ack = 1;
09301                   /* Send any queued digits */
09302                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
09303                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
09304                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
09305                         pri->pvts[chanpos]->dialdest[x]);
09306                   }
09307                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09308                } else
09309                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
09310             }
09311             break;
09312          case PRI_EVENT_NOTIFY:
09313             chanpos = pri_find_principle(pri, e->notify.channel);
09314             if (chanpos < 0) {
09315                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
09316                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
09317             } else {
09318                struct ast_frame f = { AST_FRAME_CONTROL, };
09319                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09320                switch (e->notify.info) {
09321                case PRI_NOTIFY_REMOTE_HOLD:
09322                   f.subclass = AST_CONTROL_HOLD;
09323                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09324                   break;
09325                case PRI_NOTIFY_REMOTE_RETRIEVAL:
09326                   f.subclass = AST_CONTROL_UNHOLD;
09327                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09328                   break;
09329                }
09330                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09331             }
09332             break;
09333          default:
09334             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
09335          }
09336       }  
09337       ast_mutex_unlock(&pri->lock);
09338    }
09339    /* Never reached */
09340    return NULL;
09341 }
09342 
09343 static int start_pri(struct zt_pri *pri)
09344 {
09345    int res, x;
09346    ZT_PARAMS p;
09347    ZT_BUFFERINFO bi;
09348    struct zt_spaninfo si;
09349    int i;
09350    
09351    for (i = 0; i < NUM_DCHANS; i++) {
09352       if (!pri->dchannels[i])
09353          break;
09354       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
09355       x = pri->dchannels[i];
09356       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
09357          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
09358          return -1;
09359       }
09360       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
09361       if (res) {
09362          zt_close(pri->fds[i]);
09363          pri->fds[i] = -1;
09364          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
09365          return -1;
09366       }
09367       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
09368          zt_close(pri->fds[i]);
09369          pri->fds[i] = -1;
09370          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
09371          return -1;
09372       }
09373       memset(&si, 0, sizeof(si));
09374       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
09375       if (res) {
09376          zt_close(pri->fds[i]);
09377          pri->fds[i] = -1;
09378          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
09379       }
09380       if (!si.alarms)
09381          pri->dchanavail[i] |= DCHAN_NOTINALARM;
09382       else
09383          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
09384       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
09385       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
09386       bi.numbufs = 32;
09387       bi.bufsize = 1024;
09388       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
09389          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
09390          zt_close(pri->fds[i]);
09391          pri->fds[i] = -1;
09392          return -1;
09393       }
09394       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
09395       /* Force overlap dial if we're doing GR-303! */
09396       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
09397          pri->overlapdial = 1;
09398       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
09399       /* Enslave to master if appropriate */
09400       if (i)
09401          pri_enslave(pri->dchans[0], pri->dchans[i]);
09402       if (!pri->dchans[i]) {
09403          zt_close(pri->fds[i]);
09404          pri->fds[i] = -1;
09405          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
09406          return -1;
09407       }
09408       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
09409       pri_set_nsf(pri->dchans[i], pri->nsf);
09410 #ifdef PRI_GETSET_TIMERS
09411       for (x = 0; x < PRI_MAX_TIMERS; x++) {
09412          if (pritimers[x] != 0)
09413             pri_set_timer(pri->dchans[i], x, pritimers[x]);
09414       }
09415 #endif
09416    }
09417    /* Assume primary is the one we use */
09418    pri->pri = pri->dchans[0];
09419    pri->resetpos = -1;
09420    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
09421       for (i = 0; i < NUM_DCHANS; i++) {
09422          if (!pri->dchannels[i])
09423             break;
09424          zt_close(pri->fds[i]);
09425          pri->fds[i] = -1;
09426       }
09427       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
09428       return -1;
09429    }
09430    return 0;
09431 }
09432 
09433 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
09434 {
09435    int which, span;
09436    char *ret = NULL;
09437 
09438    if (pos != rpos)
09439       return ret;
09440 
09441    for (which = span = 0; span < NUM_SPANS; span++) {
09442       if (pris[span].pri && ++which > state) {
09443          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
09444          break;
09445       }
09446    }
09447    return ret;
09448 }
09449 
09450 static char *complete_span_4(const char *line, const char *word, int pos, int state)
09451 {
09452    return complete_span_helper(line,word,pos,state,3);
09453 }
09454 
09455 static char *complete_span_5(const char *line, const char *word, int pos, int state)
09456 {
09457    return complete_span_helper(line,word,pos,state,4);
09458 }
09459 
09460 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
09461 {
09462    int myfd;
09463 
09464    if (!strncasecmp(argv[1], "set", 3)) {
09465       if (argc < 5) 
09466          return RESULT_SHOWUSAGE;
09467 
09468       if (ast_strlen_zero(argv[4]))
09469          return RESULT_SHOWUSAGE;
09470 
09471       myfd = open(argv[4], O_CREAT|O_WRONLY);
09472       if (myfd < 0) {
09473          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
09474          return RESULT_SUCCESS;
09475       }
09476 
09477       ast_mutex_lock(&pridebugfdlock);
09478 
09479       if (pridebugfd >= 0)
09480          close(pridebugfd);
09481 
09482       pridebugfd = myfd;
09483       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
09484       
09485       ast_mutex_unlock(&pridebugfdlock);
09486 
09487       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
09488    } else {
09489       /* Assume it is unset */
09490       ast_mutex_lock(&pridebugfdlock);
09491       close(pridebugfd);
09492       pridebugfd = -1;
09493       ast_cli(fd, "PRI debug output to file disabled\n");
09494       ast_mutex_unlock(&pridebugfdlock);
09495    }
09496 
09497    return RESULT_SUCCESS;
09498 }
09499 
09500 static int handle_pri_debug(int fd, int argc, char *argv[])
09501 {
09502    int span;
09503    int x;
09504    if (argc < 4) {
09505       return RESULT_SHOWUSAGE;
09506    }
09507    span = atoi(argv[3]);
09508    if ((span < 1) || (span > NUM_SPANS)) {
09509       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
09510       return RESULT_SUCCESS;
09511    }
09512    if (!pris[span-1].pri) {
09513       ast_cli(fd, "No PRI running on span %d\n", span);
09514       return RESULT_SUCCESS;
09515    }
09516    for (x = 0; x < NUM_DCHANS; x++) {
09517       if (pris[span-1].dchans[x])
09518          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09519                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09520                                                PRI_DEBUG_Q921_STATE);
09521    }
09522    ast_cli(fd, "Enabled debugging on span %d\n", span);
09523    return RESULT_SUCCESS;
09524 }
09525 
09526 
09527 
09528 static int handle_pri_no_debug(int fd, int argc, char *argv[])
09529 {
09530    int span;
09531    int x;
09532    if (argc < 5)
09533       return RESULT_SHOWUSAGE;
09534    span = atoi(argv[4]);
09535    if ((span < 1) || (span > NUM_SPANS)) {
09536       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09537       return RESULT_SUCCESS;
09538    }
09539    if (!pris[span-1].pri) {
09540       ast_cli(fd, "No PRI running on span %d\n", span);
09541       return RESULT_SUCCESS;
09542    }
09543    for (x = 0; x < NUM_DCHANS; x++) {
09544       if (pris[span-1].dchans[x])
09545          pri_set_debug(pris[span-1].dchans[x], 0);
09546    }
09547    ast_cli(fd, "Disabled debugging on span %d\n", span);
09548    return RESULT_SUCCESS;
09549 }
09550 
09551 static int handle_pri_really_debug(int fd, int argc, char *argv[])
09552 {
09553    int span;
09554    int x;
09555    if (argc < 5)
09556       return RESULT_SHOWUSAGE;
09557    span = atoi(argv[4]);
09558    if ((span < 1) || (span > NUM_SPANS)) {
09559       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09560       return RESULT_SUCCESS;
09561    }
09562    if (!pris[span-1].pri) {
09563       ast_cli(fd, "No PRI running on span %d\n", span);
09564       return RESULT_SUCCESS;
09565    }
09566    for (x = 0; x < NUM_DCHANS; x++) {
09567       if (pris[span-1].dchans[x])
09568          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09569                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09570                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
09571    }
09572    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
09573    return RESULT_SUCCESS;
09574 }
09575 
09576 static void build_status(char *s, size_t len, int status, int active)
09577 {
09578    if (!s || len < 1) {
09579       return;
09580    }
09581    s[0] = '\0';
09582    if (status & DCHAN_PROVISIONED)
09583       strncat(s, "Provisioned, ", len - strlen(s) - 1);
09584    if (!(status & DCHAN_NOTINALARM))
09585       strncat(s, "In Alarm, ", len - strlen(s) - 1);
09586    if (status & DCHAN_UP)
09587       strncat(s, "Up", len - strlen(s) - 1);
09588    else
09589       strncat(s, "Down", len - strlen(s) - 1);
09590    if (active)
09591       strncat(s, ", Active", len - strlen(s) - 1);
09592    else
09593       strncat(s, ", Standby", len - strlen(s) - 1);
09594    s[len - 1] = '\0';
09595 }
09596 
09597 static int handle_pri_show_spans(int fd, int argc, char *argv[])
09598 {
09599    int span;
09600    int x;
09601    char status[256];
09602    if (argc != 3)
09603       return RESULT_SHOWUSAGE;
09604 
09605    for (span = 0; span < NUM_SPANS; span++) {
09606       if (pris[span].pri) {
09607          for (x = 0; x < NUM_DCHANS; x++) {
09608             if (pris[span].dchannels[x]) {
09609                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
09610                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
09611             }
09612          }
09613       }
09614    }
09615    return RESULT_SUCCESS;
09616 }
09617 
09618 static int handle_pri_show_span(int fd, int argc, char *argv[])
09619 {
09620    int span;
09621    int x;
09622    char status[256];
09623    if (argc < 4)
09624       return RESULT_SHOWUSAGE;
09625    span = atoi(argv[3]);
09626    if ((span < 1) || (span > NUM_SPANS)) {
09627       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
09628       return RESULT_SUCCESS;
09629    }
09630    if (!pris[span-1].pri) {
09631       ast_cli(fd, "No PRI running on span %d\n", span);
09632       return RESULT_SUCCESS;
09633    }
09634    for (x = 0; x < NUM_DCHANS; x++) {
09635       if (pris[span-1].dchannels[x]) {
09636 #ifdef PRI_DUMP_INFO_STR
09637          char *info_str = NULL;
09638 #endif
09639          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
09640          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
09641          ast_cli(fd, "Status: %s\n", status);
09642 #ifdef PRI_DUMP_INFO_STR
09643          info_str = pri_dump_info_str(pris[span-1].pri);
09644          if (info_str) {
09645             ast_cli(fd, "%s", info_str);
09646             free(info_str);
09647          }
09648 #else
09649          pri_dump_info(pris[span-1].pri);
09650 #endif
09651          ast_cli(fd, "\n");
09652       }
09653    }
09654    return RESULT_SUCCESS;
09655 }
09656 
09657 static int handle_pri_show_debug(int fd, int argc, char *argv[])
09658 {
09659    int x;
09660    int span;
09661    int count=0;
09662    int debug=0;
09663 
09664    for (span = 0; span < NUM_SPANS; span++) {
09665            if (pris[span].pri) {
09666          for (x = 0; x < NUM_DCHANS; x++) {
09667             debug = 0;
09668                if (pris[span].dchans[x]) {
09669                   debug = pri_get_debug(pris[span].dchans[x]);
09670                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" );
09671                count++;
09672             }
09673          }
09674       }
09675 
09676    }
09677    ast_mutex_lock(&pridebugfdlock);
09678    if (pridebugfd >= 0) 
09679       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
09680    ast_mutex_unlock(&pridebugfdlock);
09681        
09682    if (!count) 
09683       ast_cli(fd, "No debug set or no PRI running\n");
09684    return RESULT_SUCCESS;
09685 }
09686 
09687 static const char pri_debug_help[] = 
09688    "Usage: pri debug span <span>\n"
09689    "       Enables debugging on a given PRI span\n";
09690    
09691 static const char pri_no_debug_help[] = 
09692    "Usage: pri no debug span <span>\n"
09693    "       Disables debugging on a given PRI span\n";
09694 
09695 static const char pri_really_debug_help[] = 
09696    "Usage: pri intensive debug span <span>\n"
09697    "       Enables debugging down to the Q.921 level\n";
09698 
09699 static const char pri_show_span_help[] = 
09700    "Usage: pri show span <span>\n"
09701    "       Displays PRI Information on a given PRI span\n";
09702 
09703 static const char pri_show_spans_help[] = 
09704    "Usage: pri show spans\n"
09705    "       Displays PRI Information\n";
09706 
09707 static struct ast_cli_entry zap_pri_cli[] = {
09708    { { "pri", "debug", "span", NULL },
09709    handle_pri_debug, "Enables PRI debugging on a span",
09710    pri_debug_help, complete_span_4 },
09711 
09712    { { "pri", "no", "debug", "span", NULL },
09713    handle_pri_no_debug, "Disables PRI debugging on a span",
09714    pri_no_debug_help, complete_span_5 },
09715 
09716    { { "pri", "intense", "debug", "span", NULL },
09717    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
09718    pri_really_debug_help, complete_span_5 },
09719 
09720    { { "pri", "show", "spans", NULL },
09721    handle_pri_show_spans, "Displays PRI Information",
09722    pri_show_spans_help },
09723 
09724    { { "pri", "show", "span", NULL },
09725    handle_pri_show_span, "Displays PRI Information",
09726    pri_show_span_help, complete_span_4 },
09727 
09728    { { "pri", "show", "debug", NULL },
09729    handle_pri_show_debug, "Displays current PRI debug settings" },
09730 
09731    { { "pri", "set", "debug", "file", NULL },
09732    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
09733 
09734    { { "pri", "unset", "debug", "file", NULL },
09735    handle_pri_set_debug_file, "Ends PRI debug output to file" },
09736 };
09737 
09738 #endif /* HAVE_PRI */
09739 
09740 static int zap_destroy_channel(int fd, int argc, char **argv)
09741 {
09742    int channel;
09743    
09744    if (argc != 4)
09745       return RESULT_SHOWUSAGE;
09746    
09747    channel = atoi(argv[3]);
09748 
09749    return zap_destroy_channel_bynum(channel);
09750 }
09751 
09752 static int setup_zap(int reload);
09753 static int zap_restart(void)
09754 {
09755    if (option_verbose > 0)
09756       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09757    while (iflist) {
09758       if (option_debug)
09759          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09760       /* Also updates iflist: */
09761       destroy_channel(NULL, iflist, 1);
09762    }
09763    if (option_debug)
09764       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09765    if (setup_zap(0) != 0) {
09766       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09767       return 1;
09768    }
09769    return 0;
09770 }
09771 
09772 static int zap_restart_cmd(int fd, int argc, char **argv)
09773 {
09774    if (argc != 2) {
09775       return RESULT_SHOWUSAGE;
09776    }
09777 
09778    if (zap_restart() != 0)
09779       return RESULT_FAILURE;
09780    return RESULT_SUCCESS;
09781 }
09782 
09783 static int action_zaprestart(struct mansession *s, const struct message *m)
09784 {
09785    if (zap_restart() != 0) {
09786       astman_send_error(s, m, "Failed rereading zaptel configuration");
09787       return 1;
09788    }
09789    astman_send_ack(s, m, "ZapRestart: Success");
09790    return 0;
09791 }
09792 
09793 static int zap_show_channels(int fd, int argc, char **argv)
09794 {
09795 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09796 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09797    struct zt_pvt *tmp = NULL;
09798    char tmps[20] = "";
09799    ast_mutex_t *lock;
09800    struct zt_pvt *start;
09801 #ifdef HAVE_PRI
09802    int trunkgroup;
09803    struct zt_pri *pri = NULL;
09804    int x;
09805 #endif
09806 
09807    lock = &iflock;
09808    start = iflist;
09809 
09810 #ifdef HAVE_PRI
09811    if (argc == 4) {
09812       if ((trunkgroup = atoi(argv[3])) < 1)
09813          return RESULT_SHOWUSAGE;
09814       for (x = 0; x < NUM_SPANS; x++) {
09815          if (pris[x].trunkgroup == trunkgroup) {
09816             pri = pris + x;
09817             break;
09818          }
09819       }
09820       if (pri) {
09821          start = pri->crvs;
09822          lock = &pri->lock;
09823       } else {
09824          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09825          return RESULT_FAILURE;
09826       }
09827    } else
09828 #endif
09829    if (argc != 3)
09830       return RESULT_SHOWUSAGE;
09831 
09832    ast_mutex_lock(lock);
09833 #ifdef HAVE_PRI
09834    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
09835 #else
09836    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
09837 #endif   
09838    
09839    tmp = start;
09840    while (tmp) {
09841       if (tmp->channel > 0) {
09842          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09843       } else
09844          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09845       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
09846       tmp = tmp->next;
09847    }
09848    ast_mutex_unlock(lock);
09849    return RESULT_SUCCESS;
09850 #undef FORMAT
09851 #undef FORMAT2
09852 }
09853 
09854 static int zap_show_channel(int fd, int argc, char **argv)
09855 {
09856    int channel;
09857    struct zt_pvt *tmp = NULL;
09858    ZT_CONFINFO ci;
09859    ZT_PARAMS ps;
09860    int x;
09861    ast_mutex_t *lock;
09862    struct zt_pvt *start;
09863 #ifdef HAVE_PRI
09864    char *c;
09865    int trunkgroup;
09866    struct zt_pri *pri=NULL;
09867 #endif
09868 
09869    lock = &iflock;
09870    start = iflist;
09871 
09872    if (argc != 4)
09873       return RESULT_SHOWUSAGE;
09874 #ifdef HAVE_PRI
09875    if ((c = strchr(argv[3], ':'))) {
09876       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09877          return RESULT_SHOWUSAGE;
09878       if ((trunkgroup < 1) || (channel < 1))
09879          return RESULT_SHOWUSAGE;
09880       for (x = 0; x < NUM_SPANS; x++) {
09881          if (pris[x].trunkgroup == trunkgroup) {
09882             pri = pris + x;
09883             break;
09884          }
09885       }
09886       if (pri) {
09887          start = pri->crvs;
09888          lock = &pri->lock;
09889       } else {
09890          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09891          return RESULT_FAILURE;
09892       }
09893    } else
09894 #endif
09895       channel = atoi(argv[3]);
09896 
09897    ast_mutex_lock(lock);
09898    tmp = start;
09899    while (tmp) {
09900       if (tmp->channel == channel) {
09901 #ifdef HAVE_PRI
09902          if (pri) 
09903             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
09904          else
09905 #endif         
09906          ast_cli(fd, "Channel: %d\n", tmp->channel);
09907          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
09908          ast_cli(fd, "Span: %d\n", tmp->span);
09909          ast_cli(fd, "Extension: %s\n", tmp->exten);
09910          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
09911          ast_cli(fd, "Context: %s\n", tmp->context);
09912          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
09913          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
09914          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
09915          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
09916          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
09917          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
09918          ast_cli(fd, "Radio: %d\n", tmp->radio);
09919          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
09920          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)" : "");
09921          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)" : "");
09922          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)" : "");
09923          ast_cli(fd, "Confno: %d\n", tmp->confno);
09924          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
09925          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
09926          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
09927          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
09928          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
09929          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
09930          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
09931          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
09932          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
09933          if (tmp->master)
09934             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
09935          for (x = 0; x < MAX_SLAVES; x++) {
09936             if (tmp->slaves[x])
09937                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
09938          }
09939 #ifdef HAVE_PRI
09940          if (tmp->pri) {
09941             ast_cli(fd, "PRI Flags: ");
09942             if (tmp->resetting)
09943                ast_cli(fd, "Resetting ");
09944             if (tmp->call)
09945                ast_cli(fd, "Call ");
09946             if (tmp->bearer)
09947                ast_cli(fd, "Bearer ");
09948             ast_cli(fd, "\n");
09949             if (tmp->logicalspan) 
09950                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
09951             else
09952                ast_cli(fd, "PRI Logical Span: Implicit\n");
09953          }
09954             
09955 #endif
09956          memset(&ci, 0, sizeof(ci));
09957          ps.channo = tmp->channel;
09958          if (tmp->subs[SUB_REAL].zfd > -1) {
09959             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
09960                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
09961             }
09962 #ifdef ZT_GETCONFMUTE
09963             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
09964                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
09965             }
09966 #endif
09967             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
09968                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
09969             } else {
09970                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
09971             }
09972          }
09973          ast_mutex_unlock(lock);
09974          return RESULT_SUCCESS;
09975       }
09976       tmp = tmp->next;
09977    }
09978    
09979    ast_cli(fd, "Unable to find given channel %d\n", channel);
09980    ast_mutex_unlock(lock);
09981    return RESULT_FAILURE;
09982 }
09983 
09984 static char zap_show_cadences_help[] =
09985 "Usage: zap show cadences\n"
09986 "       Shows all cadences currently defined\n";
09987 
09988 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
09989 {
09990    int i, j;
09991    for (i = 0; i < num_cadence; i++) {
09992       char output[1024];
09993       char tmp[16], tmp2[64];
09994       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09995       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09996 
09997       for (j = 0; j < 16; j++) {
09998          if (cadences[i].ringcadence[j] == 0)
09999             break;
10000          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
10001          if (cidrings[i] * 2 - 1 == j)
10002             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
10003          else
10004             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
10005          if (j != 0)
10006             strncat(output, ",", sizeof(output) - strlen(output) - 1);
10007          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
10008       }
10009       ast_cli(fd,"%s\n",output);
10010    }
10011    return 0;
10012 }
10013 
10014 /* Based on irqmiss.c */
10015 static int zap_show_status(int fd, int argc, char *argv[]) {
10016    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
10017    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
10018 
10019    int span;
10020    int res;
10021    char alarms[50];
10022 
10023    int ctl;
10024    ZT_SPANINFO s;
10025 
10026    ctl = open("/dev/zap/ctl", O_RDWR);
10027    if (ctl < 0) {
10028       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
10029       ast_cli(fd, "No Zaptel interface found.\n");
10030       return RESULT_FAILURE;
10031    }
10032    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10033 
10034    for (span = 1; span < ZT_MAX_SPANS; ++span) {
10035       s.spanno = span;
10036       res = ioctl(ctl, ZT_SPANSTAT, &s);
10037       if (res) {
10038          continue;
10039       }
10040       alarms[0] = '\0';
10041       if (s.alarms > 0) {
10042          if (s.alarms & ZT_ALARM_BLUE)
10043             strcat(alarms, "BLU/");
10044          if (s.alarms & ZT_ALARM_YELLOW)
10045             strcat(alarms, "YEL/");
10046          if (s.alarms & ZT_ALARM_RED)
10047             strcat(alarms, "RED/");
10048          if (s.alarms & ZT_ALARM_LOOPBACK)
10049             strcat(alarms, "LB/");
10050          if (s.alarms & ZT_ALARM_RECOVER)
10051             strcat(alarms, "REC/");
10052          if (s.alarms & ZT_ALARM_NOTOPEN)
10053             strcat(alarms, "NOP/");
10054          if (!strlen(alarms))
10055             strcat(alarms, "UUU/");
10056          if (strlen(alarms)) {
10057             /* Strip trailing / */
10058             alarms[strlen(alarms) - 1] = '\0';
10059          }
10060       } else {
10061          if (s.numchans)
10062             strcpy(alarms, "OK");
10063          else
10064             strcpy(alarms, "UNCONFIGURED");
10065       }
10066 
10067       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
10068    }
10069    close(ctl);
10070 
10071    return RESULT_SUCCESS;
10072 #undef FORMAT
10073 #undef FORMAT2
10074 }
10075 
10076 static char show_channels_usage[] =
10077    "Usage: zap show channels\n"
10078    "  Shows a list of available channels\n";
10079 
10080 static char show_channel_usage[] =
10081    "Usage: zap show channel <chan num>\n"
10082    "  Detailed information about a given channel\n";
10083 
10084 static char zap_show_status_usage[] =
10085    "Usage: zap show status\n"
10086    "       Shows a list of Zaptel cards with status\n";
10087 
10088 static char destroy_channel_usage[] =
10089    "Usage: zap destroy channel <chan num>\n"
10090    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
10091 
10092 static char zap_restart_usage[] =
10093    "Usage: zap restart\n"
10094    "  Restarts the zaptel channels: destroys them all and then\n"
10095    "  re-reads them from zapata.conf.\n"
10096    "  Note that this will STOP any running CALL on zaptel channels.\n"
10097    "";
10098 
10099 static struct ast_cli_entry zap_cli[] = {
10100    { { "zap", "show", "cadences", NULL },
10101    handle_zap_show_cadences, "List cadences",
10102    zap_show_cadences_help },
10103 
10104    { { "zap", "show", "channels", NULL},
10105    zap_show_channels, "Show active zapata channels",
10106    show_channels_usage },
10107 
10108    { { "zap", "show", "channel", NULL},
10109    zap_show_channel, "Show information on a channel",
10110    show_channel_usage },
10111 
10112    { { "zap", "destroy", "channel", NULL},
10113    zap_destroy_channel, "Destroy a channel",
10114    destroy_channel_usage },
10115 
10116    { { "zap", "restart", NULL},
10117    zap_restart_cmd, "Fully restart zaptel channels",
10118    zap_restart_usage },
10119 
10120    { { "zap", "show", "status", NULL},
10121    zap_show_status, "Show all Zaptel cards status",
10122    zap_show_status_usage },
10123 };
10124 
10125 #define TRANSFER  0
10126 #define HANGUP    1
10127 
10128 static int zap_fake_event(struct zt_pvt *p, int mode)
10129 {
10130    if (p) {
10131       switch (mode) {
10132          case TRANSFER:
10133             p->fake_event = ZT_EVENT_WINKFLASH;
10134             break;
10135          case HANGUP:
10136             p->fake_event = ZT_EVENT_ONHOOK;
10137             break;
10138          default:
10139             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10140       }
10141    }
10142    return 0;
10143 }
10144 static struct zt_pvt *find_channel(int channel)
10145 {
10146    struct zt_pvt *p = iflist;
10147    while (p) {
10148       if (p->channel == channel) {
10149          break;
10150       }
10151       p = p->next;
10152    }
10153    return p;
10154 }
10155 
10156 static int action_zapdndon(struct mansession *s, const struct message *m)
10157 {
10158    struct zt_pvt *p = NULL;
10159    const char *channel = astman_get_header(m, "ZapChannel");
10160 
10161    if (ast_strlen_zero(channel)) {
10162       astman_send_error(s, m, "No channel specified");
10163       return 0;
10164    }
10165    p = find_channel(atoi(channel));
10166    if (!p) {
10167       astman_send_error(s, m, "No such channel");
10168       return 0;
10169    }
10170    p->dnd = 1;
10171    astman_send_ack(s, m, "DND Enabled");
10172    return 0;
10173 }
10174 
10175 static int action_zapdndoff(struct mansession *s, const struct message *m)
10176 {
10177    struct zt_pvt *p = NULL;
10178    const char *channel = astman_get_header(m, "ZapChannel");
10179 
10180    if (ast_strlen_zero(channel)) {
10181       astman_send_error(s, m, "No channel specified");
10182       return 0;
10183    }
10184    p = find_channel(atoi(channel));
10185    if (!p) {
10186       astman_send_error(s, m, "No such channel");
10187       return 0;
10188    }
10189    p->dnd = 0;
10190    astman_send_ack(s, m, "DND Disabled");
10191    return 0;
10192 }
10193 
10194 static int action_transfer(struct mansession *s, const struct message *m)
10195 {
10196    struct zt_pvt *p = NULL;
10197    const char *channel = astman_get_header(m, "ZapChannel");
10198 
10199    if (ast_strlen_zero(channel)) {
10200       astman_send_error(s, m, "No channel specified");
10201       return 0;
10202    }
10203    p = find_channel(atoi(channel));
10204    if (!p) {
10205       astman_send_error(s, m, "No such channel");
10206       return 0;
10207    }
10208    zap_fake_event(p,TRANSFER);
10209    astman_send_ack(s, m, "ZapTransfer");
10210    return 0;
10211 }
10212 
10213 static int action_transferhangup(struct mansession *s, const struct message *m)
10214 {
10215    struct zt_pvt *p = NULL;
10216    const char *channel = astman_get_header(m, "ZapChannel");
10217 
10218    if (ast_strlen_zero(channel)) {
10219       astman_send_error(s, m, "No channel specified");
10220       return 0;
10221    }
10222    p = find_channel(atoi(channel));
10223    if (!p) {
10224       astman_send_error(s, m, "No such channel");
10225       return 0;
10226    }
10227    zap_fake_event(p,HANGUP);
10228    astman_send_ack(s, m, "ZapHangup");
10229    return 0;
10230 }
10231 
10232 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
10233 {
10234    struct zt_pvt *p = NULL;
10235    const char *channel = astman_get_header(m, "ZapChannel");
10236    const char *number = astman_get_header(m, "Number");
10237    int i;
10238 
10239    if (ast_strlen_zero(channel)) {
10240       astman_send_error(s, m, "No channel specified");
10241       return 0;
10242    }
10243    if (ast_strlen_zero(number)) {
10244       astman_send_error(s, m, "No number specified");
10245       return 0;
10246    }
10247    p = find_channel(atoi(channel));
10248    if (!p) {
10249       astman_send_error(s, m, "No such channel");
10250       return 0;
10251    }
10252    if (!p->owner) {
10253       astman_send_error(s, m, "Channel does not have it's owner");
10254       return 0;
10255    }
10256    for (i = 0; i < strlen(number); i++) {
10257       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10258       zap_queue_frame(p, &f, NULL); 
10259    }
10260    astman_send_ack(s, m, "ZapDialOffhook");
10261    return 0;
10262 }
10263 
10264 static int action_zapshowchannels(struct mansession *s, const struct message *m)
10265 {
10266    struct zt_pvt *tmp = NULL;
10267    const char *id = astman_get_header(m, "ActionID");
10268    char idText[256] = "";
10269 
10270    astman_send_ack(s, m, "Zapata channel status will follow");
10271    if (!ast_strlen_zero(id))
10272       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10273 
10274    ast_mutex_lock(&iflock);
10275    
10276    tmp = iflist;
10277    while (tmp) {
10278       if (tmp->channel > 0) {
10279          int alarm = get_alarms(tmp);
10280          astman_append(s,
10281             "Event: ZapShowChannels\r\n"
10282             "Channel: %d\r\n"
10283             "Signalling: %s\r\n"
10284             "Context: %s\r\n"
10285             "DND: %s\r\n"
10286             "Alarm: %s\r\n"
10287             "%s"
10288             "\r\n",
10289             tmp->channel, sig2str(tmp->sig), tmp->context, 
10290             tmp->dnd ? "Enabled" : "Disabled",
10291             alarm2str(alarm), idText);
10292       } 
10293 
10294       tmp = tmp->next;
10295    }
10296 
10297    ast_mutex_unlock(&iflock);
10298    
10299    astman_append(s, 
10300       "Event: ZapShowChannelsComplete\r\n"
10301       "%s"
10302       "\r\n", 
10303       idText);
10304    return 0;
10305 }
10306 
10307 static int __unload_module(void)
10308 {
10309    int x = 0;
10310    struct zt_pvt *p, *pl;
10311 #ifdef HAVE_PRI
10312    int i;
10313    for (i = 0; i < NUM_SPANS; i++) {
10314       if (pris[i].master != AST_PTHREADT_NULL) 
10315          pthread_cancel(pris[i].master);
10316    }
10317    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
10318    ast_unregister_application(zap_send_keypad_facility_app);
10319 #endif
10320    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
10321    ast_manager_unregister( "ZapDialOffhook" );
10322    ast_manager_unregister( "ZapHangup" );
10323    ast_manager_unregister( "ZapTransfer" );
10324    ast_manager_unregister( "ZapDNDoff" );
10325    ast_manager_unregister( "ZapDNDon" );
10326    ast_manager_unregister("ZapShowChannels");
10327    ast_manager_unregister("ZapRestart");
10328    ast_channel_unregister(&zap_tech);
10329    ast_mutex_lock(&iflock);
10330    /* Hangup all interfaces if they have an owner */
10331    p = iflist;
10332    while (p) {
10333       if (p->owner)
10334          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10335       p = p->next;
10336    }
10337    ast_mutex_unlock(&iflock);
10338    ast_mutex_lock(&monlock);
10339    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10340       pthread_cancel(monitor_thread);
10341       pthread_kill(monitor_thread, SIGURG);
10342       pthread_join(monitor_thread, NULL);
10343    }
10344    monitor_thread = AST_PTHREADT_STOP;
10345    ast_mutex_unlock(&monlock);
10346 
10347    ast_mutex_lock(&iflock);
10348    /* Destroy all the interfaces and free their memory */
10349    p = iflist;
10350    while (p) {
10351       /* Free any callerid */
10352       if (p->cidspill)
10353          free(p->cidspill);
10354       /* Close the zapata thingy */
10355       if (p->subs[SUB_REAL].zfd > -1)
10356          zt_close(p->subs[SUB_REAL].zfd);
10357       pl = p;
10358       p = p->next;
10359       x++;
10360       /* Free associated memory */
10361       if (pl)
10362          destroy_zt_pvt(&pl);
10363       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10364    }
10365    iflist = NULL;
10366    ifcount = 0;
10367    ast_mutex_unlock(&iflock);
10368 #ifdef HAVE_PRI      
10369    for (i = 0; i < NUM_SPANS; i++) {
10370       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10371          pthread_join(pris[i].master, NULL);
10372       zt_close(pris[i].fds[i]);
10373    }
10374 #endif
10375    return 0;
10376 }
10377 
10378 static int unload_module(void)
10379 {
10380 #ifdef HAVE_PRI      
10381    int y;
10382    for (y = 0; y < NUM_SPANS; y++)
10383       ast_mutex_destroy(&pris[y].lock);
10384 #endif
10385    return __unload_module();
10386 }
10387 
10388 static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
10389 {
10390    char *c, *chan;
10391    int x, start, finish;
10392    struct zt_pvt *tmp;
10393 #ifdef HAVE_PRI
10394    struct zt_pri *pri;
10395    int trunkgroup, y;
10396 #endif
10397    
10398    if ((reload == 0) && (conf.chan.sig < 0)) {
10399       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10400       return -1;
10401    }
10402 
10403    c = ast_strdupa(value);
10404 
10405 #ifdef HAVE_PRI
10406    pri = NULL;
10407    if (iscrv) {
10408       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10409          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
10410          return -1;
10411       }
10412       if (trunkgroup < 1) {
10413          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
10414          return -1;
10415       }
10416       c += y;
10417       for (y = 0; y < NUM_SPANS; y++) {
10418          if (pris[y].trunkgroup == trunkgroup) {
10419             pri = pris + y;
10420             break;
10421          }
10422       }
10423       if (!pri) {
10424          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
10425          return -1;
10426       }
10427    }
10428 #endif         
10429 
10430    while ((chan = strsep(&c, ","))) {
10431       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10432          /* Range */
10433       } else if (sscanf(chan, "%d", &start)) {
10434          /* Just one */
10435          finish = start;
10436       } else if (!strcasecmp(chan, "pseudo")) {
10437          finish = start = CHAN_PSEUDO;
10438          if (found_pseudo)
10439             *found_pseudo = 1;
10440       } else {
10441          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
10442          return -1;
10443       }
10444       if (finish < start) {
10445          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10446          x = finish;
10447          finish = start;
10448          start = x;
10449       }
10450 
10451       for (x = start; x <= finish; x++) {
10452 #ifdef HAVE_PRI
10453          tmp = mkintf(x, conf, pri, reload);
10454 #else       
10455          tmp = mkintf(x, conf, NULL, reload);
10456 #endif         
10457 
10458          if (tmp) {
10459             if (option_verbose > 2) {
10460 #ifdef HAVE_PRI
10461                if (pri)
10462                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
10463                else
10464 #endif
10465                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10466             }
10467          } else {
10468             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
10469                (reload == 1) ? "reconfigure" : "register", value);
10470             return -1;
10471          }
10472       }
10473    }
10474 
10475    return 0;
10476 }
10477 
10478 /** The length of the parameters list of 'zapchan'. 
10479  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10480 #define MAX_CHANLIST_LEN 80
10481 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
10482 {
10483    struct zt_pvt *tmp;
10484    char *ringc; /* temporary string for parsing the dring number. */
10485    int y;
10486    int found_pseudo = 0;
10487         char zapchan[MAX_CHANLIST_LEN] = {};
10488 
10489    for (; v; v = v->next) {
10490       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
10491          continue;
10492 
10493       /* Create the interface list */
10494       if (!strcasecmp(v->name, "channel")
10495 #ifdef HAVE_PRI
10496           || !strcasecmp(v->name, "crv")
10497 #endif         
10498          ) {
10499          int iscrv;
10500          if (skipchannels)
10501             continue;
10502          iscrv = !strcasecmp(v->name, "crv");
10503          if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
10504                return -1;
10505       } else if (!strcasecmp(v->name, "zapchan")) {
10506          ast_copy_string(zapchan, v->value, sizeof(zapchan));
10507       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10508          if (ast_true(v->value))
10509             confp->chan.usedistinctiveringdetection = 1;
10510       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
10511          if (ast_true(v->value))
10512             distinctiveringaftercid = 1;
10513       } else if (!strcasecmp(v->name, "dring1context")) {
10514          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
10515       } else if (!strcasecmp(v->name, "dring2context")) {
10516          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
10517       } else if (!strcasecmp(v->name, "dring3context")) {
10518          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
10519       } else if (!strcasecmp(v->name, "dring1")) {
10520          ringc = v->value;
10521          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10522       } else if (!strcasecmp(v->name, "dring2")) {
10523          ringc = v->value;
10524          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10525       } else if (!strcasecmp(v->name, "dring3")) {
10526          ringc = v->value;
10527          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10528       } else if (!strcasecmp(v->name, "usecallerid")) {
10529          confp->chan.use_callerid = ast_true(v->value);
10530       } else if (!strcasecmp(v->name, "cidsignalling")) {
10531          if (!strcasecmp(v->value, "bell"))
10532             confp->chan.cid_signalling = CID_SIG_BELL;
10533          else if (!strcasecmp(v->value, "v23"))
10534             confp->chan.cid_signalling = CID_SIG_V23;
10535          else if (!strcasecmp(v->value, "dtmf"))
10536             confp->chan.cid_signalling = CID_SIG_DTMF;
10537          else if (!strcasecmp(v->value, "smdi"))
10538             confp->chan.cid_signalling = CID_SIG_SMDI;
10539          else if (!strcasecmp(v->value, "v23_jp"))
10540             confp->chan.cid_signalling = CID_SIG_V23_JP;
10541          else if (ast_true(v->value))
10542             confp->chan.cid_signalling = CID_SIG_BELL;
10543       } else if (!strcasecmp(v->name, "cidstart")) {
10544          if (!strcasecmp(v->value, "ring"))
10545             confp->chan.cid_start = CID_START_RING;
10546          else if (!strcasecmp(v->value, "polarity"))
10547             confp->chan.cid_start = CID_START_POLARITY;
10548          else if (ast_true(v->value))
10549             confp->chan.cid_start = CID_START_RING;
10550       } else if (!strcasecmp(v->name, "threewaycalling")) {
10551          confp->chan.threewaycalling = ast_true(v->value);
10552       } else if (!strcasecmp(v->name, "cancallforward")) {
10553          confp->chan.cancallforward = ast_true(v->value);
10554       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10555          if (ast_true(v->value)) 
10556             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
10557          else
10558             confp->chan.dtmfrelax = 0;
10559       } else if (!strcasecmp(v->name, "mailbox")) {
10560          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
10561       } else if (!strcasecmp(v->name, "adsi")) {
10562          confp->chan.adsi = ast_true(v->value);
10563       } else if (!strcasecmp(v->name, "usesmdi")) {
10564          confp->chan.use_smdi = ast_true(v->value);
10565       } else if (!strcasecmp(v->name, "smdiport")) {
10566          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
10567       } else if (!strcasecmp(v->name, "transfer")) {
10568          confp->chan.transfer = ast_true(v->value);
10569       } else if (!strcasecmp(v->name, "canpark")) {
10570          confp->chan.canpark = ast_true(v->value);
10571       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10572          confp->chan.echocanbridged = ast_true(v->value);
10573       } else if (!strcasecmp(v->name, "busydetect")) {
10574          confp->chan.busydetect = ast_true(v->value);
10575       } else if (!strcasecmp(v->name, "busycount")) {
10576          confp->chan.busycount = atoi(v->value);
10577       } else if (!strcasecmp(v->name, "busypattern")) {
10578          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
10579             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
10580          }
10581       } else if (!strcasecmp(v->name, "callprogress")) {
10582          if (ast_true(v->value))
10583             confp->chan.callprogress |= 1;
10584          else
10585             confp->chan.callprogress &= ~1;
10586       } else if (!strcasecmp(v->name, "faxdetect")) {
10587          if (!strcasecmp(v->value, "incoming")) {
10588             confp->chan.callprogress |= 4;
10589             confp->chan.callprogress &= ~2;
10590          } else if (!strcasecmp(v->value, "outgoing")) {
10591             confp->chan.callprogress &= ~4;
10592             confp->chan.callprogress |= 2;
10593          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10594             confp->chan.callprogress |= 6;
10595          else
10596             confp->chan.callprogress &= ~6;
10597       } else if (!strcasecmp(v->name, "echocancel")) {
10598          if (!ast_strlen_zero(v->value)) {
10599             y = atoi(v->value);
10600          } else
10601             y = 0;
10602          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
10603             confp->chan.echocancel = y;
10604          else {
10605             confp->chan.echocancel = ast_true(v->value);
10606             if (confp->chan.echocancel)
10607                confp->chan.echocancel=128;
10608          }
10609       } else if (!strcasecmp(v->name, "echotraining")) {
10610          if (sscanf(v->value, "%d", &y) == 1) {
10611             if ((y < 10) || (y > 4000)) {
10612                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
10613             } else {
10614                confp->chan.echotraining = y;
10615             }
10616          } else if (ast_true(v->value)) {
10617             confp->chan.echotraining = 400;
10618          } else
10619             confp->chan.echotraining = 0;
10620       } else if (!strcasecmp(v->name, "hidecallerid")) {
10621          confp->chan.hidecallerid = ast_true(v->value);
10622       } else if (!strcasecmp(v->name, "hidecalleridname")) {
10623          confp->chan.hidecalleridname = ast_true(v->value);
10624       } else if (!strcasecmp(v->name, "pulsedial")) {
10625          confp->chan.pulse = ast_true(v->value);
10626       } else if (!strcasecmp(v->name, "callreturn")) {
10627          confp->chan.callreturn = ast_true(v->value);
10628       } else if (!strcasecmp(v->name, "callwaiting")) {
10629          confp->chan.callwaiting = ast_true(v->value);
10630       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10631          confp->chan.callwaitingcallerid = ast_true(v->value);
10632       } else if (!strcasecmp(v->name, "context")) {
10633          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
10634       } else if (!strcasecmp(v->name, "language")) {
10635          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
10636       } else if (!strcasecmp(v->name, "progzone")) {
10637          ast_copy_string(progzone, v->value, sizeof(progzone));
10638       } else if (!strcasecmp(v->name, "mohinterpret") 
10639          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
10640          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
10641       } else if (!strcasecmp(v->name, "mohsuggest")) {
10642          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
10643       } else if (!strcasecmp(v->name, "stripmsd")) {
10644          confp->chan.stripmsd = atoi(v->value);
10645       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10646          numbufs = atoi(v->value);
10647       } else if (!strcasecmp(v->name, "group")) {
10648          confp->chan.group = ast_get_group(v->value);
10649       } else if (!strcasecmp(v->name, "callgroup")) {
10650          confp->chan.callgroup = ast_get_group(v->value);
10651       } else if (!strcasecmp(v->name, "pickupgroup")) {
10652          confp->chan.pickupgroup = ast_get_group(v->value);
10653       } else if (!strcasecmp(v->name, "immediate")) {
10654          confp->chan.immediate = ast_true(v->value);
10655       } else if (!strcasecmp(v->name, "transfertobusy")) {
10656          confp->chan.transfertobusy = ast_true(v->value);
10657       } else if (!strcasecmp(v->name, "rxgain")) {
10658          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
10659             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10660          }
10661       } else if (!strcasecmp(v->name, "txgain")) {
10662          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
10663             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10664          }
10665       } else if (!strcasecmp(v->name, "tonezone")) {
10666          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
10667             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10668          }
10669       } else if (!strcasecmp(v->name, "callerid")) {
10670          if (!strcasecmp(v->value, "asreceived")) {
10671             confp->chan.cid_num[0] = '\0';
10672             confp->chan.cid_name[0] = '\0';
10673          } else {
10674             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
10675          } 
10676       } else if (!strcasecmp(v->name, "fullname")) {
10677          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
10678       } else if (!strcasecmp(v->name, "cid_number")) {
10679          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
10680       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10681          confp->chan.zaptrcallerid = ast_true(v->value);
10682       } else if (!strcasecmp(v->name, "restrictcid")) {
10683          confp->chan.restrictcid = ast_true(v->value);
10684       } else if (!strcasecmp(v->name, "usecallingpres")) {
10685          confp->chan.use_callingpres = ast_true(v->value);
10686       } else if (!strcasecmp(v->name, "accountcode")) {
10687          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
10688       } else if (!strcasecmp(v->name, "amaflags")) {
10689          y = ast_cdr_amaflags2int(v->value);
10690          if (y < 0) 
10691             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10692          else
10693             confp->chan.amaflags = y;
10694       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
10695          confp->chan.polarityonanswerdelay = atoi(v->value);
10696       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
10697          confp->chan.answeronpolarityswitch = ast_true(v->value);
10698       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
10699          confp->chan.hanguponpolarityswitch = ast_true(v->value);
10700       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
10701          confp->chan.sendcalleridafter = atoi(v->value);
10702       } else if (!reload){ 
10703           if (!strcasecmp(v->name, "signalling")) {
10704             confp->chan.outsigmod = -1;
10705             if (!strcasecmp(v->value, "em")) {
10706                confp->chan.sig = SIG_EM;
10707             } else if (!strcasecmp(v->value, "em_e1")) {
10708                confp->chan.sig = SIG_EM_E1;
10709             } else if (!strcasecmp(v->value, "em_w")) {
10710                confp->chan.sig = SIG_EMWINK;
10711                confp->chan.radio = 0;
10712             } else if (!strcasecmp(v->value, "fxs_ls")) {
10713                confp->chan.sig = SIG_FXSLS;
10714                confp->chan.radio = 0;
10715             } else if (!strcasecmp(v->value, "fxs_gs")) {
10716                confp->chan.sig = SIG_FXSGS;
10717                confp->chan.radio = 0;
10718             } else if (!strcasecmp(v->value, "fxs_ks")) {
10719                confp->chan.sig = SIG_FXSKS;
10720                confp->chan.radio = 0;
10721             } else if (!strcasecmp(v->value, "fxo_ls")) {
10722                confp->chan.sig = SIG_FXOLS;
10723                confp->chan.radio = 0;
10724             } else if (!strcasecmp(v->value, "fxo_gs")) {
10725                confp->chan.sig = SIG_FXOGS;
10726                confp->chan.radio = 0;
10727             } else if (!strcasecmp(v->value, "fxo_ks")) {
10728                confp->chan.sig = SIG_FXOKS;
10729                confp->chan.radio = 0;
10730             } else if (!strcasecmp(v->value, "fxs_rx")) {
10731                confp->chan.sig = SIG_FXSKS;
10732                confp->chan.radio = 1;
10733             } else if (!strcasecmp(v->value, "fxo_rx")) {
10734                confp->chan.sig = SIG_FXOLS;
10735                confp->chan.radio = 1;
10736             } else if (!strcasecmp(v->value, "fxs_tx")) {
10737                confp->chan.sig = SIG_FXSLS;
10738                confp->chan.radio = 1;
10739             } else if (!strcasecmp(v->value, "fxo_tx")) {
10740                confp->chan.sig = SIG_FXOGS;
10741                confp->chan.radio = 1;
10742             } else if (!strcasecmp(v->value, "em_rx")) {
10743                confp->chan.sig = SIG_EM;
10744                confp->chan.radio = 1;
10745             } else if (!strcasecmp(v->value, "em_tx")) {
10746                confp->chan.sig = SIG_EM;
10747                confp->chan.radio = 1;
10748             } else if (!strcasecmp(v->value, "em_rxtx")) {
10749                confp->chan.sig = SIG_EM;
10750                confp->chan.radio = 2;
10751             } else if (!strcasecmp(v->value, "em_txrx")) {
10752                confp->chan.sig = SIG_EM;
10753                confp->chan.radio = 2;
10754             } else if (!strcasecmp(v->value, "sf")) {
10755                confp->chan.sig = SIG_SF;
10756                confp->chan.radio = 0;
10757             } else if (!strcasecmp(v->value, "sf_w")) {
10758                confp->chan.sig = SIG_SFWINK;
10759                confp->chan.radio = 0;
10760             } else if (!strcasecmp(v->value, "sf_featd")) {
10761                confp->chan.sig = SIG_FEATD;
10762                confp->chan.radio = 0;
10763             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10764                confp->chan.sig = SIG_FEATDMF;
10765                confp->chan.radio = 0;
10766             } else if (!strcasecmp(v->value, "sf_featb")) {
10767                confp->chan.sig = SIG_SF_FEATB;
10768                confp->chan.radio = 0;
10769             } else if (!strcasecmp(v->value, "sf")) {
10770                confp->chan.sig = SIG_SF;
10771                confp->chan.radio = 0;
10772             } else if (!strcasecmp(v->value, "sf_rx")) {
10773                confp->chan.sig = SIG_SF;
10774                confp->chan.radio = 1;
10775             } else if (!strcasecmp(v->value, "sf_tx")) {
10776                confp->chan.sig = SIG_SF;
10777                confp->chan.radio = 1;
10778             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10779                confp->chan.sig = SIG_SF;
10780                confp->chan.radio = 2;
10781             } else if (!strcasecmp(v->value, "sf_txrx")) {
10782                confp->chan.sig = SIG_SF;
10783                confp->chan.radio = 2;
10784             } else if (!strcasecmp(v->value, "featd")) {
10785                confp->chan.sig = SIG_FEATD;
10786                confp->chan.radio = 0;
10787             } else if (!strcasecmp(v->value, "featdmf")) {
10788                confp->chan.sig = SIG_FEATDMF;
10789                confp->chan.radio = 0;
10790             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10791                confp->chan.sig = SIG_FEATDMF_TA;
10792                confp->chan.radio = 0;
10793             } else if (!strcasecmp(v->value, "e911")) {
10794                confp->chan.sig = SIG_E911;
10795                confp->chan.radio = 0;
10796             } else if (!strcasecmp(v->value, "fgccama")) {
10797                confp->chan.sig = SIG_FGC_CAMA;
10798                confp->chan.radio = 0;
10799             } else if (!strcasecmp(v->value, "fgccamamf")) {
10800                confp->chan.sig = SIG_FGC_CAMAMF;
10801                confp->chan.radio = 0;
10802             } else if (!strcasecmp(v->value, "featb")) {
10803                confp->chan.sig = SIG_FEATB;
10804                confp->chan.radio = 0;
10805 #ifdef HAVE_PRI
10806             } else if (!strcasecmp(v->value, "pri_net")) {
10807                confp->chan.radio = 0;
10808                confp->chan.sig = SIG_PRI;
10809                confp->pri.nodetype = PRI_NETWORK;
10810             } else if (!strcasecmp(v->value, "pri_cpe")) {
10811                confp->chan.sig = SIG_PRI;
10812                confp->chan.radio = 0;
10813                confp->pri.nodetype = PRI_CPE;
10814             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10815                confp->chan.sig = SIG_GR303FXOKS;
10816                confp->chan.radio = 0;
10817                confp->pri.nodetype = PRI_NETWORK;
10818             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
10819                confp->chan.sig = SIG_GR303FXSKS;
10820                confp->chan.radio = 0;
10821                confp->pri.nodetype = PRI_CPE;
10822 #endif
10823             } else {
10824                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10825             }
10826           } else if (!strcasecmp(v->name, "outsignalling")) {
10827             if (!strcasecmp(v->value, "em")) {
10828                confp->chan.outsigmod = SIG_EM;
10829             } else if (!strcasecmp(v->value, "em_e1")) {
10830                confp->chan.outsigmod = SIG_EM_E1;
10831             } else if (!strcasecmp(v->value, "em_w")) {
10832                confp->chan.outsigmod = SIG_EMWINK;
10833             } else if (!strcasecmp(v->value, "sf")) {
10834                confp->chan.outsigmod = SIG_SF;
10835             } else if (!strcasecmp(v->value, "sf_w")) {
10836                confp->chan.outsigmod = SIG_SFWINK;
10837             } else if (!strcasecmp(v->value, "sf_featd")) {
10838                confp->chan.outsigmod = SIG_FEATD;
10839             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10840                confp->chan.outsigmod = SIG_FEATDMF;
10841             } else if (!strcasecmp(v->value, "sf_featb")) {
10842                confp->chan.outsigmod = SIG_SF_FEATB;
10843             } else if (!strcasecmp(v->value, "sf")) {
10844                confp->chan.outsigmod = SIG_SF;
10845             } else if (!strcasecmp(v->value, "featd")) {
10846                confp->chan.outsigmod = SIG_FEATD;
10847             } else if (!strcasecmp(v->value, "featdmf")) {
10848                confp->chan.outsigmod = SIG_FEATDMF;
10849             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10850                confp->chan.outsigmod = SIG_FEATDMF_TA;
10851             } else if (!strcasecmp(v->value, "e911")) {
10852                confp->chan.outsigmod = SIG_E911;
10853             } else if (!strcasecmp(v->value, "fgccama")) {
10854                confp->chan.outsigmod = SIG_FGC_CAMA;
10855             } else if (!strcasecmp(v->value, "fgccamamf")) {
10856                confp->chan.outsigmod = SIG_FGC_CAMAMF;
10857             } else if (!strcasecmp(v->value, "featb")) {
10858                confp->chan.outsigmod = SIG_FEATB;
10859             } else {
10860                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10861             }
10862 #ifdef HAVE_PRI
10863          } else if (!strcasecmp(v->name, "pridialplan")) {
10864             if (!strcasecmp(v->value, "national")) {
10865                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
10866             } else if (!strcasecmp(v->value, "unknown")) {
10867                confp->pri.dialplan = PRI_UNKNOWN + 1;
10868             } else if (!strcasecmp(v->value, "private")) {
10869                confp->pri.dialplan = PRI_PRIVATE + 1;
10870             } else if (!strcasecmp(v->value, "international")) {
10871                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
10872             } else if (!strcasecmp(v->value, "local")) {
10873                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
10874             } else if (!strcasecmp(v->value, "dynamic")) {
10875                confp->pri.dialplan = -1;
10876             } else {
10877                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10878             }
10879          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
10880             if (!strcasecmp(v->value, "national")) {
10881                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
10882             } else if (!strcasecmp(v->value, "unknown")) {
10883                confp->pri.localdialplan = PRI_UNKNOWN + 1;
10884             } else if (!strcasecmp(v->value, "private")) {
10885                confp->pri.localdialplan = PRI_PRIVATE + 1;
10886             } else if (!strcasecmp(v->value, "international")) {
10887                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
10888             } else if (!strcasecmp(v->value, "local")) {
10889                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
10890             } else if (!strcasecmp(v->value, "dynamic")) {
10891                confp->pri.localdialplan = -1;
10892             } else {
10893                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10894             }
10895          } else if (!strcasecmp(v->name, "switchtype")) {
10896             if (!strcasecmp(v->value, "national")) 
10897                confp->pri.switchtype = PRI_SWITCH_NI2;
10898             else if (!strcasecmp(v->value, "ni1"))
10899                confp->pri.switchtype = PRI_SWITCH_NI1;
10900             else if (!strcasecmp(v->value, "dms100"))
10901                confp->pri.switchtype = PRI_SWITCH_DMS100;
10902             else if (!strcasecmp(v->value, "4ess"))
10903                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
10904             else if (!strcasecmp(v->value, "5ess"))
10905                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
10906             else if (!strcasecmp(v->value, "euroisdn"))
10907                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
10908             else if (!strcasecmp(v->value, "qsig"))
10909                confp->pri.switchtype = PRI_SWITCH_QSIG;
10910             else {
10911                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
10912                return -1;
10913             }
10914          } else if (!strcasecmp(v->name, "nsf")) {
10915             if (!strcasecmp(v->value, "sdn"))
10916                confp->pri.nsf = PRI_NSF_SDN;
10917             else if (!strcasecmp(v->value, "megacom"))
10918                confp->pri.nsf = PRI_NSF_MEGACOM;
10919             else if (!strcasecmp(v->value, "tollfreemegacom"))
10920                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
10921             else if (!strcasecmp(v->value, "accunet"))
10922                confp->pri.nsf = PRI_NSF_ACCUNET;
10923             else if (!strcasecmp(v->value, "none"))
10924                confp->pri.nsf = PRI_NSF_NONE;
10925             else {
10926                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
10927                confp->pri.nsf = PRI_NSF_NONE;
10928             }
10929          } else if (!strcasecmp(v->name, "priindication")) {
10930             if (!strcasecmp(v->value, "outofband"))
10931                confp->chan.priindication_oob = 1;
10932             else if (!strcasecmp(v->value, "inband"))
10933                confp->chan.priindication_oob = 0;
10934             else
10935                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
10936                   v->value, v->lineno);
10937          } else if (!strcasecmp(v->name, "priexclusive")) {
10938             confp->chan.priexclusive = ast_true(v->value);
10939          } else if (!strcasecmp(v->name, "internationalprefix")) {
10940             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
10941          } else if (!strcasecmp(v->name, "nationalprefix")) {
10942             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
10943          } else if (!strcasecmp(v->name, "localprefix")) {
10944             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
10945          } else if (!strcasecmp(v->name, "privateprefix")) {
10946             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
10947          } else if (!strcasecmp(v->name, "unknownprefix")) {
10948             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
10949          } else if (!strcasecmp(v->name, "resetinterval")) {
10950             if (!strcasecmp(v->value, "never"))
10951                confp->pri.resetinterval = -1;
10952             else if (atoi(v->value) >= 60)
10953                confp->pri.resetinterval = atoi(v->value);
10954             else
10955                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
10956                   v->value, v->lineno);
10957          } else if (!strcasecmp(v->name, "minunused")) {
10958             confp->pri.minunused = atoi(v->value);
10959          } else if (!strcasecmp(v->name, "minidle")) {
10960             confp->pri.minidle = atoi(v->value); 
10961          } else if (!strcasecmp(v->name, "idleext")) {
10962             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
10963          } else if (!strcasecmp(v->name, "idledial")) {
10964             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
10965          } else if (!strcasecmp(v->name, "overlapdial")) {
10966             confp->pri.overlapdial = ast_true(v->value);
10967          } else if (!strcasecmp(v->name, "pritimer")) {
10968 #ifdef PRI_GETSET_TIMERS
10969             char *timerc, *c;
10970             int timer, timeridx;
10971             c = v->value;
10972             timerc = strsep(&c, ",");
10973             if (timerc) {
10974                timer = atoi(c);
10975                if (!timer)
10976                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
10977                else {
10978                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
10979                      pritimers[timeridx] = timer;
10980                   else
10981                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
10982                }
10983             } else
10984                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
10985 
10986          } else if (!strcasecmp(v->name, "facilityenable")) {
10987             confp->pri.facilityenable = ast_true(v->value);
10988 #endif /* PRI_GETSET_TIMERS */
10989 #endif /* HAVE_PRI */
10990          } else if (!strcasecmp(v->name, "cadence")) {
10991             /* setup to scan our argument */
10992             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
10993             int i;
10994             struct zt_ring_cadence new_cadence;
10995             int cid_location = -1;
10996             int firstcadencepos = 0;
10997             char original_args[80];
10998             int cadence_is_ok = 1;
10999 
11000             ast_copy_string(original_args, v->value, sizeof(original_args));
11001             /* 16 cadences allowed (8 pairs) */
11002             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]);
11003    
11004             /* Cadence must be even (on/off) */
11005             if (element_count % 2 == 1) {
11006                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
11007                cadence_is_ok = 0;
11008             }
11009    
11010             /* Ring cadences cannot be negative */
11011             for (i = 0; i < element_count; i++) {
11012                if (c[i] == 0) {
11013                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
11014                   cadence_is_ok = 0;
11015                   break;
11016                } else if (c[i] < 0) {
11017                   if (i % 2 == 1) {
11018                      /* Silence duration, negative possibly okay */
11019                      if (cid_location == -1) {
11020                         cid_location = i;
11021                         c[i] *= -1;
11022                      } else {
11023                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
11024                         cadence_is_ok = 0;
11025                         break;
11026                      }
11027                   } else {
11028                      if (firstcadencepos == 0) {
11029                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
11030                                  /* duration will be passed negative to the zaptel driver */
11031                      } else {
11032                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
11033                         cadence_is_ok = 0;
11034                         break;
11035                      }
11036                   }
11037                }
11038             }
11039    
11040             /* Substitute our scanned cadence */
11041             for (i = 0; i < 16; i++) {
11042                new_cadence.ringcadence[i] = c[i];
11043             }
11044    
11045             if (cadence_is_ok) {
11046                /* ---we scanned it without getting annoyed; now some sanity checks--- */
11047                if (element_count < 2) {
11048                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
11049                } else {
11050                   if (cid_location == -1) {
11051                      /* user didn't say; default to first pause */
11052                      cid_location = 1;
11053                   } else {
11054                      /* convert element_index to cidrings value */
11055                      cid_location = (cid_location + 1) / 2;
11056                   }
11057                   /* ---we like their cadence; try to install it--- */
11058                   if (!user_has_defined_cadences++)
11059                      /* this is the first user-defined cadence; clear the default user cadences */
11060                      num_cadence = 0;
11061                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
11062                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
11063                   else {
11064                      cadences[num_cadence] = new_cadence;
11065                      cidrings[num_cadence++] = cid_location;
11066                      if (option_verbose > 2)
11067                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
11068                   }
11069                }
11070             }
11071          } else if (!strcasecmp(v->name, "ringtimeout")) {
11072             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
11073          } else if (!strcasecmp(v->name, "prewink")) {
11074             confp->timing.prewinktime = atoi(v->value);
11075          } else if (!strcasecmp(v->name, "preflash")) {
11076             confp->timing.preflashtime = atoi(v->value);
11077          } else if (!strcasecmp(v->name, "wink")) {
11078             confp->timing.winktime = atoi(v->value);
11079          } else if (!strcasecmp(v->name, "flash")) {
11080             confp->timing.flashtime = atoi(v->value);
11081          } else if (!strcasecmp(v->name, "start")) {
11082             confp->timing.starttime = atoi(v->value);
11083          } else if (!strcasecmp(v->name, "rxwink")) {
11084             confp->timing.rxwinktime = atoi(v->value);
11085          } else if (!strcasecmp(v->name, "rxflash")) {
11086             confp->timing.rxflashtime = atoi(v->value);
11087          } else if (!strcasecmp(v->name, "debounce")) {
11088             confp->timing.debouncetime = atoi(v->value);
11089          } else if (!strcasecmp(v->name, "toneduration")) {
11090             int toneduration;
11091             int ctlfd;
11092             int res;
11093             struct zt_dialparams dps;
11094 
11095             ctlfd = open("/dev/zap/ctl", O_RDWR);
11096             if (ctlfd == -1) {
11097                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11098                return -1;
11099             }
11100 
11101             toneduration = atoi(v->value);
11102             if (toneduration > -1) {
11103                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11104                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11105                if (res < 0) {
11106                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11107                   return -1;
11108                }
11109             }
11110             close(ctlfd);
11111          } else if (!strcasecmp(v->name, "defaultcic")) {
11112             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11113          } else if (!strcasecmp(v->name, "defaultozz")) {
11114             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11115          } 
11116       } else if (!skipchannels)
11117          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11118    }
11119    if (zapchan[0]) { 
11120       /* The user has set 'zapchan' */
11121       /*< \todo pass proper line number instead of 0 */
11122       if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
11123          return -1;
11124       }
11125    }
11126    /*< \todo why check for the pseudo in the per-channel section.
11127     * Any actual use for manual setup of the pseudo channel? */
11128    if (!found_pseudo && reload == 0) {
11129       /* Make sure pseudo isn't a member of any groups if
11130          we're automatically making it. */   
11131       
11132       confp->chan.group = 0;
11133       confp->chan.callgroup = 0;
11134       confp->chan.pickupgroup = 0;
11135 
11136       tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
11137 
11138       if (tmp) {
11139          if (option_verbose > 2)
11140             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11141       } else {
11142          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11143       }
11144    }
11145    return 0;
11146 }
11147       
11148 static int setup_zap(int reload)
11149 {
11150    struct ast_config *cfg;
11151    struct ast_variable *v;
11152    struct zt_chan_conf conf = zt_chan_conf_default();
11153    int res;
11154 
11155 #ifdef HAVE_PRI
11156    char *c;
11157    int spanno;
11158    int i, x;
11159    int logicalspan;
11160    int trunkgroup;
11161    int dchannels[NUM_DCHANS];
11162 #endif
11163 
11164    cfg = ast_config_load(config);
11165 
11166    /* Error if we have no config file */
11167    if (!cfg) {
11168       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
11169       return 0;
11170    }
11171 
11172    /* It's a little silly to lock it, but we mind as well just to be sure */
11173    ast_mutex_lock(&iflock);
11174 #ifdef HAVE_PRI
11175    if (!reload) {
11176       /* Process trunkgroups first */
11177       v = ast_variable_browse(cfg, "trunkgroups");
11178       while (v) {
11179          if (!strcasecmp(v->name, "trunkgroup")) {
11180             trunkgroup = atoi(v->value);
11181             if (trunkgroup > 0) {
11182                if ((c = strchr(v->value, ','))) {
11183                   i = 0;
11184                   memset(dchannels, 0, sizeof(dchannels));
11185                   while (c && (i < NUM_DCHANS)) {
11186                      dchannels[i] = atoi(c + 1);
11187                      if (dchannels[i] < 0) {
11188                         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);
11189                      } else
11190                         i++;
11191                      c = strchr(c + 1, ',');
11192                   }
11193                   if (i) {
11194                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
11195                         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);
11196                      } else if (option_verbose > 1)
11197                         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");
11198                   } else
11199                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
11200                } else
11201                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
11202             } else
11203                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
11204          } else if (!strcasecmp(v->name, "spanmap")) {
11205             spanno = atoi(v->value);
11206             if (spanno > 0) {
11207                if ((c = strchr(v->value, ','))) {
11208                   trunkgroup = atoi(c + 1);
11209                   if (trunkgroup > 0) {
11210                      if ((c = strchr(c + 1, ','))) 
11211                         logicalspan = atoi(c + 1);
11212                      else
11213                         logicalspan = 0;
11214                      if (logicalspan >= 0) {
11215                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
11216                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11217                         } else if (option_verbose > 1) 
11218                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11219                      } else
11220                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
11221                   } else
11222                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
11223                } else
11224                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
11225             } else
11226                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
11227          } else {
11228             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
11229          }
11230          v = v->next;
11231       }
11232    }
11233 #endif
11234    
11235    /* Copy the default jb config over global_jbconf */
11236    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
11237 
11238    v = ast_variable_browse(cfg, "channels");
11239    res = process_zap(&conf, v, reload, 0);
11240    ast_mutex_unlock(&iflock);
11241    ast_config_destroy(cfg);
11242    if (res)
11243       return res;
11244    cfg = ast_config_load("users.conf");
11245    if (cfg) {
11246       char *cat;
11247       const char *chans;
11248       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
11249       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
11250          if (!strcasecmp(cat, "general"))
11251             continue;
11252          chans = ast_variable_retrieve(cfg, cat, "zapchan");
11253          if (!ast_strlen_zero(chans)) {
11254             /** \todo At this point we should probably 
11255              * duplicate conf, and pass a copy, to prevent 
11256              * one section from affecting another
11257              */
11258             process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
11259          }
11260       }
11261       ast_config_destroy(cfg);
11262    }
11263 #ifdef HAVE_PRI
11264    if (!reload) {
11265       for (x = 0; x < NUM_SPANS; x++) {
11266          if (pris[x].pvts[0]) {
11267             if (start_pri(pris + x)) {
11268                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11269                return -1;
11270             } else if (option_verbose > 1)
11271                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11272          }
11273       }
11274    }
11275 #endif
11276    /* And start the monitor for the first time */
11277    restart_monitor();
11278    return 0;
11279 }
11280 
11281 static int load_module(void)
11282 {
11283    int res;
11284 
11285 #ifdef HAVE_PRI
11286    int y,i;
11287    memset(pris, 0, sizeof(pris));
11288    for (y = 0; y < NUM_SPANS; y++) {
11289       ast_mutex_init(&pris[y].lock);
11290       pris[y].offset = -1;
11291       pris[y].master = AST_PTHREADT_NULL;
11292       for (i = 0; i < NUM_DCHANS; i++)
11293          pris[y].fds[i] = -1;
11294    }
11295    pri_set_error(zt_pri_error);
11296    pri_set_message(zt_pri_message);
11297    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
11298          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
11299 #endif
11300    res = setup_zap(0);
11301    /* Make sure we can register our Zap channel type */
11302    if (res)
11303       return AST_MODULE_LOAD_DECLINE;
11304    if (ast_channel_register(&zap_tech)) {
11305       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
11306       __unload_module();
11307       return -1;
11308    }
11309 #ifdef HAVE_PRI
11310    ast_string_field_init(&inuse, 16);
11311    ast_string_field_set(&inuse, name, "GR-303InUse");
11312    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11313 #endif   
11314    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11315    
11316    memset(round_robin, 0, sizeof(round_robin));
11317    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11318    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11319    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11320    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11321    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11322    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11323    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
11324 
11325    return res;
11326 }
11327 
11328 static int zt_sendtext(struct ast_channel *c, const char *text)
11329 {
11330 #define  END_SILENCE_LEN 400
11331 #define  HEADER_MS 50
11332 #define  TRAILER_MS 5
11333 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11334 #define  ASCII_BYTES_PER_CHAR 80
11335 
11336    unsigned char *buf,*mybuf;
11337    struct zt_pvt *p = c->tech_pvt;
11338    struct pollfd fds[1];
11339    int size,res,fd,len,x;
11340    int bytes=0;
11341    /* Initial carrier (imaginary) */
11342    float cr = 1.0;
11343    float ci = 0.0;
11344    float scont = 0.0;
11345    int index;
11346 
11347    index = zt_get_index(c, p, 0);
11348    if (index < 0) {
11349       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11350       return -1;
11351    }
11352    if (!text[0]) return(0); /* if nothing to send, dont */
11353    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11354    if (p->mate) 
11355       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11356    else
11357       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11358    if (!buf)
11359       return -1;
11360    mybuf = buf;
11361    if (p->mate) {
11362       int codec = AST_LAW(p);
11363       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
11364          PUT_CLID_MARKMS;
11365       }
11366       /* Put actual message */
11367       for (x = 0; text[x]; x++) {
11368          PUT_CLID(text[x]);
11369       }
11370       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
11371          PUT_CLID_MARKMS;
11372       }
11373       len = bytes;
11374       buf = mybuf;
11375    } else {
11376       len = tdd_generate(p->tdd, buf, text);
11377       if (len < 1) {
11378          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
11379          free(mybuf);
11380          return -1;
11381       }
11382    }
11383    memset(buf + len, 0x7f, END_SILENCE_LEN);
11384    len += END_SILENCE_LEN;
11385    fd = p->subs[index].zfd;
11386    while (len) {
11387       if (ast_check_hangup(c)) {
11388          free(mybuf);
11389          return -1;
11390       }
11391       size = len;
11392       if (size > READ_SIZE)
11393          size = READ_SIZE;
11394       fds[0].fd = fd;
11395       fds[0].events = POLLOUT | POLLPRI;
11396       fds[0].revents = 0;
11397       res = poll(fds, 1, -1);
11398       if (!res) {
11399          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11400          continue;
11401       }
11402         /* if got exception */
11403       if (fds[0].revents & POLLPRI)
11404          return -1;
11405       if (!(fds[0].revents & POLLOUT)) {
11406          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11407          continue;
11408       }
11409       res = write(fd, buf, size);
11410       if (res != size) {
11411          if (res == -1) {
11412             free(mybuf);
11413             return -1;
11414          }
11415          if (option_debug)
11416             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11417          break;
11418       }
11419       len -= size;
11420       buf += size;
11421    }
11422    free(mybuf);
11423    return(0);
11424 }
11425 
11426 
11427 static int reload(void)
11428 {
11429    int res = 0;
11430 
11431    res = setup_zap(1);
11432    if (res) {
11433       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11434       return -1;
11435    }
11436    return 0;
11437 }
11438 
11439 /* This is a workaround so that menuselect displays a proper description
11440  * AST_MODULE_INFO(, , "Zapata Telephony"
11441  */
11442 
11443 #ifdef ZAPATA_PRI
11444 #define tdesc "Zapata Telephony w/PRI"
11445 #else
11446 #define tdesc "Zapata Telephony"
11447 #endif
11448 
11449 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
11450       .load = load_module,
11451       .unload = unload_module,
11452       .reload = reload,
11453           );
11454 
11455 

Generated on Wed Aug 15 01:24:20 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3