Mon Apr 30 07:36:32 2007

Asterisk developer's documentation


chan_zap.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Zaptel Pseudo TDM interface 
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Connects to the zaptel telephony library as well as 
00026  * libpri. Libpri is optional and needed only if you are
00027  * going to use ISDN connections.
00028  *
00029  * You need to install libraries before you attempt to compile
00030  * and install the zaptel channel.
00031  *
00032  * \par See also
00033  * \arg \ref Config_zap
00034  *
00035  * \ingroup channel_drivers
00036  *
00037  * \todo Deprecate the "musiconhold" configuration option post 1.4
00038  */
00039 
00040 /*** MODULEINFO
00041    <depend>zaptel_vldtmf</depend>
00042    <depend>zaptel</depend>
00043    <depend>tonezone</depend>
00044    <use>pri</use>
00045  ***/
00046 
00047 #include "asterisk.h"
00048 
00049 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00050 
00051 #include <stdio.h>
00052 #include <string.h>
00053 #ifdef __NetBSD__
00054 #include <pthread.h>
00055 #include <signal.h>
00056 #else
00057 #include <sys/signal.h>
00058 #endif
00059 #include <errno.h>
00060 #include <stdlib.h>
00061 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00062 #include <stdint.h>
00063 #endif
00064 #include <unistd.h>
00065 #include <sys/ioctl.h>
00066 #include <math.h>
00067 #include <ctype.h>
00068 #include <zaptel/zaptel.h>
00069 #include <zaptel/tonezone.h>
00070 
00071 #ifdef HAVE_PRI
00072 #include <libpri.h>
00073 #endif
00074 
00075 #include "asterisk/lock.h"
00076 #include "asterisk/channel.h"
00077 #include "asterisk/config.h"
00078 #include "asterisk/logger.h"
00079 #include "asterisk/module.h"
00080 #include "asterisk/pbx.h"
00081 #include "asterisk/options.h"
00082 #include "asterisk/file.h"
00083 #include "asterisk/ulaw.h"
00084 #include "asterisk/alaw.h"
00085 #include "asterisk/callerid.h"
00086 #include "asterisk/adsi.h"
00087 #include "asterisk/cli.h"
00088 #include "asterisk/cdr.h"
00089 #include "asterisk/features.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/say.h"
00092 #include "asterisk/tdd.h"
00093 #include "asterisk/app.h"
00094 #include "asterisk/dsp.h"
00095 #include "asterisk/astdb.h"
00096 #include "asterisk/manager.h"
00097 #include "asterisk/causes.h"
00098 #include "asterisk/term.h"
00099 #include "asterisk/utils.h"
00100 #include "asterisk/transcap.h"
00101 #include "asterisk/stringfields.h"
00102 #include "asterisk/abstract_jb.h"
00103 #include "asterisk/smdi.h"
00104 #include "asterisk/astobj.h"
00105 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00106 
00107 /*! Global jitterbuffer configuration - by default, jb is disabled */
00108 static struct ast_jb_conf default_jbconf =
00109 {
00110    .flags = 0,
00111    .max_size = -1,
00112    .resync_threshold = -1,
00113    .impl = ""
00114 };
00115 static struct ast_jb_conf global_jbconf;
00116 
00117 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00118 #error "Your zaptel is too old.  Please update"
00119 #endif
00120 
00121 #ifndef ZT_TONEDETECT
00122 /* Work around older code with no tone detect */
00123 #define ZT_EVENT_DTMFDOWN 0
00124 #define ZT_EVENT_DTMFUP 0
00125 #endif
00126 
00127 /* define this to send PRI user-user information elements */
00128 #undef SUPPORT_USERUSER
00129 
00130 /*! 
00131  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00132  * the user hangs up to reset the state machine so ring works properly.
00133  * This is used to be able to support kewlstart by putting the zhone in
00134  * groundstart mode since their forward disconnect supervision is entirely
00135  * broken even though their documentation says it isn't and their support
00136  * is entirely unwilling to provide any assistance with their channel banks
00137  * even though their web site says they support their products for life.
00138  */
00139 /* #define ZHONE_HACK */
00140 
00141 /*! \note
00142  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00143  * before dialing on it.  Certain FXO interfaces always think they're out of
00144  * service with this method however.
00145  */
00146 /* #define ZAP_CHECK_HOOKSTATE */
00147 
00148 /*! \brief Typically, how many rings before we should send Caller*ID */
00149 #define DEFAULT_CIDRINGS 1
00150 
00151 #define CHANNEL_PSEUDO -12
00152 
00153 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00154 
00155 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00156 #define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) 
00157 
00158 static const char tdesc[] = "Zapata Telephony Driver"
00159 #ifdef HAVE_PRI
00160                " w/PRI"
00161 #endif
00162 ;
00163 
00164 static const char config[] = "zapata.conf";
00165 
00166 #define SIG_EM    ZT_SIG_EM
00167 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00168 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00169 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00170 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00171 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00172 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00173 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00174 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00175 #define SIG_FXSLS ZT_SIG_FXSLS
00176 #define SIG_FXSGS ZT_SIG_FXSGS
00177 #define SIG_FXSKS ZT_SIG_FXSKS
00178 #define SIG_FXOLS ZT_SIG_FXOLS
00179 #define SIG_FXOGS ZT_SIG_FXOGS
00180 #define SIG_FXOKS ZT_SIG_FXOKS
00181 #define SIG_PRI      ZT_SIG_CLEAR
00182 #define  SIG_SF      ZT_SIG_SF
00183 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00184 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00185 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00186 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00187 #define SIG_EM_E1 ZT_SIG_EM_E1
00188 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00189 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00190 
00191 #define NUM_SPANS       32
00192 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00193 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00194 
00195 #define CHAN_PSEUDO  -2
00196 
00197 #define DCHAN_PROVISIONED (1 << 0)
00198 #define DCHAN_NOTINALARM  (1 << 1)
00199 #define DCHAN_UP          (1 << 2)
00200 
00201 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00202 
00203 static char defaultcic[64] = "";
00204 static char defaultozz[64] = "";
00205 
00206 static char progzone[10] = "";
00207 
00208 static int usedistinctiveringdetection = 0;
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    unsigned int 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          ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01434       }
01435    } else
01436       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01437 }
01438 
01439 static void zt_train_ec(struct zt_pvt *p)
01440 {
01441    int x;
01442    int res;
01443    if (p && p->echocancel && p->echotraining) {
01444       x = p->echotraining;
01445       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01446       if (res)
01447          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01448       else {
01449          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01450       }
01451    } else
01452       ast_log(LOG_DEBUG, "No echo training requested\n");
01453 }
01454 
01455 static void zt_disable_ec(struct zt_pvt *p)
01456 {
01457    int x;
01458    int res;
01459    if (p->echocancel) {
01460       x = 0;
01461       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01462       if (res)
01463          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01464       else
01465          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01466    }
01467    p->echocanon = 0;
01468 }
01469 
01470 static void fill_txgain(struct zt_gains *g, float gain, int law)
01471 {
01472    int j;
01473    int k;
01474    float linear_gain = pow(10.0, gain / 20.0);
01475 
01476    switch (law) {
01477    case ZT_LAW_ALAW:
01478       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01479          if (gain) {
01480             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01481             if (k > 32767) k = 32767;
01482             if (k < -32767) k = -32767;
01483             g->txgain[j] = AST_LIN2A(k);
01484          } else {
01485             g->txgain[j] = j;
01486          }
01487       }
01488       break;
01489    case ZT_LAW_MULAW:
01490       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01491          if (gain) {
01492             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01493             if (k > 32767) k = 32767;
01494             if (k < -32767) k = -32767;
01495             g->txgain[j] = AST_LIN2MU(k);
01496          } else {
01497             g->txgain[j] = j;
01498          }
01499       }
01500       break;
01501    }
01502 }
01503 
01504 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01505 {
01506    int j;
01507    int k;
01508    float linear_gain = pow(10.0, gain / 20.0);
01509 
01510    switch (law) {
01511    case ZT_LAW_ALAW:
01512       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01513          if (gain) {
01514             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01515             if (k > 32767) k = 32767;
01516             if (k < -32767) k = -32767;
01517             g->rxgain[j] = AST_LIN2A(k);
01518          } else {
01519             g->rxgain[j] = j;
01520          }
01521       }
01522       break;
01523    case ZT_LAW_MULAW:
01524       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01525          if (gain) {
01526             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01527             if (k > 32767) k = 32767;
01528             if (k < -32767) k = -32767;
01529             g->rxgain[j] = AST_LIN2MU(k);
01530          } else {
01531             g->rxgain[j] = j;
01532          }
01533       }
01534       break;
01535    }
01536 }
01537 
01538 static int set_actual_txgain(int fd, int chan, float gain, int law)
01539 {
01540    struct zt_gains g;
01541    int res;
01542 
01543    memset(&g, 0, sizeof(g));
01544    g.chan = chan;
01545    res = ioctl(fd, ZT_GETGAINS, &g);
01546    if (res) {
01547       if (option_debug)
01548          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01549       return res;
01550    }
01551 
01552    fill_txgain(&g, gain, law);
01553 
01554    return ioctl(fd, ZT_SETGAINS, &g);
01555 }
01556 
01557 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01558 {
01559    struct zt_gains g;
01560    int res;
01561 
01562    memset(&g, 0, sizeof(g));
01563    g.chan = chan;
01564    res = ioctl(fd, ZT_GETGAINS, &g);
01565    if (res) {
01566       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01567       return res;
01568    }
01569 
01570    fill_rxgain(&g, gain, law);
01571 
01572    return ioctl(fd, ZT_SETGAINS, &g);
01573 }
01574 
01575 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01576 {
01577    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01578 }
01579 
01580 static int bump_gains(struct zt_pvt *p)
01581 {
01582    int res;
01583 
01584    /* Bump receive gain by 5.0db */
01585    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01586    if (res) {
01587       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01588       return -1;
01589    }
01590 
01591    return 0;
01592 }
01593 
01594 static int restore_gains(struct zt_pvt *p)
01595 {
01596    int res;
01597 
01598    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01599    if (res) {
01600       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01601       return -1;
01602    }
01603 
01604    return 0;
01605 }
01606 
01607 static inline int zt_set_hook(int fd, int hs)
01608 {
01609    int x, res;
01610    x = hs;
01611    res = ioctl(fd, ZT_HOOK, &x);
01612    if (res < 0) 
01613    {
01614       if (errno == EINPROGRESS) return 0;
01615       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01616    }
01617    return res;
01618 }
01619 
01620 static inline int zt_confmute(struct zt_pvt *p, int muted)
01621 {
01622    int x, y, res;
01623    x = muted;
01624    if (p->sig == SIG_PRI) {
01625       y = 1;
01626       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01627       if (res)
01628          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01629    }
01630    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01631    if (res < 0)
01632       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01633    return res;
01634 }
01635 
01636 static int save_conference(struct zt_pvt *p)
01637 {
01638    struct zt_confinfo c;
01639    int res;
01640    if (p->saveconf.confmode) {
01641       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01642       return -1;
01643    }
01644    p->saveconf.chan = 0;
01645    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01646    if (res) {
01647       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01648       p->saveconf.confmode = 0;
01649       return -1;
01650    }
01651    c.chan = 0;
01652    c.confno = 0;
01653    c.confmode = ZT_CONF_NORMAL;
01654    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01655    if (res) {
01656       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01657       return -1;
01658    }
01659    if (option_debug)
01660       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01661    return 0;
01662 }
01663 
01664 static int restore_conference(struct zt_pvt *p)
01665 {
01666    int res;
01667    if (p->saveconf.confmode) {
01668       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01669       p->saveconf.confmode = 0;
01670       if (res) {
01671          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01672          return -1;
01673       }
01674    }
01675    if (option_debug)
01676       ast_log(LOG_DEBUG, "Restored conferencing\n");
01677    return 0;
01678 }
01679 
01680 static int send_callerid(struct zt_pvt *p);
01681 
01682 static int send_cwcidspill(struct zt_pvt *p)
01683 {
01684    p->callwaitcas = 0;
01685    p->cidcwexpire = 0;
01686    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01687       return -1;
01688    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01689    /* Make sure we account for the end */
01690    p->cidlen += READ_SIZE * 4;
01691    p->cidpos = 0;
01692    send_callerid(p);
01693    if (option_verbose > 2)
01694       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01695    return 0;
01696 }
01697 
01698 static int has_voicemail(struct zt_pvt *p)
01699 {
01700 
01701    return ast_app_has_voicemail(p->mailbox, NULL);
01702 }
01703 
01704 static int send_callerid(struct zt_pvt *p)
01705 {
01706    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01707    int res;
01708    /* Take out of linear mode if necessary */
01709    if (p->subs[SUB_REAL].linear) {
01710       p->subs[SUB_REAL].linear = 0;
01711       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01712    }
01713    while (p->cidpos < p->cidlen) {
01714       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01715       if (res < 0) {
01716          if (errno == EAGAIN)
01717             return 0;
01718          else {
01719             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01720             return -1;
01721          }
01722       }
01723       if (!res)
01724          return 0;
01725       p->cidpos += res;
01726    }
01727    free(p->cidspill);
01728    p->cidspill = NULL;
01729    if (p->callwaitcas) {
01730       /* Wait for CID/CW to expire */
01731       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01732    } else
01733       restore_conference(p);
01734    return 0;
01735 }
01736 
01737 static int zt_callwait(struct ast_channel *ast)
01738 {
01739    struct zt_pvt *p = ast->tech_pvt;
01740    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01741    if (p->cidspill) {
01742       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01743       free(p->cidspill);
01744    }
01745    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01746       return -1;
01747    save_conference(p);
01748    /* Silence */
01749    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01750    if (!p->callwaitrings && p->callwaitingcallerid) {
01751       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01752       p->callwaitcas = 1;
01753       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01754    } else {
01755       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01756       p->callwaitcas = 0;
01757       p->cidlen = 2400 + READ_SIZE * 4;
01758    }
01759    p->cidpos = 0;
01760    send_callerid(p);
01761    
01762    return 0;
01763 }
01764 
01765 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01766 {
01767    struct zt_pvt *p = ast->tech_pvt;
01768    int x, res, index,mysig;
01769    char *c, *n, *l;
01770 #ifdef HAVE_PRI
01771    char *s = NULL;
01772 #endif
01773    char dest[256]; /* must be same length as p->dialdest */
01774    ast_mutex_lock(&p->lock);
01775    ast_copy_string(dest, rdest, sizeof(dest));
01776    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01777    if ((ast->_state == AST_STATE_BUSY)) {
01778       p->subs[SUB_REAL].needbusy = 1;
01779       ast_mutex_unlock(&p->lock);
01780       return 0;
01781    }
01782    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01783       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01784       ast_mutex_unlock(&p->lock);
01785       return -1;
01786    }
01787    p->dialednone = 0;
01788    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01789    {
01790       /* Special pseudo -- automatically up */
01791       ast_setstate(ast, AST_STATE_UP); 
01792       ast_mutex_unlock(&p->lock);
01793       return 0;
01794    }
01795    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01796    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01797    if (res)
01798       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01799    p->outgoing = 1;
01800 
01801    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01802 
01803    mysig = p->sig;
01804    if (p->outsigmod > -1)
01805       mysig = p->outsigmod;
01806 
01807    switch (mysig) {
01808    case SIG_FXOLS:
01809    case SIG_FXOGS:
01810    case SIG_FXOKS:
01811       if (p->owner == ast) {
01812          /* Normal ring, on hook */
01813          
01814          /* Don't send audio while on hook, until the call is answered */
01815          p->dialing = 1;
01816          if (p->use_callerid) {
01817             /* Generate the Caller-ID spill if desired */
01818             if (p->cidspill) {
01819                ast_log(LOG_WARNING, "cidspill already exists??\n");
01820                free(p->cidspill);
01821             }
01822             p->callwaitcas = 0;
01823             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01824                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01825                p->cidpos = 0;
01826                send_callerid(p);
01827             }
01828          }
01829          /* Choose proper cadence */
01830          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01831             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01832                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01833             p->cidrings = cidrings[p->distinctivering - 1];
01834          } else {
01835             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01836                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01837             p->cidrings = p->sendcalleridafter;
01838          }
01839 
01840          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01841          c = strchr(dest, '/');
01842          if (c)
01843             c++;
01844          if (c && (strlen(c) < p->stripmsd)) {
01845             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01846             c = NULL;
01847          }
01848          if (c) {
01849             p->dop.op = ZT_DIAL_OP_REPLACE;
01850             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01851             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01852          } else {
01853             p->dop.dialstr[0] = '\0';
01854          }
01855          x = ZT_RING;
01856          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01857             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01858             ast_mutex_unlock(&p->lock);
01859             return -1;
01860          }
01861          p->dialing = 1;
01862       } else {
01863          /* Call waiting call */
01864          p->callwaitrings = 0;
01865          if (ast->cid.cid_num)
01866             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01867          else
01868             p->callwait_num[0] = '\0';
01869          if (ast->cid.cid_name)
01870             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01871          else
01872             p->callwait_name[0] = '\0';
01873          /* Call waiting tone instead */
01874          if (zt_callwait(ast)) {
01875             ast_mutex_unlock(&p->lock);
01876             return -1;
01877          }
01878          /* Make ring-back */
01879          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01880             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01881             
01882       }
01883       n = ast->cid.cid_name;
01884       l = ast->cid.cid_num;
01885       if (l)
01886          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01887       else
01888          p->lastcid_num[0] = '\0';
01889       if (n)
01890          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01891       else
01892          p->lastcid_name[0] = '\0';
01893       ast_setstate(ast, AST_STATE_RINGING);
01894       index = zt_get_index(ast, p, 0);
01895       if (index > -1) {
01896          p->subs[index].needringing = 1;
01897       }
01898       break;
01899    case SIG_FXSLS:
01900    case SIG_FXSGS:
01901    case SIG_FXSKS:
01902    case SIG_EMWINK:
01903    case SIG_EM:
01904    case SIG_EM_E1:
01905    case SIG_FEATD:
01906    case SIG_FEATDMF:
01907    case SIG_E911:
01908    case SIG_FGC_CAMA:
01909    case SIG_FGC_CAMAMF:
01910    case SIG_FEATB:
01911    case SIG_SFWINK:
01912    case SIG_SF:
01913    case SIG_SF_FEATD:
01914    case SIG_SF_FEATDMF:
01915    case SIG_FEATDMF_TA:
01916    case SIG_SF_FEATB:
01917       c = strchr(dest, '/');
01918       if (c)
01919          c++;
01920       else
01921          c = "";
01922       if (strlen(c) < p->stripmsd) {
01923          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01924          ast_mutex_unlock(&p->lock);
01925          return -1;
01926       }
01927 #ifdef HAVE_PRI
01928       /* Start the trunk, if not GR-303 */
01929       if (!p->pri) {
01930 #endif
01931          x = ZT_START;
01932          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01933          if (res < 0) {
01934             if (errno != EINPROGRESS) {
01935                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01936                ast_mutex_unlock(&p->lock);
01937                return -1;
01938             }
01939          }
01940 #ifdef HAVE_PRI
01941       }
01942 #endif
01943       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01944       p->dop.op = ZT_DIAL_OP_REPLACE;
01945 
01946       c += p->stripmsd;
01947 
01948       switch (mysig) {
01949       case SIG_FEATD:
01950          l = ast->cid.cid_num;
01951          if (l) 
01952             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01953          else
01954             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01955          break;
01956       case SIG_FEATDMF:
01957          l = ast->cid.cid_num;
01958          if (l) 
01959             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01960          else
01961             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01962          break;
01963       case SIG_FEATDMF_TA:
01964       {
01965          const char *cic, *ozz;
01966 
01967          /* If you have to go through a Tandem Access point you need to use this */
01968          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01969          if (!ozz)
01970             ozz = defaultozz;
01971          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01972          if (!cic)
01973             cic = defaultcic;
01974          if (!ozz || !cic) {
01975             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01976             ast_mutex_unlock(&p->lock);
01977             return -1;
01978          }
01979          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01980          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01981          p->whichwink = 0;
01982       }
01983          break;
01984       case SIG_E911:
01985          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01986          break;
01987       case SIG_FGC_CAMA:
01988          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
01989          break;
01990       case SIG_FGC_CAMAMF:
01991       case SIG_FEATB:
01992          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
01993          break;
01994       default:
01995          if (p->pulse)
01996             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
01997          else
01998             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
01999          break;
02000       }
02001 
02002       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02003          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02004          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02005          p->echorest[sizeof(p->echorest) - 1] = '\0';
02006          p->echobreak = 1;
02007          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02008       } else
02009          p->echobreak = 0;
02010       if (!res) {
02011          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02012             x = ZT_ONHOOK;
02013             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02014             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02015             ast_mutex_unlock(&p->lock);
02016             return -1;
02017          }
02018       } else
02019          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02020       p->dialing = 1;
02021       if (ast_strlen_zero(c))
02022          p->dialednone = 1;
02023       ast_setstate(ast, AST_STATE_DIALING);
02024       break;
02025    case 0:
02026       /* Special pseudo -- automatically up*/
02027       ast_setstate(ast, AST_STATE_UP);
02028       break;      
02029    case SIG_PRI:
02030       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02031       p->dialdest[0] = '\0';
02032       break;
02033    default:
02034       ast_log(LOG_DEBUG, "not yet implemented\n");
02035       ast_mutex_unlock(&p->lock);
02036       return -1;
02037    }
02038 #ifdef HAVE_PRI
02039    if (p->pri) {
02040       struct pri_sr *sr;
02041 #ifdef SUPPORT_USERUSER
02042       const char *useruser;
02043 #endif
02044       int pridialplan;
02045       int dp_strip;
02046       int prilocaldialplan;
02047       int ldp_strip;
02048       int exclusive;
02049       const char *rr_str;
02050       int redirect_reason;
02051 
02052       c = strchr(dest, '/');
02053       if (c)
02054          c++;
02055       else
02056          c = dest;
02057       if (!p->hidecalleridname)
02058          n = ast->cid.cid_name;
02059       else
02060          n = NULL;
02061       if (!p->hidecallerid) {
02062          l = ast->cid.cid_num;
02063          n = ast->cid.cid_name;
02064       } else {
02065          l = NULL;
02066          n = NULL;
02067       }
02068       if (strlen(c) < p->stripmsd) {
02069          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02070          ast_mutex_unlock(&p->lock);
02071          return -1;
02072       }
02073       if (mysig != SIG_FXSKS) {
02074          p->dop.op = ZT_DIAL_OP_REPLACE;
02075          s = strchr(c + p->stripmsd, 'w');
02076          if (s) {
02077             if (strlen(s) > 1)
02078                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02079             else
02080                p->dop.dialstr[0] = '\0';
02081             *s = '\0';
02082          } else {
02083             p->dop.dialstr[0] = '\0';
02084          }
02085       }
02086       if (pri_grab(p, p->pri)) {
02087          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02088          ast_mutex_unlock(&p->lock);
02089          return -1;
02090       }
02091       if (!(p->call = pri_new_call(p->pri->pri))) {
02092          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02093          pri_rel(p->pri);
02094          ast_mutex_unlock(&p->lock);
02095          return -1;
02096       }
02097       if (!(sr = pri_sr_new())) {
02098          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02099          pri_rel(p->pri);
02100          ast_mutex_unlock(&p->lock);
02101       }
02102       if (p->bearer || (mysig == SIG_FXSKS)) {
02103          if (p->bearer) {
02104             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);
02105             p->bearer->call = p->call;
02106          } else
02107             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02108          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02109       }
02110       p->digital = IS_DIGITAL(ast->transfercapability);
02111       /* Add support for exclusive override */
02112       if (p->priexclusive)
02113          exclusive = 1;
02114       else {
02115       /* otherwise, traditional behavior */
02116          if (p->pri->nodetype == PRI_NETWORK)
02117             exclusive = 0;
02118          else
02119             exclusive = 1;
02120       }
02121       
02122       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02123       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02124                (p->digital ? -1 : 
02125                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02126       if (p->pri->facilityenable)
02127          pri_facility_enable(p->pri->pri);
02128 
02129       if (option_verbose > 2)
02130          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02131       dp_strip = 0;
02132       pridialplan = p->pri->dialplan - 1;
02133       if (pridialplan == -2) { /* compute dynamically */
02134          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02135             dp_strip = strlen(p->pri->internationalprefix);
02136             pridialplan = PRI_INTERNATIONAL_ISDN;
02137          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02138             dp_strip = strlen(p->pri->nationalprefix);
02139             pridialplan = PRI_NATIONAL_ISDN;
02140          } else {
02141             pridialplan = PRI_LOCAL_ISDN;
02142          }
02143       }
02144       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02145 
02146       ldp_strip = 0;
02147       prilocaldialplan = p->pri->localdialplan - 1;
02148       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02149          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02150             ldp_strip = strlen(p->pri->internationalprefix);
02151             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02152          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02153             ldp_strip = strlen(p->pri->nationalprefix);
02154             prilocaldialplan = PRI_NATIONAL_ISDN;
02155          } else {
02156             prilocaldialplan = PRI_LOCAL_ISDN;
02157          }
02158       }
02159       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02160          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02161       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02162          if (!strcasecmp(rr_str, "UNKNOWN"))
02163             redirect_reason = 0;
02164          else if (!strcasecmp(rr_str, "BUSY"))
02165             redirect_reason = 1;
02166          else if (!strcasecmp(rr_str, "NO_REPLY"))
02167             redirect_reason = 2;
02168          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02169             redirect_reason = 15;
02170          else
02171             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02172       } else
02173          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02174       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02175 
02176 #ifdef SUPPORT_USERUSER
02177       /* User-user info */
02178       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02179 
02180       if (useruser)
02181          pri_sr_set_useruser(sr, useruser);
02182 #endif
02183 
02184       if (pri_setup(p->pri->pri, p->call, sr)) {
02185          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02186             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02187          pri_rel(p->pri);
02188          ast_mutex_unlock(&p->lock);
02189          pri_sr_free(sr);
02190          return -1;
02191       }
02192       pri_sr_free(sr);
02193       ast_setstate(ast, AST_STATE_DIALING);
02194       pri_rel(p->pri);
02195    }
02196 #endif      
02197    ast_mutex_unlock(&p->lock);
02198    return 0;
02199 }
02200 
02201 static void destroy_zt_pvt(struct zt_pvt **pvt)
02202 {
02203    struct zt_pvt *p = *pvt;
02204    /* Remove channel from the list */
02205    if (p->prev)
02206       p->prev->next = p->next;
02207    if (p->next)
02208       p->next->prev = p->prev;
02209    if (p->use_smdi)
02210       ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
02211    ast_mutex_destroy(&p->lock);
02212    free(p);
02213    *pvt = NULL;
02214 }
02215 
02216 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02217 {
02218    int owned = 0;
02219    int i = 0;
02220 
02221    if (!now) {
02222       if (cur->owner) {
02223          owned = 1;
02224       }
02225 
02226       for (i = 0; i < 3; i++) {
02227          if (cur->subs[i].owner) {
02228             owned = 1;
02229          }
02230       }
02231       if (!owned) {
02232          if (prev) {
02233             prev->next = cur->next;
02234             if (prev->next)
02235                prev->next->prev = prev;
02236             else
02237                ifend = prev;
02238          } else {
02239             iflist = cur->next;
02240             if (iflist)
02241                iflist->prev = NULL;
02242             else
02243                ifend = NULL;
02244          }
02245          if (cur->subs[SUB_REAL].zfd > -1) {
02246             zt_close(cur->subs[SUB_REAL].zfd);
02247          }
02248          destroy_zt_pvt(&cur);
02249       }
02250    } else {
02251       if (prev) {
02252          prev->next = cur->next;
02253          if (prev->next)
02254             prev->next->prev = prev;
02255          else
02256             ifend = prev;
02257       } else {
02258          iflist = cur->next;
02259          if (iflist)
02260             iflist->prev = NULL;
02261          else
02262             ifend = NULL;
02263       }
02264       if (cur->subs[SUB_REAL].zfd > -1) {
02265          zt_close(cur->subs[SUB_REAL].zfd);
02266       }
02267       destroy_zt_pvt(&cur);
02268    }
02269    return 0;
02270 }
02271 
02272 #ifdef HAVE_PRI
02273 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02274 
02275 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02276 
02277 static char *zap_send_keypad_facility_descrip = 
02278 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02279 "  IE over the current channel.\n";
02280 
02281 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02282 {
02283    /* Data will be our digit string */
02284    struct zt_pvt *p;
02285    char *digits = (char *) data;
02286 
02287    if (ast_strlen_zero(digits)) {
02288       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02289       return -1;
02290    }
02291 
02292    p = (struct zt_pvt *)chan->tech_pvt;
02293 
02294    if (!p) {
02295       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02296       return -1;
02297    }
02298 
02299    ast_mutex_lock(&p->lock);
02300 
02301    if (!p->pri || !p->call) {
02302       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02303       ast_mutex_unlock(&p->lock);
02304       return -1;
02305    }
02306 
02307    if (!pri_grab(p, p->pri)) {
02308       pri_keypad_facility(p->pri->pri, p->call, digits);
02309       pri_rel(p->pri);
02310    } else {
02311       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02312       ast_mutex_unlock(&p->lock);
02313       return -1;
02314    }
02315 
02316    ast_mutex_unlock(&p->lock);
02317 
02318    return 0;
02319 }
02320 
02321 static int pri_is_up(struct zt_pri *pri)
02322 {
02323    int x;
02324    for (x = 0; x < NUM_DCHANS; x++) {
02325       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02326          return 1;
02327    }
02328    return 0;
02329 }
02330 
02331 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02332 {
02333    bearer->owner = &inuse;
02334    bearer->realcall = crv;
02335    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02336    if (crv->subs[SUB_REAL].owner)
02337       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02338    crv->bearer = bearer;
02339    crv->call = bearer->call;
02340    crv->pri = pri;
02341    return 0;
02342 }
02343 
02344 static char *pri_order(int level)
02345 {
02346    switch (level) {
02347    case 0:
02348       return "Primary";
02349    case 1:
02350       return "Secondary";
02351    case 2:
02352       return "Tertiary";
02353    case 3:
02354       return "Quaternary";
02355    default:
02356       return "<Unknown>";
02357    }     
02358 }
02359 
02360 /* Returns fd of the active dchan */
02361 static int pri_active_dchan_fd(struct zt_pri *pri)
02362 {
02363    int x = -1;
02364 
02365    for (x = 0; x < NUM_DCHANS; x++) {
02366       if ((pri->dchans[x] == pri->pri))
02367          break;
02368    }
02369 
02370    return pri->fds[x];
02371 }
02372 
02373 static int pri_find_dchan(struct zt_pri *pri)
02374 {
02375    int oldslot = -1;
02376    struct pri *old;
02377    int newslot = -1;
02378    int x;
02379    old = pri->pri;
02380    for (x = 0; x < NUM_DCHANS; x++) {
02381       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02382          newslot = x;
02383       if (pri->dchans[x] == old) {
02384          oldslot = x;
02385       }
02386    }
02387    if (newslot < 0) {
02388       newslot = 0;
02389       ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02390          pri->dchannels[newslot]);
02391    }
02392    if (old && (oldslot != newslot))
02393       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02394          pri->dchannels[oldslot], pri->dchannels[newslot]);
02395    pri->pri = pri->dchans[newslot];
02396    return 0;
02397 }
02398 #endif
02399 
02400 static int zt_hangup(struct ast_channel *ast)
02401 {
02402    int res;
02403    int index,x, law;
02404    /*static int restore_gains(struct zt_pvt *p);*/
02405    struct zt_pvt *p = ast->tech_pvt;
02406    struct zt_pvt *tmp = NULL;
02407    struct zt_pvt *prev = NULL;
02408    ZT_PARAMS par;
02409 
02410    if (option_debug)
02411       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02412    if (!ast->tech_pvt) {
02413       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02414       return 0;
02415    }
02416    
02417    ast_mutex_lock(&p->lock);
02418    
02419    index = zt_get_index(ast, p, 1);
02420 
02421    if (p->sig == SIG_PRI) {
02422       x = 1;
02423       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02424    }
02425 
02426    x = 0;
02427    zt_confmute(p, 0);
02428    restore_gains(p);
02429    if (p->origcid_num) {
02430       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02431       free(p->origcid_num);
02432       p->origcid_num = NULL;
02433    }  
02434    if (p->origcid_name) {
02435       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02436       free(p->origcid_name);
02437       p->origcid_name = NULL;
02438    }  
02439    if (p->dsp)
02440       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02441    if (p->exten)
02442       p->exten[0] = '\0';
02443 
02444    if (option_debug)
02445       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02446       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02447    p->ignoredtmf = 0;
02448    
02449    if (index > -1) {
02450       /* Real channel, do some fixup */
02451       p->subs[index].owner = NULL;
02452       p->subs[index].needanswer = 0;
02453       p->subs[index].needflash = 0;
02454       p->subs[index].needringing = 0;
02455       p->subs[index].needbusy = 0;
02456       p->subs[index].needcongestion = 0;
02457       p->subs[index].linear = 0;
02458       p->subs[index].needcallerid = 0;
02459       p->polarity = POLARITY_IDLE;
02460       zt_setlinear(p->subs[index].zfd, 0);
02461       if (index == SUB_REAL) {
02462          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02463             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02464             if (p->subs[SUB_CALLWAIT].inthreeway) {
02465                /* We had flipped over to answer a callwait and now it's gone */
02466                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02467                /* Move to the call-wait, but un-own us until they flip back. */
02468                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02469                unalloc_sub(p, SUB_CALLWAIT);
02470                p->owner = NULL;
02471             } else {
02472                /* The three way hung up, but we still have a call wait */
02473                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02474                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02475                unalloc_sub(p, SUB_THREEWAY);
02476                if (p->subs[SUB_REAL].inthreeway) {
02477                   /* This was part of a three way call.  Immediately make way for
02478                      another call */
02479                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02480                   p->owner = p->subs[SUB_REAL].owner;
02481                } else {
02482                   /* This call hasn't been completed yet...  Set owner to NULL */
02483                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02484                   p->owner = NULL;
02485                }
02486                p->subs[SUB_REAL].inthreeway = 0;
02487             }
02488          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02489             /* Move to the call-wait and switch back to them. */
02490             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02491             unalloc_sub(p, SUB_CALLWAIT);
02492             p->owner = p->subs[SUB_REAL].owner;
02493             if (p->owner->_state != AST_STATE_UP)
02494                p->subs[SUB_REAL].needanswer = 1;
02495             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02496                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02497          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02498             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02499             unalloc_sub(p, SUB_THREEWAY);
02500             if (p->subs[SUB_REAL].inthreeway) {
02501                /* This was part of a three way call.  Immediately make way for
02502                   another call */
02503                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02504                p->owner = p->subs[SUB_REAL].owner;
02505             } else {
02506                /* This call hasn't been completed yet...  Set owner to NULL */
02507                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02508                p->owner = NULL;
02509             }
02510             p->subs[SUB_REAL].inthreeway = 0;
02511          }
02512       } else if (index == SUB_CALLWAIT) {
02513          /* Ditch the holding callwait call, and immediately make it availabe */
02514          if (p->subs[SUB_CALLWAIT].inthreeway) {
02515             /* This is actually part of a three way, placed on hold.  Place the third part
02516                on music on hold now */
02517             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02518                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02519                   S_OR(p->mohsuggest, NULL),
02520                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02521             }
02522             p->subs[SUB_THREEWAY].inthreeway = 0;
02523             /* Make it the call wait now */
02524             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02525             unalloc_sub(p, SUB_THREEWAY);
02526          } else
02527             unalloc_sub(p, SUB_CALLWAIT);
02528       } else if (index == SUB_THREEWAY) {
02529          if (p->subs[SUB_CALLWAIT].inthreeway) {
02530             /* The other party of the three way call is currently in a call-wait state.
02531                Start music on hold for them, and take the main guy out of the third call */
02532             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02533                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02534                   S_OR(p->mohsuggest, NULL),
02535                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02536             }
02537             p->subs[SUB_CALLWAIT].inthreeway = 0;
02538          }
02539          p->subs[SUB_REAL].inthreeway = 0;
02540          /* If this was part of a three way call index, let us make
02541             another three way call */
02542          unalloc_sub(p, SUB_THREEWAY);
02543       } else {
02544          /* This wasn't any sort of call, but how are we an index? */
02545          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02546       }
02547    }
02548 
02549    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02550       p->owner = NULL;
02551       p->ringt = 0;
02552       p->distinctivering = 0;
02553       p->confirmanswer = 0;
02554       p->cidrings = 1;
02555       p->outgoing = 0;
02556       p->digital = 0;
02557       p->faxhandled = 0;
02558       p->pulsedial = 0;
02559       p->onhooktime = time(NULL);
02560 #ifdef HAVE_PRI
02561       p->proceeding = 0;
02562       p->progress = 0;
02563       p->alerting = 0;
02564       p->setup_ack = 0;
02565 #endif      
02566       if (p->dsp) {
02567          ast_dsp_free(p->dsp);
02568          p->dsp = NULL;
02569       }
02570 
02571       law = ZT_LAW_DEFAULT;
02572       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02573       if (res < 0) 
02574          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02575       /* Perform low level hangup if no owner left */
02576 #ifdef HAVE_PRI
02577       if (p->pri) {
02578 #ifdef SUPPORT_USERUSER
02579          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02580 #endif
02581 
02582          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02583          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02584             if (!pri_grab(p, p->pri)) {
02585                if (p->alreadyhungup) {
02586                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02587 
02588 #ifdef SUPPORT_USERUSER
02589                   pri_call_set_useruser(p->call, useruser);
02590 #endif
02591 
02592                   pri_hangup(p->pri->pri, p->call, -1);
02593                   p->call = NULL;
02594                   if (p->bearer) 
02595                      p->bearer->call = NULL;
02596                } else {
02597                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02598                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02599                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02600 
02601 #ifdef SUPPORT_USERUSER
02602                   pri_call_set_useruser(p->call, useruser);
02603 #endif
02604 
02605                   p->alreadyhungup = 1;
02606                   if (p->bearer)
02607                      p->bearer->alreadyhungup = 1;
02608                   if (cause) {
02609                      if (atoi(cause))
02610                         icause = atoi(cause);
02611                   }
02612                   pri_hangup(p->pri->pri, p->call, icause);
02613                }
02614                if (res < 0) 
02615                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02616                pri_rel(p->pri);        
02617             } else {
02618                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02619                res = -1;
02620             }
02621          } else {
02622             if (p->bearer)
02623                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02624             p->call = NULL;
02625             res = 0;
02626          }
02627       }
02628 #endif
02629       if (p->sig && (p->sig != SIG_PRI))
02630          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02631       if (res < 0) {
02632          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02633       }
02634       switch (p->sig) {
02635       case SIG_FXOGS:
02636       case SIG_FXOLS:
02637       case SIG_FXOKS:
02638          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02639          if (!res) {
02640 #if 0
02641             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02642 #endif
02643             /* If they're off hook, try playing congestion */
02644             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02645                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02646             else
02647                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02648          }
02649          break;
02650       case SIG_FXSGS:
02651       case SIG_FXSLS:
02652       case SIG_FXSKS:
02653          /* Make sure we're not made available for at least two seconds assuming
02654             we were actually used for an inbound or outbound call. */
02655          if (ast->_state != AST_STATE_RESERVED) {
02656             time(&p->guardtime);
02657             p->guardtime += 2;
02658          }
02659          break;
02660       default:
02661          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02662       }
02663       if (p->cidspill)
02664          free(p->cidspill);
02665       if (p->sig)
02666          zt_disable_ec(p);
02667       x = 0;
02668       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02669       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02670       p->didtdd = 0;
02671       p->cidspill = NULL;
02672       p->callwaitcas = 0;
02673       p->callwaiting = p->permcallwaiting;
02674       p->hidecallerid = p->permhidecallerid;
02675       p->dialing = 0;
02676       p->rdnis[0] = '\0';
02677       update_conf(p);
02678       reset_conf(p);
02679       /* Restore data mode */
02680       if (p->sig == SIG_PRI) {
02681          x = 0;
02682          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02683       }
02684 #ifdef HAVE_PRI
02685       if (p->bearer) {
02686          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02687          /* Free up the bearer channel as well, and
02688             don't use its file descriptor anymore */
02689          update_conf(p->bearer);
02690          reset_conf(p->bearer);
02691          p->bearer->owner = NULL;
02692          p->bearer->realcall = NULL;
02693          p->bearer = NULL;
02694          p->subs[SUB_REAL].zfd = -1;
02695          p->pri = NULL;
02696       }
02697 #endif
02698       restart_monitor();
02699    }
02700 
02701    p->callwaitingrepeat = 0;
02702    p->cidcwexpire = 0;
02703    p->oprmode = 0;
02704    ast->tech_pvt = NULL;
02705    ast_mutex_unlock(&p->lock);
02706    ast_module_unref(ast_module_info->self);
02707    if (option_verbose > 2) 
02708       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02709 
02710    ast_mutex_lock(&iflock);
02711    tmp = iflist;
02712    prev = NULL;
02713    if (p->destroy) {
02714       while (tmp) {
02715          if (tmp == p) {
02716             destroy_channel(prev, tmp, 0);
02717             break;
02718          } else {
02719             prev = tmp;
02720             tmp = tmp->next;
02721          }
02722       }
02723    }
02724    ast_mutex_unlock(&iflock);
02725    return 0;
02726 }
02727 
02728 static int zt_answer(struct ast_channel *ast)
02729 {
02730    struct zt_pvt *p = ast->tech_pvt;
02731    int res = 0;
02732    int index;
02733    int oldstate = ast->_state;
02734    ast_setstate(ast, AST_STATE_UP);
02735    ast_mutex_lock(&p->lock);
02736    index = zt_get_index(ast, p, 0);
02737    if (index < 0)
02738       index = SUB_REAL;
02739    /* nothing to do if a radio channel */
02740    if ((p->radio || (p->oprmode < 0))) {
02741       ast_mutex_unlock(&p->lock);
02742       return 0;
02743    }
02744    switch (p->sig) {
02745    case SIG_FXSLS:
02746    case SIG_FXSGS:
02747    case SIG_FXSKS:
02748       p->ringt = 0;
02749       /* Fall through */
02750    case SIG_EM:
02751    case SIG_EM_E1:
02752    case SIG_EMWINK:
02753    case SIG_FEATD:
02754    case SIG_FEATDMF:
02755    case SIG_FEATDMF_TA:
02756    case SIG_E911:
02757    case SIG_FGC_CAMA:
02758    case SIG_FGC_CAMAMF:
02759    case SIG_FEATB:
02760    case SIG_SF:
02761    case SIG_SFWINK:
02762    case SIG_SF_FEATD:
02763    case SIG_SF_FEATDMF:
02764    case SIG_SF_FEATB:
02765    case SIG_FXOLS:
02766    case SIG_FXOGS:
02767    case SIG_FXOKS:
02768       /* Pick up the line */
02769       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02770       if (p->hanguponpolarityswitch) {
02771          gettimeofday(&p->polaritydelaytv, NULL);
02772       }
02773       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02774       tone_zone_play_tone(p->subs[index].zfd, -1);
02775       p->dialing = 0;
02776       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02777          if (oldstate == AST_STATE_RINGING) {
02778             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02779             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02780             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02781             p->owner = p->subs[SUB_REAL].owner;
02782          }
02783       }
02784       if (p->sig & __ZT_SIG_FXS) {
02785          zt_enable_ec(p);
02786          zt_train_ec(p);
02787       }
02788       break;
02789 #ifdef HAVE_PRI
02790    case SIG_PRI:
02791       /* Send a pri acknowledge */
02792       if (!pri_grab(p, p->pri)) {
02793          p->proceeding = 1;
02794          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02795          pri_rel(p->pri);
02796       } else {
02797          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02798          res = -1;
02799       }
02800       break;
02801 #endif
02802    case 0:
02803       ast_mutex_unlock(&p->lock);
02804       return 0;
02805    default:
02806       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02807       res = -1;
02808    }
02809    ast_mutex_unlock(&p->lock);
02810    return res;
02811 }
02812 
02813 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02814 {
02815    char *cp;
02816    signed char *scp;
02817    int x;
02818    int index;
02819    struct zt_pvt *p = chan->tech_pvt, *pp;
02820    struct oprmode *oprmode;
02821    
02822 
02823    /* all supported options require data */
02824    if (!data || (datalen < 1)) {
02825       errno = EINVAL;
02826       return -1;
02827    }
02828 
02829    switch (option) {
02830    case AST_OPTION_TXGAIN:
02831       scp = (signed char *) data;
02832       index = zt_get_index(chan, p, 0);
02833       if (index < 0) {
02834          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02835          return -1;
02836       }
02837       ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02838       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02839    case AST_OPTION_RXGAIN:
02840       scp = (signed char *) data;
02841       index = zt_get_index(chan, p, 0);
02842       if (index < 0) {
02843          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02844          return -1;
02845       }
02846       ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02847       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02848    case AST_OPTION_TONE_VERIFY:
02849       if (!p->dsp)
02850          break;
02851       cp = (char *) data;
02852       switch (*cp) {
02853       case 1:
02854          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02855          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02856          break;
02857       case 2:
02858          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02859          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02860          break;
02861       default:
02862          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02863          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02864          break;
02865       }
02866       break;
02867    case AST_OPTION_TDD:
02868       /* turn on or off TDD */
02869       cp = (char *) data;
02870       p->mate = 0;
02871       if (!*cp) { /* turn it off */
02872          if (option_debug)
02873             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02874          if (p->tdd)
02875             tdd_free(p->tdd);
02876          p->tdd = 0;
02877          break;
02878       }
02879       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02880          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02881       zt_disable_ec(p);
02882       /* otherwise, turn it on */
02883       if (!p->didtdd) { /* if havent done it yet */
02884          unsigned char mybuf[41000], *buf;
02885          int size, res, fd, len;
02886          struct pollfd fds[1];
02887 
02888          buf = mybuf;
02889          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02890          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02891          len = 40000;
02892          index = zt_get_index(chan, p, 0);
02893          if (index < 0) {
02894             ast_log(LOG_WARNING, "No index in TDD?\n");
02895             return -1;
02896          }
02897          fd = p->subs[index].zfd;
02898          while (len) {
02899             if (ast_check_hangup(chan))
02900                return -1;
02901             size = len;
02902             if (size > READ_SIZE)
02903                size = READ_SIZE;
02904             fds[0].fd = fd;
02905             fds[0].events = POLLPRI | POLLOUT;
02906             fds[0].revents = 0;
02907             res = poll(fds, 1, -1);
02908             if (!res) {
02909                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02910                continue;
02911             }
02912             /* if got exception */
02913             if (fds[0].revents & POLLPRI)
02914                return -1;
02915             if (!(fds[0].revents & POLLOUT)) {
02916                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02917                continue;
02918             }
02919             res = write(fd, buf, size);
02920             if (res != size) {
02921                if (res == -1) return -1;
02922                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02923                break;
02924             }
02925             len -= size;
02926             buf += size;
02927          }
02928          p->didtdd = 1; /* set to have done it now */    
02929       }
02930       if (*cp == 2) { /* Mate mode */
02931          if (p->tdd)
02932             tdd_free(p->tdd);
02933          p->tdd = 0;
02934          p->mate = 1;
02935          break;
02936       }     
02937       if (!p->tdd) { /* if we dont have one yet */
02938          p->tdd = tdd_new(); /* allocate one */
02939       }     
02940       break;
02941    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02942       if (!p->dsp)
02943          break;
02944       cp = (char *) data;
02945       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02946          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02947       ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
02948       break;
02949    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02950       cp = (char *) data;
02951       if (!*cp) {    
02952          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02953          x = 0;
02954          zt_disable_ec(p);
02955       } else {    
02956          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02957          x = 1;
02958       }
02959       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02960          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02961       break;
02962    case AST_OPTION_OPRMODE:  /* Operator services mode */
02963       oprmode = (struct oprmode *) data;
02964       pp = oprmode->peer->tech_pvt;
02965       p->oprmode = pp->oprmode = 0;
02966       /* setup peers */
02967       p->oprpeer = pp;
02968       pp->oprpeer = p;
02969       /* setup modes, if any */
02970       if (oprmode->mode) 
02971       {
02972          pp->oprmode = oprmode->mode;
02973          p->oprmode = -oprmode->mode;
02974       }
02975       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
02976          oprmode->mode, chan->name,oprmode->peer->name);;
02977       break;
02978    case AST_OPTION_ECHOCAN:
02979       cp = (char *) data;
02980       if (*cp) {
02981          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
02982          zt_enable_ec(p);
02983       } else {
02984          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
02985          zt_disable_ec(p);
02986       }
02987       break;
02988    }
02989    errno = 0;
02990 
02991    return 0;
02992 }
02993 
02994 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
02995 {
02996    struct zt_pvt *p = chan->tech_pvt;
02997    
02998    if (!strcasecmp(data, "rxgain")) {
02999       ast_mutex_lock(&p->lock);
03000       snprintf(buf, len, "%f", p->rxgain);
03001       ast_mutex_unlock(&p->lock);   
03002    } else if (!strcasecmp(data, "txgain")) {
03003       ast_mutex_lock(&p->lock);
03004       snprintf(buf, len, "%f", p->txgain);
03005       ast_mutex_unlock(&p->lock);   
03006    } else {
03007       ast_copy_string(buf, "", len);
03008    }
03009    return 0;
03010 }
03011 
03012 
03013 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03014 {
03015    /* Unlink a specific slave or all slaves/masters from a given master */
03016    int x;
03017    int hasslaves;
03018    if (!master)
03019       return;
03020    if (needlock) {
03021       ast_mutex_lock(&master->lock);
03022       if (slave) {
03023          while (ast_mutex_trylock(&slave->lock)) {
03024             ast_mutex_unlock(&master->lock);
03025             usleep(1);
03026             ast_mutex_lock(&master->lock);
03027          }
03028       }
03029    }
03030    hasslaves = 0;
03031    for (x = 0; x < MAX_SLAVES; x++) {
03032       if (master->slaves[x]) {
03033          if (!slave || (master->slaves[x] == slave)) {
03034             /* Take slave out of the conference */
03035             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03036             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03037             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03038             master->slaves[x]->master = NULL;
03039             master->slaves[x] = NULL;
03040          } else
03041             hasslaves = 1;
03042       }
03043       if (!hasslaves)
03044          master->inconference = 0;
03045    }
03046    if (!slave) {
03047       if (master->master) {
03048          /* Take master out of the conference */
03049          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03050          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03051          hasslaves = 0;
03052          for (x = 0; x < MAX_SLAVES; x++) {
03053             if (master->master->slaves[x] == master)
03054                master->master->slaves[x] = NULL;
03055             else if (master->master->slaves[x])
03056                hasslaves = 1;
03057          }
03058          if (!hasslaves)
03059             master->master->inconference = 0;
03060       }
03061       master->master = NULL;
03062    }
03063    update_conf(master);
03064    if (needlock) {
03065       if (slave)
03066          ast_mutex_unlock(&slave->lock);
03067       ast_mutex_unlock(&master->lock);
03068    }
03069 }
03070 
03071 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03072    int x;
03073    if (!slave || !master) {
03074       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03075       return;
03076    }
03077    for (x = 0; x < MAX_SLAVES; x++) {
03078       if (!master->slaves[x]) {
03079          master->slaves[x] = slave;
03080          break;
03081       }
03082    }
03083    if (x >= MAX_SLAVES) {
03084       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03085       master->slaves[MAX_SLAVES - 1] = slave;
03086    }
03087    if (slave->master) 
03088       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03089    slave->master = master;
03090    
03091    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03092 }
03093 
03094 static void disable_dtmf_detect(struct zt_pvt *p)
03095 {
03096 #ifdef ZT_TONEDETECT
03097    int val;
03098 #endif
03099 
03100    p->ignoredtmf = 1;
03101 
03102 #ifdef ZT_TONEDETECT
03103    val = 0;
03104    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03105 #endif      
03106    if (!p->hardwaredtmf && p->dsp) {
03107       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03108       ast_dsp_set_features(p->dsp, p->dsp_features);
03109    }
03110 }
03111 
03112 static void enable_dtmf_detect(struct zt_pvt *p)
03113 {
03114 #ifdef ZT_TONEDETECT
03115    int val;
03116 #endif
03117 
03118    if (p->channel == CHAN_PSEUDO)
03119       return;
03120 
03121    p->ignoredtmf = 0;
03122 
03123 #ifdef ZT_TONEDETECT
03124    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03125    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03126 #endif      
03127    if (!p->hardwaredtmf && p->dsp) {
03128       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03129       ast_dsp_set_features(p->dsp, p->dsp_features);
03130    }
03131 }
03132 
03133 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)
03134 {
03135    struct ast_channel *who;
03136    struct zt_pvt *p0, *p1, *op0, *op1;
03137    struct zt_pvt *master = NULL, *slave = NULL;
03138    struct ast_frame *f;
03139    int inconf = 0;
03140    int nothingok = 1;
03141    int ofd0, ofd1;
03142    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03143    int os0 = -1, os1 = -1;
03144    int priority = 0;
03145    struct ast_channel *oc0, *oc1;
03146    enum ast_bridge_result res;
03147 
03148 #ifdef PRI_2BCT
03149    int triedtopribridge = 0;
03150    q931_call *q931c0 = NULL, *q931c1 = NULL;
03151 #endif
03152 
03153    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03154       There is code below to handle it properly until DTMF is actually seen,
03155       but due to currently unresolved issues it's ignored...
03156    */
03157 
03158    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03159       return AST_BRIDGE_FAILED_NOWARN;
03160 
03161    ast_mutex_lock(&c0->lock);
03162    ast_mutex_lock(&c1->lock);
03163 
03164    p0 = c0->tech_pvt;
03165    p1 = c1->tech_pvt;
03166    /* cant do pseudo-channels here */
03167    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03168       ast_mutex_unlock(&c0->lock);
03169       ast_mutex_unlock(&c1->lock);
03170       return AST_BRIDGE_FAILED_NOWARN;
03171    }
03172 
03173    oi0 = zt_get_index(c0, p0, 0);
03174    oi1 = zt_get_index(c1, p1, 0);
03175    if ((oi0 < 0) || (oi1 < 0)) {
03176       ast_mutex_unlock(&c0->lock);
03177       ast_mutex_unlock(&c1->lock);
03178       return AST_BRIDGE_FAILED;
03179    }
03180 
03181    op0 = p0 = c0->tech_pvt;
03182    op1 = p1 = c1->tech_pvt;
03183    ofd0 = c0->fds[0];
03184    ofd1 = c1->fds[0];
03185    oc0 = p0->owner;
03186    oc1 = p1->owner;
03187 
03188    if (ast_mutex_trylock(&p0->lock)) {
03189       /* Don't block, due to potential for deadlock */
03190       ast_mutex_unlock(&c0->lock);
03191       ast_mutex_unlock(&c1->lock);
03192       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03193       return AST_BRIDGE_RETRY;
03194    }
03195    if (ast_mutex_trylock(&p1->lock)) {
03196       /* Don't block, due to potential for deadlock */
03197       ast_mutex_unlock(&p0->lock);
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 
03204    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03205       if (p0->owner && p1->owner) {
03206          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03207          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03208             master = p0;
03209             slave = p1;
03210             inconf = 1;
03211          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03212             master = p1;
03213             slave = p0;
03214             inconf = 1;
03215          } else {
03216             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03217             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03218                p0->channel,
03219                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03220                p0->subs[SUB_REAL].inthreeway, p0->channel,
03221                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03222                p1->subs[SUB_REAL].inthreeway);
03223          }
03224          nothingok = 0;
03225       }
03226    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03227       if (p1->subs[SUB_THREEWAY].inthreeway) {
03228          master = p1;
03229          slave = p0;
03230          nothingok = 0;
03231       }
03232    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03233       if (p0->subs[SUB_THREEWAY].inthreeway) {
03234          master = p0;
03235          slave = p1;
03236          nothingok = 0;
03237       }
03238    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03239       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03240          don't put us in anything */
03241       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03242          master = p1;
03243          slave = p0;
03244          nothingok = 0;
03245       }
03246    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03247       /* Same as previous */
03248       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03249          master = p0;
03250          slave = p1;
03251          nothingok = 0;
03252       }
03253    }
03254    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03255       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03256    if (master && slave) {
03257       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03258          in an active threeway call with a channel that is ringing, we should
03259          indicate ringing. */
03260       if ((oi1 == SUB_THREEWAY) && 
03261           p1->subs[SUB_THREEWAY].inthreeway && 
03262           p1->subs[SUB_REAL].owner && 
03263           p1->subs[SUB_REAL].inthreeway && 
03264           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03265          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03266          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03267          os1 = p1->subs[SUB_REAL].owner->_state;
03268       } else {
03269          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03270          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03271       }
03272       if ((oi0 == SUB_THREEWAY) && 
03273           p0->subs[SUB_THREEWAY].inthreeway && 
03274           p0->subs[SUB_REAL].owner && 
03275           p0->subs[SUB_REAL].inthreeway && 
03276           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03277          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03278          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03279          os0 = p0->subs[SUB_REAL].owner->_state;
03280       } else {
03281          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03282          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03283       }
03284       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03285          if (!p0->echocanbridged || !p1->echocanbridged) {
03286             /* Disable echo cancellation if appropriate */
03287             zt_disable_ec(p0);
03288             zt_disable_ec(p1);
03289          }
03290       }
03291       zt_link(slave, master);
03292       master->inconference = inconf;
03293    } else if (!nothingok)
03294       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03295 
03296    update_conf(p0);
03297    update_conf(p1);
03298    t0 = p0->subs[SUB_REAL].inthreeway;
03299    t1 = p1->subs[SUB_REAL].inthreeway;
03300 
03301    ast_mutex_unlock(&p0->lock);
03302    ast_mutex_unlock(&p1->lock);
03303 
03304    ast_mutex_unlock(&c0->lock);
03305    ast_mutex_unlock(&c1->lock);
03306 
03307    /* Native bridge failed */
03308    if ((!master || !slave) && !nothingok) {
03309       zt_enable_ec(p0);
03310       zt_enable_ec(p1);
03311       return AST_BRIDGE_FAILED;
03312    }
03313    
03314    if (option_verbose > 2) 
03315       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03316 
03317    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03318       disable_dtmf_detect(op0);
03319 
03320    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03321       disable_dtmf_detect(op1);
03322 
03323    for (;;) {
03324       struct ast_channel *c0_priority[2] = {c0, c1};
03325       struct ast_channel *c1_priority[2] = {c1, c0};
03326 
03327       /* Here's our main loop...  Start by locking things, looking for private parts, 
03328          and then balking if anything is wrong */
03329       ast_mutex_lock(&c0->lock);
03330       ast_mutex_lock(&c1->lock);
03331       p0 = c0->tech_pvt;
03332       p1 = c1->tech_pvt;
03333 
03334       if (op0 == p0)
03335          i0 = zt_get_index(c0, p0, 1);
03336       if (op1 == p1)
03337          i1 = zt_get_index(c1, p1, 1);
03338       ast_mutex_unlock(&c0->lock);
03339       ast_mutex_unlock(&c1->lock);
03340 
03341       if (!timeoutms || 
03342           (op0 != p0) ||
03343           (op1 != p1) || 
03344           (ofd0 != c0->fds[0]) || 
03345           (ofd1 != c1->fds[0]) ||
03346           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03347           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03348           (oc0 != p0->owner) || 
03349           (oc1 != p1->owner) ||
03350           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03351           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03352           (oi0 != i0) ||
03353           (oi1 != i1)) {
03354          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03355             op0->channel, oi0, op1->channel, oi1);
03356          res = AST_BRIDGE_RETRY;
03357          goto return_from_bridge;
03358       }
03359 
03360 #ifdef PRI_2BCT
03361       q931c0 = p0->call;
03362       q931c1 = p1->call;
03363       if (p0->transfer && p1->transfer 
03364           && q931c0 && q931c1 
03365           && !triedtopribridge) {
03366          pri_channel_bridge(q931c0, q931c1);
03367          triedtopribridge = 1;
03368       }
03369 #endif
03370 
03371       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03372       if (!who) {
03373          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03374          continue;
03375       }
03376       f = ast_read(who);
03377       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03378          *fo = f;
03379          *rc = who;
03380          res = AST_BRIDGE_COMPLETE;
03381          goto return_from_bridge;
03382       }
03383       if (f->frametype == AST_FRAME_DTMF) {
03384          if ((who == c0) && p0->pulsedial) {
03385             ast_write(c1, f);
03386          } else if ((who == c1) && p1->pulsedial) {
03387             ast_write(c0, f);
03388          } else {
03389             *fo = f;
03390             *rc = who;
03391             res = AST_BRIDGE_COMPLETE;
03392             goto return_from_bridge;
03393          }
03394       }
03395       ast_frfree(f);
03396       
03397       /* Swap who gets priority */
03398       priority = !priority;
03399    }
03400 
03401 return_from_bridge:
03402    if (op0 == p0)
03403       zt_enable_ec(p0);
03404 
03405    if (op1 == p1)
03406       zt_enable_ec(p1);
03407 
03408    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03409       enable_dtmf_detect(op0);
03410 
03411    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03412       enable_dtmf_detect(op1);
03413 
03414    zt_unlink(slave, master, 1);
03415 
03416    return res;
03417 }
03418 
03419 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03420 {
03421    struct zt_pvt *p = newchan->tech_pvt;
03422    int x;
03423    ast_mutex_lock(&p->lock);
03424    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03425    if (p->owner == oldchan) {
03426       p->owner = newchan;
03427    }
03428    for (x = 0; x < 3; x++)
03429       if (p->subs[x].owner == oldchan) {
03430          if (!x)
03431             zt_unlink(NULL, p, 0);
03432          p->subs[x].owner = newchan;
03433       }
03434    if (newchan->_state == AST_STATE_RINGING) 
03435       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03436    update_conf(p);
03437    ast_mutex_unlock(&p->lock);
03438    return 0;
03439 }
03440 
03441 static int zt_ring_phone(struct zt_pvt *p)
03442 {
03443    int x;
03444    int res;
03445    /* Make sure our transmit state is on hook */
03446    x = 0;
03447    x = ZT_ONHOOK;
03448    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03449    do {
03450       x = ZT_RING;
03451       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03452       if (res) {
03453          switch (errno) {
03454          case EBUSY:
03455          case EINTR:
03456             /* Wait just in case */
03457             usleep(10000);
03458             continue;
03459          case EINPROGRESS:
03460             res = 0;
03461             break;
03462          default:
03463             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03464             res = 0;
03465          }
03466       }
03467    } while (res);
03468    return res;
03469 }
03470 
03471 static void *ss_thread(void *data);
03472 
03473 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03474 
03475 static int attempt_transfer(struct zt_pvt *p)
03476 {
03477    /* In order to transfer, we need at least one of the channels to
03478       actually be in a call bridge.  We can't conference two applications
03479       together (but then, why would we want to?) */
03480    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03481       /* The three-way person we're about to transfer to could still be in MOH, so
03482          stop if now if appropriate */
03483       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03484          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03485       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03486          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03487       }
03488       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03489          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03490       }
03491       if (p->subs[SUB_REAL].owner->cdr) {
03492          /* Move CDR from second channel to current one */
03493          p->subs[SUB_THREEWAY].owner->cdr =
03494             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03495          p->subs[SUB_REAL].owner->cdr = NULL;
03496       }
03497       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03498          /* Move CDR from second channel's bridge to current one */
03499          p->subs[SUB_THREEWAY].owner->cdr =
03500             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03501          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03502       }
03503        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03504          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03505                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03506          return -1;
03507       }
03508       /* Orphan the channel after releasing the lock */
03509       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03510       unalloc_sub(p, SUB_THREEWAY);
03511    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03512       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03513       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03514          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03515       }
03516       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03517          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03518       }
03519       if (p->subs[SUB_THREEWAY].owner->cdr) {
03520          /* Move CDR from second channel to current one */
03521          p->subs[SUB_REAL].owner->cdr = 
03522             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03523          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03524       }
03525       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03526          /* Move CDR from second channel's bridge to current one */
03527          p->subs[SUB_REAL].owner->cdr = 
03528             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03529          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03530       }
03531       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03532          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03533                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03534          return -1;
03535       }
03536       /* Three-way is now the REAL */
03537       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03538       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03539       unalloc_sub(p, SUB_THREEWAY);
03540       /* Tell the caller not to hangup */
03541       return 1;
03542    } else {
03543       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03544                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03545       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03546       return -1;
03547    }
03548    return 0;
03549 }
03550 
03551 static int check_for_conference(struct zt_pvt *p)
03552 {
03553    ZT_CONFINFO ci;
03554    /* Fine if we already have a master, etc */
03555    if (p->master || (p->confno > -1))
03556       return 0;
03557    memset(&ci, 0, sizeof(ci));
03558    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03559       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03560       return 0;
03561    }
03562    /* If we have no master and don't have a confno, then 
03563       if we're in a conference, it's probably a MeetMe room or
03564       some such, so don't let us 3-way out! */
03565    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03566       if (option_verbose > 2) 
03567          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03568       return 1;
03569    }
03570    return 0;
03571 }
03572 
03573 static int get_alarms(struct zt_pvt *p)
03574 {
03575    int res;
03576    ZT_SPANINFO zi;
03577    memset(&zi, 0, sizeof(zi));
03578    zi.spanno = p->span;
03579    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03580    if (res < 0) {
03581       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03582       return 0;
03583    }
03584    return zi.alarms;
03585 }
03586 
03587 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03588 {
03589    struct zt_pvt *p = ast->tech_pvt;
03590    struct ast_frame *f = *dest;
03591 
03592    ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03593    if (p->confirmanswer) {
03594       ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03595       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03596          of a DTMF digit */
03597       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03598       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03599       *dest = &p->subs[index].f;
03600       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03601       p->confirmanswer = 0;
03602    } else if (p->callwaitcas) {
03603       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03604          ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03605          if (p->cidspill)
03606             free(p->cidspill);
03607          send_cwcidspill(p);
03608       }
03609       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03610          p->callwaitcas = 0;
03611       p->subs[index].f.frametype = AST_FRAME_NULL;
03612       p->subs[index].f.subclass = 0;
03613       *dest = &p->subs[index].f;
03614    } else if (f->subclass == 'f') {
03615       /* Fax tone -- Handle and return NULL */
03616       if ((p->callprogress & 0x6) && !p->faxhandled) {
03617          p->faxhandled++;
03618          if (strcmp(ast->exten, "fax")) {
03619             const char *target_context = S_OR(ast->macrocontext, ast->context);
03620 
03621             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03622                if (option_verbose > 2)
03623                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03624                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03625                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03626                if (ast_async_goto(ast, target_context, "fax", 1))
03627                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03628             } else
03629                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03630          } else
03631             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03632       } else
03633             ast_log(LOG_DEBUG, "Fax already handled\n");
03634       zt_confmute(p, 0);
03635       p->subs[index].f.frametype = AST_FRAME_NULL;
03636       p->subs[index].f.subclass = 0;
03637       *dest = &p->subs[index].f;
03638    } else if (f->subclass == 'm') {
03639       /* Confmute request */
03640       zt_confmute(p, 1);
03641       p->subs[index].f.frametype = AST_FRAME_NULL;
03642       p->subs[index].f.subclass = 0;
03643       *dest = &p->subs[index].f;    
03644    } else if (f->subclass == 'u') {
03645       /* Unmute */
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
03651       zt_confmute(p, 0);
03652 }
03653          
03654 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03655 {
03656    int res, x;
03657    int index, mysig;
03658    char *c;
03659    struct zt_pvt *p = ast->tech_pvt;
03660    pthread_t threadid;
03661    pthread_attr_t attr;
03662    struct ast_channel *chan;
03663    struct ast_frame *f;
03664 
03665    index = zt_get_index(ast, p, 0);
03666    mysig = p->sig;
03667    if (p->outsigmod > -1)
03668       mysig = p->outsigmod;
03669    p->subs[index].f.frametype = AST_FRAME_NULL;
03670    p->subs[index].f.subclass = 0;
03671    p->subs[index].f.datalen = 0;
03672    p->subs[index].f.samples = 0;
03673    p->subs[index].f.mallocd = 0;
03674    p->subs[index].f.offset = 0;
03675    p->subs[index].f.src = "zt_handle_event";
03676    p->subs[index].f.data = NULL;
03677    f = &p->subs[index].f;
03678 
03679    if (index < 0)
03680       return &p->subs[index].f;
03681    if (p->fake_event) {
03682       res = p->fake_event;
03683       p->fake_event = 0;
03684    } else
03685       res = zt_get_event(p->subs[index].zfd);
03686 
03687    ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03688 
03689    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03690       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03691 
03692       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03693 #ifdef HAVE_PRI
03694       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03695          /* absorb event */
03696       } else {
03697 #endif
03698          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03699          p->subs[index].f.subclass = res & 0xff;
03700 #ifdef HAVE_PRI
03701       }
03702 #endif
03703       zt_handle_dtmfup(ast, index, &f);
03704       return f;
03705    }
03706 
03707    if (res & ZT_EVENT_DTMFDOWN) {
03708       ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03709       /* Mute conference */
03710       zt_confmute(p, 1);
03711       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03712       p->subs[index].f.subclass = res & 0xff;
03713       return &p->subs[index].f;
03714    }
03715 
03716    switch (res) {
03717 #ifdef ZT_EVENT_EC_DISABLED
03718       case ZT_EVENT_EC_DISABLED:
03719          if (option_verbose > 2) 
03720             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03721          p->echocanon = 0;
03722          break;
03723 #endif
03724       case ZT_EVENT_BITSCHANGED:
03725          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03726       case ZT_EVENT_PULSE_START:
03727          /* Stop tone if there's a pulse start and the PBX isn't started */
03728          if (!ast->pbx)
03729             tone_zone_play_tone(p->subs[index].zfd, -1);
03730          break;   
03731       case ZT_EVENT_DIALCOMPLETE:
03732          if (p->inalarm) break;
03733          if ((p->radio || (p->oprmode < 0))) break;
03734          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03735             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03736             return NULL;
03737          }
03738          if (!x) { /* if not still dialing in driver */
03739             zt_enable_ec(p);
03740             if (p->echobreak) {
03741                zt_train_ec(p);
03742                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03743                p->dop.op = ZT_DIAL_OP_REPLACE;
03744                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03745                p->echobreak = 0;
03746             } else {
03747                p->dialing = 0;
03748                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03749                   /* if thru with dialing after offhook */
03750                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03751                      ast_setstate(ast, AST_STATE_UP);
03752                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03753                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03754                      break;
03755                   } else { /* if to state wait for offhook to dial rest */
03756                      /* we now wait for off hook */
03757                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03758                   }
03759                }
03760                if (ast->_state == AST_STATE_DIALING) {
03761                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03762                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03763                   } 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)))) {
03764                      ast_setstate(ast, AST_STATE_RINGING);
03765                   } else if (!p->answeronpolarityswitch) {
03766                      ast_setstate(ast, AST_STATE_UP);
03767                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03768                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03769                   }
03770                }
03771             }
03772          }
03773          break;
03774       case ZT_EVENT_ALARM:
03775 #ifdef HAVE_PRI
03776          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03777             /* T309 is not enabled : hangup calls when alarm occurs */
03778             if (p->call) {
03779                if (p->pri && p->pri->pri) {
03780                   if (!pri_grab(p, p->pri)) {
03781                      pri_hangup(p->pri->pri, p->call, -1);
03782                      pri_destroycall(p->pri->pri, p->call);
03783                      p->call = NULL;
03784                      pri_rel(p->pri);
03785                   } else
03786                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03787                } else
03788                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03789             }
03790             if (p->owner)
03791                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03792          }
03793          if (p->bearer)
03794             p->bearer->inalarm = 1;
03795          else
03796 #endif
03797          p->inalarm = 1;
03798          res = get_alarms(p);
03799          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
03800          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03801                         "Alarm: %s\r\n"
03802                         "Channel: %d\r\n",
03803                         alarm2str(res), p->channel);
03804 #ifdef HAVE_LIBPRI
03805          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
03806             /* fall through intentionally */
03807          } else {
03808             break;
03809          }
03810 #endif
03811       case ZT_EVENT_ONHOOK:
03812          if (p->radio) {
03813             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03814             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03815             break;
03816          }
03817          if (p->oprmode < 0)
03818          {
03819             if (p->oprmode != -1) break;
03820             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03821             {
03822                /* Make sure it starts ringing */
03823                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03824                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
03825                save_conference(p->oprpeer);
03826                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03827             }
03828             break;
03829          }
03830          switch (p->sig) {
03831          case SIG_FXOLS:
03832          case SIG_FXOGS:
03833          case SIG_FXOKS:
03834             p->onhooktime = time(NULL);
03835             p->msgstate = -1;
03836             /* Check for some special conditions regarding call waiting */
03837             if (index == SUB_REAL) {
03838                /* The normal line was hung up */
03839                if (p->subs[SUB_CALLWAIT].owner) {
03840                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03841                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03842                   if (option_verbose > 2) 
03843                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03844                   unalloc_sub(p, SUB_CALLWAIT); 
03845 #if 0
03846                   p->subs[index].needanswer = 0;
03847                   p->subs[index].needringing = 0;
03848 #endif                  
03849                   p->callwaitingrepeat = 0;
03850                   p->cidcwexpire = 0;
03851                   p->owner = NULL;
03852                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03853                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03854                      p->dialing = 1;
03855                   zt_ring_phone(p);
03856                } else if (p->subs[SUB_THREEWAY].owner) {
03857                   unsigned int mssinceflash;
03858                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03859                      the private structure -- not especially easy or clean */
03860                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03861                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03862                      ast_mutex_unlock(&p->lock);
03863                      ast_mutex_unlock(&ast->lock);
03864                      usleep(1);
03865                      /* We can grab ast and p in that order, without worry.  We should make sure
03866                         nothing seriously bad has happened though like some sort of bizarre double
03867                         masquerade! */
03868                      ast_mutex_lock(&ast->lock);
03869                      ast_mutex_lock(&p->lock);
03870                      if (p->owner != ast) {
03871                         ast_log(LOG_WARNING, "This isn't good...\n");
03872                         return NULL;
03873                      }
03874                   }
03875                   if (!p->subs[SUB_THREEWAY].owner) {
03876                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03877                      return NULL;
03878                   }
03879                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03880                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03881                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03882                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03883                         hanging up.  Hangup both channels now */
03884                      if (p->subs[SUB_THREEWAY].owner)
03885                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03886                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03887                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03888                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03889                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03890                      if (p->transfer) {
03891                         /* In any case this isn't a threeway call anymore */
03892                         p->subs[SUB_REAL].inthreeway = 0;
03893                         p->subs[SUB_THREEWAY].inthreeway = 0;
03894                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03895                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03896                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03897                            /* Swap subs and dis-own channel */
03898                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03899                            p->owner = NULL;
03900                            /* Ring the phone */
03901                            zt_ring_phone(p);
03902                         } else {
03903                            if ((res = attempt_transfer(p)) < 0) {
03904                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03905                               if (p->subs[SUB_THREEWAY].owner)
03906                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03907                            } else if (res) {
03908                               /* Don't actually hang up at this point */
03909                               if (p->subs[SUB_THREEWAY].owner)
03910                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03911                               break;
03912                            }
03913                         }
03914                      } else {
03915                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03916                         if (p->subs[SUB_THREEWAY].owner)
03917                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03918                      }
03919                   } else {
03920                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03921                      /* Swap subs and dis-own channel */
03922                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03923                      p->owner = NULL;
03924                      /* Ring the phone */
03925                      zt_ring_phone(p);
03926                   }
03927                }
03928             } else {
03929                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03930             }
03931             /* Fall through */
03932          default:
03933             zt_disable_ec(p);
03934             return NULL;
03935          }
03936          break;
03937       case ZT_EVENT_RINGOFFHOOK:
03938          if (p->inalarm) break;
03939          if (p->oprmode < 0)
03940          {
03941             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03942             {
03943                /* Make sure it stops ringing */
03944                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03945                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
03946                restore_conference(p->oprpeer);
03947             }
03948             break;
03949          }
03950          if (p->radio)
03951          {
03952             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03953             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
03954             break;
03955          }
03956          /* for E911, its supposed to wait for offhook then dial
03957             the second half of the dial string */
03958          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
03959             c = strchr(p->dialdest, '/');
03960             if (c)
03961                c++;
03962             else
03963                c = p->dialdest;
03964             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
03965             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
03966             if (strlen(p->dop.dialstr) > 4) {
03967                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
03968                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
03969                p->echorest[sizeof(p->echorest) - 1] = '\0';
03970                p->echobreak = 1;
03971                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
03972             } else
03973                p->echobreak = 0;
03974             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
03975                x = ZT_ONHOOK;
03976                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03977                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
03978                return NULL;
03979                }
03980             p->dialing = 1;
03981             return &p->subs[index].f;
03982          }
03983          switch (p->sig) {
03984          case SIG_FXOLS:
03985          case SIG_FXOGS:
03986          case SIG_FXOKS:
03987             switch (ast->_state) {
03988             case AST_STATE_RINGING:
03989                zt_enable_ec(p);
03990                zt_train_ec(p);
03991                p->subs[index].f.frametype = AST_FRAME_CONTROL;
03992                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03993                /* Make sure it stops ringing */
03994                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
03995                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
03996                if (p->cidspill) {
03997                   /* Cancel any running CallerID spill */
03998                   free(p->cidspill);
03999                   p->cidspill = NULL;
04000                }
04001                p->dialing = 0;
04002                p->callwaitcas = 0;
04003                if (p->confirmanswer) {
04004                   /* Ignore answer if "confirm answer" is enabled */
04005                   p->subs[index].f.frametype = AST_FRAME_NULL;
04006                   p->subs[index].f.subclass = 0;
04007                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04008                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04009                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04010                   if (res < 0) {
04011                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04012                      p->dop.dialstr[0] = '\0';
04013                      return NULL;
04014                   } else {
04015                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04016                      p->subs[index].f.frametype = AST_FRAME_NULL;
04017                      p->subs[index].f.subclass = 0;
04018                      p->dialing = 1;
04019                   }
04020                   p->dop.dialstr[0] = '\0';
04021                   ast_setstate(ast, AST_STATE_DIALING);
04022                } else
04023                   ast_setstate(ast, AST_STATE_UP);
04024                return &p->subs[index].f;
04025             case AST_STATE_DOWN:
04026                ast_setstate(ast, AST_STATE_RING);
04027                ast->rings = 1;
04028                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04029                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04030                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04031                return &p->subs[index].f;
04032             case AST_STATE_UP:
04033                /* Make sure it stops ringing */
04034                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04035                /* Okay -- probably call waiting*/
04036                if (ast_bridged_channel(p->owner))
04037                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04038                p->subs[index].needunhold = 1;
04039                break;
04040             case AST_STATE_RESERVED:
04041                /* Start up dialtone */
04042                if (has_voicemail(p))
04043                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04044                else
04045                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04046                break;
04047             default:
04048                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04049             }
04050             break;
04051          case SIG_FXSLS:
04052          case SIG_FXSGS:
04053          case SIG_FXSKS:
04054             if (ast->_state == AST_STATE_RING) {
04055                p->ringt = p->ringt_base;
04056             }
04057 
04058             /* If we get a ring then we cannot be in 
04059              * reversed polarity. So we reset to idle */
04060             ast_log(LOG_DEBUG, "Setting IDLE polarity due "
04061                "to ring. Old polarity was %d\n", 
04062                p->polarity);
04063             p->polarity = POLARITY_IDLE;
04064 
04065             /* Fall through */
04066          case SIG_EM:
04067          case SIG_EM_E1:
04068          case SIG_EMWINK:
04069          case SIG_FEATD:
04070          case SIG_FEATDMF:
04071          case SIG_FEATDMF_TA:
04072          case SIG_E911:
04073          case SIG_FGC_CAMA:
04074          case SIG_FGC_CAMAMF:
04075          case SIG_FEATB:
04076          case SIG_SF:
04077          case SIG_SFWINK:
04078          case SIG_SF_FEATD:
04079          case SIG_SF_FEATDMF:
04080          case SIG_SF_FEATB:
04081             if (ast->_state == AST_STATE_PRERING)
04082                ast_setstate(ast, AST_STATE_RING);
04083             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04084                if (option_debug)
04085                   ast_log(LOG_DEBUG, "Ring detected\n");
04086                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04087                p->subs[index].f.subclass = AST_CONTROL_RING;
04088             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04089                if (option_debug)
04090                   ast_log(LOG_DEBUG, "Line answered\n");
04091                if (p->confirmanswer) {
04092                   p->subs[index].f.frametype = AST_FRAME_NULL;
04093                   p->subs[index].f.subclass = 0;
04094                } else {
04095                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04096                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04097                   ast_setstate(ast, AST_STATE_UP);
04098                }
04099             } else if (ast->_state != AST_STATE_RING)
04100                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04101             break;
04102          default:
04103             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04104          }
04105          break;
04106 #ifdef ZT_EVENT_RINGBEGIN
04107       case ZT_EVENT_RINGBEGIN:
04108          switch (p->sig) {
04109          case SIG_FXSLS:
04110          case SIG_FXSGS:
04111          case SIG_FXSKS:
04112             if (ast->_state == AST_STATE_RING) {
04113                p->ringt = p->ringt_base;
04114             }
04115             break;
04116          }
04117          break;
04118 #endif         
04119       case ZT_EVENT_RINGEROFF:
04120          if (p->inalarm) break;
04121          if ((p->radio || (p->oprmode < 0))) break;
04122          ast->rings++;
04123          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04124             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04125             free(p->cidspill);
04126             p->cidspill = NULL;
04127             p->callwaitcas = 0;
04128          }
04129          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04130          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04131          break;
04132       case ZT_EVENT_RINGERON:
04133          break;
04134       case ZT_EVENT_NOALARM:
04135          p->inalarm = 0;
04136 #ifdef HAVE_PRI
04137          /* Extremely unlikely but just in case */
04138          if (p->bearer)
04139             p->bearer->inalarm = 0;
04140 #endif            
04141          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04142          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04143                         "Channel: %d\r\n", p->channel);
04144          break;
04145       case ZT_EVENT_WINKFLASH:
04146          if (p->inalarm) break;
04147          if (p->radio) break;
04148          if (p->oprmode < 0) break;
04149          if (p->oprmode > 1)
04150          {
04151             struct zt_params par;
04152 
04153             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04154             {
04155                if (!par.rxisoffhook)
04156                {
04157                   /* Make sure it stops ringing */
04158                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04159                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04160                   save_conference(p);
04161                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04162                }
04163             }
04164             break;
04165          }
04166          /* Remember last time we got a flash-hook */
04167          gettimeofday(&p->flashtime, NULL);
04168          switch (mysig) {
04169          case SIG_FXOLS:
04170          case SIG_FXOGS:
04171          case SIG_FXOKS:
04172             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04173                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04174             p->callwaitcas = 0;
04175 
04176             if (index != SUB_REAL) {
04177                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04178                goto winkflashdone;
04179             }
04180             
04181             if (p->subs[SUB_CALLWAIT].owner) {
04182                /* Swap to call-wait */
04183                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04184                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04185                p->owner = p->subs[SUB_REAL].owner;
04186                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04187                if (p->owner->_state == AST_STATE_RINGING) {
04188                   ast_setstate(p->owner, AST_STATE_UP);
04189                   p->subs[SUB_REAL].needanswer = 1;
04190                }
04191                p->callwaitingrepeat = 0;
04192                p->cidcwexpire = 0;
04193                /* Start music on hold if appropriate */
04194                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04195                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04196                      S_OR(p->mohsuggest, NULL),
04197                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04198                }
04199                p->subs[SUB_CALLWAIT].needhold = 1;
04200                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04201                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04202                      S_OR(p->mohsuggest, NULL),
04203                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04204                }
04205                p->subs[SUB_REAL].needunhold = 1;
04206             } else if (!p->subs[SUB_THREEWAY].owner) {
04207                char cid_num[256];
04208                char cid_name[256];
04209 
04210                if (!p->threewaycalling) {
04211                   /* Just send a flash if no 3-way calling */
04212                   p->subs[SUB_REAL].needflash = 1;
04213                   goto winkflashdone;
04214                } else if (!check_for_conference(p)) {
04215                   if (p->zaptrcallerid && p->owner) {
04216                      if (p->owner->cid.cid_num)
04217                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04218                      if (p->owner->cid.cid_name)
04219                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04220                   }
04221                   /* XXX This section needs much more error checking!!! XXX */
04222                   /* Start a 3-way call if feasible */
04223                   if (!((ast->pbx) ||
04224                         (ast->_state == AST_STATE_UP) ||
04225                         (ast->_state == AST_STATE_RING))) {
04226                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04227                         goto winkflashdone;
04228                   }
04229                   if (alloc_sub(p, SUB_THREEWAY)) {
04230                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04231                      goto winkflashdone;
04232                   }
04233                   /* Make new channel */
04234                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04235                   if (p->zaptrcallerid) {
04236                      if (!p->origcid_num)
04237                         p->origcid_num = ast_strdup(p->cid_num);
04238                      if (!p->origcid_name)
04239                         p->origcid_name = ast_strdup(p->cid_name);
04240                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04241                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04242                   }
04243                   /* Swap things around between the three-way and real call */
04244                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04245                   /* Disable echo canceller for better dialing */
04246                   zt_disable_ec(p);
04247                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04248                   if (res)
04249                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04250                   p->owner = chan;
04251                   pthread_attr_init(&attr);
04252                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04253                   if (!chan) {
04254                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04255                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04256                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04257                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04258                      zt_enable_ec(p);
04259                      ast_hangup(chan);
04260                   } else {
04261                      if (option_verbose > 2) 
04262                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04263                      /* Start music on hold if appropriate */
04264                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04265                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04266                            S_OR(p->mohsuggest, NULL),
04267                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04268                      }
04269                      p->subs[SUB_THREEWAY].needhold = 1;
04270                   }
04271                   pthread_attr_destroy(&attr);
04272                }
04273             } else {
04274                /* Already have a 3 way call */
04275                if (p->subs[SUB_THREEWAY].inthreeway) {
04276                   /* Call is already up, drop the last person */
04277                   if (option_debug)
04278                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04279                   /* If the primary call isn't answered yet, use it */
04280                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04281                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04282                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04283                      p->owner = p->subs[SUB_REAL].owner;
04284                   }
04285                   /* Drop the last call and stop the conference */
04286                   if (option_verbose > 2)
04287                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04288                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04289                   p->subs[SUB_REAL].inthreeway = 0;
04290                   p->subs[SUB_THREEWAY].inthreeway = 0;
04291                } else {
04292                   /* Lets see what we're up to */
04293                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04294                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04295                      int otherindex = SUB_THREEWAY;
04296 
04297                      if (option_verbose > 2)
04298                         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);
04299                      /* Put them in the threeway, and flip */
04300                      p->subs[SUB_THREEWAY].inthreeway = 1;
04301                      p->subs[SUB_REAL].inthreeway = 1;
04302                      if (ast->_state == AST_STATE_UP) {
04303                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04304                         otherindex = SUB_REAL;
04305                      }
04306                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04307                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04308                      p->subs[otherindex].needunhold = 1;
04309                      p->owner = p->subs[SUB_REAL].owner;
04310                      if (ast->_state == AST_STATE_RINGING) {
04311                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04312                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04313                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04314                      }
04315                   } else {
04316                      if (option_verbose > 2)
04317                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04318                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04319                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04320                      p->owner = p->subs[SUB_REAL].owner;
04321                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04322                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04323                      p->subs[SUB_REAL].needunhold = 1;
04324                      zt_enable_ec(p);
04325                   }
04326                      
04327                }
04328             }
04329          winkflashdone:              
04330             update_conf(p);
04331             break;
04332          case SIG_EM:
04333          case SIG_EM_E1:
04334          case SIG_EMWINK:
04335          case SIG_FEATD:
04336          case SIG_SF:
04337          case SIG_SFWINK:
04338          case SIG_SF_FEATD:
04339          case SIG_FXSLS:
04340          case SIG_FXSGS:
04341             if (p->dialing)
04342                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04343             else
04344                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04345             break;
04346          case SIG_FEATDMF_TA:
04347             switch (p->whichwink) {
04348             case 0:
04349                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04350                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04351                break;
04352             case 1:
04353                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04354                break;
04355             case 2:
04356                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04357                return NULL;
04358             }
04359             p->whichwink++;
04360             /* Fall through */
04361          case SIG_FEATDMF:
04362          case SIG_E911:
04363          case SIG_FGC_CAMAMF:
04364          case SIG_FGC_CAMA:
04365          case SIG_FEATB:
04366          case SIG_SF_FEATDMF:
04367          case SIG_SF_FEATB:
04368             /* FGD MF *Must* wait for wink */
04369             if (!ast_strlen_zero(p->dop.dialstr))
04370                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04371             else if (res < 0) {
04372                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04373                p->dop.dialstr[0] = '\0';
04374                return NULL;
04375             } else 
04376                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04377             p->dop.dialstr[0] = '\0';
04378             break;
04379          default:
04380             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04381          }
04382          break;
04383       case ZT_EVENT_HOOKCOMPLETE:
04384          if (p->inalarm) break;
04385          if ((p->radio || (p->oprmode < 0))) break;
04386          switch (mysig) {
04387          case SIG_FXSLS:  /* only interesting for FXS */
04388          case SIG_FXSGS:
04389          case SIG_FXSKS:
04390          case SIG_EM:
04391          case SIG_EM_E1:
04392          case SIG_EMWINK:
04393          case SIG_FEATD:
04394          case SIG_SF:
04395          case SIG_SFWINK:
04396          case SIG_SF_FEATD:
04397             if (!ast_strlen_zero(p->dop.dialstr)) 
04398                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04399             else if (res < 0) {
04400                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04401                p->dop.dialstr[0] = '\0';
04402                return NULL;
04403             } else 
04404                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04405             p->dop.dialstr[0] = '\0';
04406             p->dop.op = ZT_DIAL_OP_REPLACE;
04407             break;
04408          case SIG_FEATDMF:
04409          case SIG_FEATDMF_TA:
04410          case SIG_E911:
04411          case SIG_FGC_CAMA:
04412          case SIG_FGC_CAMAMF:
04413          case SIG_FEATB:
04414          case SIG_SF_FEATDMF:
04415          case SIG_SF_FEATB:
04416             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04417             break;
04418          default:
04419             break;
04420          }
04421          break;
04422       case ZT_EVENT_POLARITY:
04423          /*
04424           * If we get a Polarity Switch event, check to see
04425           * if we should change the polarity state and
04426           * mark the channel as UP or if this is an indication
04427           * of remote end disconnect.
04428           */
04429          if (p->polarity == POLARITY_IDLE) {
04430             p->polarity = POLARITY_REV;
04431             if (p->answeronpolarityswitch &&
04432                 ((ast->_state == AST_STATE_DIALING) ||
04433                 (ast->_state == AST_STATE_RINGING))) {
04434                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04435                ast_setstate(p->owner, AST_STATE_UP);
04436                if (p->hanguponpolarityswitch) {
04437                   gettimeofday(&p->polaritydelaytv, NULL);
04438                }
04439             } else
04440                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04441          } 
04442          /* Removed else statement from here as it was preventing hangups from ever happening*/
04443          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04444          if (p->hanguponpolarityswitch &&
04445             (p->polarityonanswerdelay > 0) &&
04446                 (p->polarity == POLARITY_REV) &&
04447             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04448                                 /* Added log_debug information below to provide a better indication of what is going on */
04449             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) );
04450          
04451             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04452                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04453                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04454                p->polarity = POLARITY_IDLE;
04455             } else {
04456                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);
04457             }
04458          } else {
04459             p->polarity = POLARITY_IDLE;
04460             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04461          }
04462                         /* Added more log_debug information below to provide a better indication of what is going on */
04463          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) );
04464          break;
04465       default:
04466          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04467    }
04468    return &p->subs[index].f;
04469 }
04470 
04471 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04472 {
04473    struct zt_pvt *p = ast->tech_pvt;
04474    int res;
04475    int usedindex=-1;
04476    int index;
04477    struct ast_frame *f;
04478 
04479 
04480    index = zt_get_index(ast, p, 1);
04481    
04482    p->subs[index].f.frametype = AST_FRAME_NULL;
04483    p->subs[index].f.datalen = 0;
04484    p->subs[index].f.samples = 0;
04485    p->subs[index].f.mallocd = 0;
04486    p->subs[index].f.offset = 0;
04487    p->subs[index].f.subclass = 0;
04488    p->subs[index].f.delivery = ast_tv(0,0);
04489    p->subs[index].f.src = "zt_exception";
04490    p->subs[index].f.data = NULL;
04491    
04492    
04493    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04494       /* If nobody owns us, absorb the event appropriately, otherwise
04495          we loop indefinitely.  This occurs when, during call waiting, the
04496          other end hangs up our channel so that it no longer exists, but we
04497          have neither FLASH'd nor ONHOOK'd to signify our desire to
04498          change to the other channel. */
04499       if (p->fake_event) {
04500          res = p->fake_event;
04501          p->fake_event = 0;
04502       } else
04503          res = zt_get_event(p->subs[SUB_REAL].zfd);
04504       /* Switch to real if there is one and this isn't something really silly... */
04505       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04506          (res != ZT_EVENT_HOOKCOMPLETE)) {
04507          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04508          p->owner = p->subs[SUB_REAL].owner;
04509          if (p->owner && ast_bridged_channel(p->owner))
04510             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04511          p->subs[SUB_REAL].needunhold = 1;
04512       }
04513       switch (res) {
04514       case ZT_EVENT_ONHOOK:
04515          zt_disable_ec(p);
04516          if (p->owner) {
04517             if (option_verbose > 2) 
04518                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04519             zt_ring_phone(p);
04520             p->callwaitingrepeat = 0;
04521             p->cidcwexpire = 0;
04522          } else
04523             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04524          update_conf(p);
04525          break;
04526       case ZT_EVENT_RINGOFFHOOK:
04527          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04528          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04529             p->subs[SUB_REAL].needanswer = 1;
04530             p->dialing = 0;
04531          }
04532          break;
04533       case ZT_EVENT_HOOKCOMPLETE:
04534       case ZT_EVENT_RINGERON:
04535       case ZT_EVENT_RINGEROFF:
04536          /* Do nothing */
04537          break;
04538       case ZT_EVENT_WINKFLASH:
04539          gettimeofday(&p->flashtime, NULL);
04540          if (p->owner) {
04541             if (option_verbose > 2) 
04542                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04543             if (p->owner->_state != AST_STATE_UP) {
04544                /* Answer if necessary */
04545                usedindex = zt_get_index(p->owner, p, 0);
04546                if (usedindex > -1) {
04547                   p->subs[usedindex].needanswer = 1;
04548                }
04549                ast_setstate(p->owner, AST_STATE_UP);
04550             }
04551             p->callwaitingrepeat = 0;
04552             p->cidcwexpire = 0;
04553             if (ast_bridged_channel(p->owner))
04554                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04555             p->subs[SUB_REAL].needunhold = 1;
04556          } else
04557             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04558          update_conf(p);
04559          break;
04560       default:
04561          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04562       }
04563       f = &p->subs[index].f;
04564       return f;
04565    }
04566    if (!(p->radio || (p->oprmode < 0))) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04567    /* If it's not us, return NULL immediately */
04568    if (ast != p->owner) {
04569       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04570       f = &p->subs[index].f;
04571       return f;
04572    }
04573    f = zt_handle_event(ast);
04574    return f;
04575 }
04576 
04577 static struct ast_frame *zt_exception(struct ast_channel *ast)
04578 {
04579    struct zt_pvt *p = ast->tech_pvt;
04580    struct ast_frame *f;
04581    ast_mutex_lock(&p->lock);
04582    f = __zt_exception(ast);
04583    ast_mutex_unlock(&p->lock);
04584    return f;
04585 }
04586 
04587 static struct ast_frame  *zt_read(struct ast_channel *ast)
04588 {
04589    struct zt_pvt *p = ast->tech_pvt;
04590    int res;
04591    int index;
04592    void *readbuf;
04593    struct ast_frame *f;
04594    
04595 
04596    ast_mutex_lock(&p->lock);
04597    
04598    index = zt_get_index(ast, p, 0);
04599    
04600    /* Hang up if we don't really exist */
04601    if (index < 0) {
04602       ast_log(LOG_WARNING, "We dont exist?\n");
04603       ast_mutex_unlock(&p->lock);
04604       return NULL;
04605    }
04606    
04607    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04608 
04609    p->subs[index].f.frametype = AST_FRAME_NULL;
04610    p->subs[index].f.datalen = 0;
04611    p->subs[index].f.samples = 0;
04612    p->subs[index].f.mallocd = 0;
04613    p->subs[index].f.offset = 0;
04614    p->subs[index].f.subclass = 0;
04615    p->subs[index].f.delivery = ast_tv(0,0);
04616    p->subs[index].f.src = "zt_read";
04617    p->subs[index].f.data = NULL;
04618    
04619    /* make sure it sends initial key state as first frame */
04620    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04621    {
04622       ZT_PARAMS ps;
04623 
04624       ps.channo = p->channel;
04625       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04626          ast_mutex_unlock(&p->lock);
04627          return NULL;
04628       }
04629       p->firstradio = 1;
04630       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04631       if (ps.rxisoffhook)
04632       {
04633          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04634       }
04635       else
04636       {
04637          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04638       }
04639       ast_mutex_unlock(&p->lock);
04640       return &p->subs[index].f;
04641    }
04642    if (p->ringt == 1) {
04643       ast_mutex_unlock(&p->lock);
04644       return NULL;
04645    }
04646    else if (p->ringt > 0) 
04647       p->ringt--;
04648 
04649    if (p->subs[index].needringing) {
04650       /* Send ringing frame if requested */
04651       p->subs[index].needringing = 0;
04652       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04653       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04654       ast_setstate(ast, AST_STATE_RINGING);
04655       ast_mutex_unlock(&p->lock);
04656       return &p->subs[index].f;
04657    }
04658 
04659    if (p->subs[index].needbusy) {
04660       /* Send busy frame if requested */
04661       p->subs[index].needbusy = 0;
04662       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04663       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04664       ast_mutex_unlock(&p->lock);
04665       return &p->subs[index].f;
04666    }
04667 
04668    if (p->subs[index].needcongestion) {
04669       /* Send congestion frame if requested */
04670       p->subs[index].needcongestion = 0;
04671       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04672       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04673       ast_mutex_unlock(&p->lock);
04674       return &p->subs[index].f;
04675    }
04676 
04677    if (p->subs[index].needcallerid) {
04678       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04679                      S_OR(p->lastcid_name, NULL),
04680                      S_OR(p->lastcid_num, NULL)
04681                      );
04682       p->subs[index].needcallerid = 0;
04683    }
04684    
04685    if (p->subs[index].needanswer) {
04686       /* Send answer frame if requested */
04687       p->subs[index].needanswer = 0;
04688       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04689       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04690       ast_mutex_unlock(&p->lock);
04691       return &p->subs[index].f;
04692    }  
04693    
04694    if (p->subs[index].needflash) {
04695       /* Send answer frame if requested */
04696       p->subs[index].needflash = 0;
04697       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04698       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04699       ast_mutex_unlock(&p->lock);
04700       return &p->subs[index].f;
04701    }  
04702    
04703    if (p->subs[index].needhold) {
04704       /* Send answer frame if requested */
04705       p->subs[index].needhold = 0;
04706       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04707       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04708       ast_mutex_unlock(&p->lock);
04709       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04710       return &p->subs[index].f;
04711    }  
04712    
04713    if (p->subs[index].needunhold) {
04714       /* Send answer frame if requested */
04715       p->subs[index].needunhold = 0;
04716       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04717       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04718       ast_mutex_unlock(&p->lock);
04719       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04720       return &p->subs[index].f;
04721    }  
04722    
04723    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04724       if (!p->subs[index].linear) {
04725          p->subs[index].linear = 1;
04726          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04727          if (res) 
04728             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04729       }
04730    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04731          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04732       if (p->subs[index].linear) {
04733          p->subs[index].linear = 0;
04734          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04735          if (res) 
04736             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04737       }
04738    } else {
04739       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04740       ast_mutex_unlock(&p->lock);
04741       return NULL;
04742    }
04743    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04744    CHECK_BLOCKING(ast);
04745    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04746    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04747    /* Check for hangup */
04748    if (res < 0) {
04749       f = NULL;
04750       if (res == -1)  {
04751          if (errno == EAGAIN) {
04752             /* Return "NULL" frame if there is nobody there */
04753             ast_mutex_unlock(&p->lock);
04754             return &p->subs[index].f;
04755          } else if (errno == ELAST) {
04756             f = __zt_exception(ast);
04757          } else
04758             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04759       }
04760       ast_mutex_unlock(&p->lock);
04761       return f;
04762    }
04763    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04764       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04765       f = __zt_exception(ast);
04766       ast_mutex_unlock(&p->lock);
04767       return f;
04768    }
04769    if (p->tdd) { /* if in TDD mode, see if we receive that */
04770       int c;
04771 
04772       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04773       if (c < 0) {
04774          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04775          ast_mutex_unlock(&p->lock);
04776          return NULL;
04777       }
04778       if (c) { /* if a char to return */
04779          p->subs[index].f.subclass = 0;
04780          p->subs[index].f.frametype = AST_FRAME_TEXT;
04781          p->subs[index].f.mallocd = 0;
04782          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04783          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04784          p->subs[index].f.datalen = 1;
04785          *((char *) p->subs[index].f.data) = c;
04786          ast_mutex_unlock(&p->lock);
04787          return &p->subs[index].f;
04788       }
04789    }
04790    if (p->callwaitingrepeat)
04791       p->callwaitingrepeat--;
04792    if (p->cidcwexpire)
04793       p->cidcwexpire--;
04794    /* Repeat callwaiting */
04795    if (p->callwaitingrepeat == 1) {
04796       p->callwaitrings++;
04797       zt_callwait(ast);
04798    }
04799    /* Expire CID/CW */
04800    if (p->cidcwexpire == 1) {
04801       if (option_verbose > 2)
04802          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04803       restore_conference(p);
04804    }
04805    if (p->subs[index].linear) {
04806       p->subs[index].f.datalen = READ_SIZE * 2;
04807    } else 
04808       p->subs[index].f.datalen = READ_SIZE;
04809 
04810    /* Handle CallerID Transmission */
04811    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04812       send_callerid(p);
04813    }
04814 
04815    p->subs[index].f.frametype = AST_FRAME_VOICE;
04816    p->subs[index].f.subclass = ast->rawreadformat;
04817    p->subs[index].f.samples = READ_SIZE;
04818    p->subs[index].f.mallocd = 0;
04819    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04820    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
04821 #if 0
04822    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04823 #endif   
04824    if (p->dialing || /* Transmitting something */
04825       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04826       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04827       ) {
04828       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04829          don't send anything */
04830       p->subs[index].f.frametype = AST_FRAME_NULL;
04831       p->subs[index].f.subclass = 0;
04832       p->subs[index].f.samples = 0;
04833       p->subs[index].f.mallocd = 0;
04834       p->subs[index].f.offset = 0;
04835       p->subs[index].f.data = NULL;
04836       p->subs[index].f.datalen= 0;
04837    }
04838    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04839       /* Perform busy detection. etc on the zap line */
04840       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04841       if (f) {
04842          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04843             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04844                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04845                   a busy  */
04846                f = NULL;
04847             }
04848          } else if (f->frametype == AST_FRAME_DTMF) {
04849 #ifdef HAVE_PRI
04850             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04851                /* Don't accept in-band DTMF when in overlap dial mode */
04852                f->frametype = AST_FRAME_NULL;
04853                f->subclass = 0;
04854             }
04855 #endif            
04856             /* DSP clears us of being pulse */
04857             p->pulsedial = 0;
04858          }
04859       }
04860    } else 
04861       f = &p->subs[index].f; 
04862 
04863    if (f && (f->frametype == AST_FRAME_DTMF))
04864       zt_handle_dtmfup(ast, index, &f);
04865 
04866    /* If we have a fake_event, trigger exception to handle it */
04867    if (p->fake_event)
04868       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04869 
04870    ast_mutex_unlock(&p->lock);
04871    return f;
04872 }
04873 
04874 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
04875 {
04876    int sent=0;
04877    int size;
04878    int res;
04879    int fd;
04880    fd = p->subs[index].zfd;
04881    while (len) {
04882       size = len;
04883       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04884          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04885       res = write(fd, buf, size);
04886       if (res != size) {
04887          if (option_debug)
04888             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04889          return sent;
04890       }
04891       len -= size;
04892       buf += size;
04893    }
04894    return sent;
04895 }
04896 
04897 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
04898 {
04899    struct zt_pvt *p = ast->tech_pvt;
04900    int res;
04901    unsigned char outbuf[4096];
04902    int index;
04903    index = zt_get_index(ast, p, 0);
04904    if (index < 0) {
04905       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04906       return -1;
04907    }
04908 
04909 #if 0
04910 #ifdef HAVE_PRI
04911    ast_mutex_lock(&p->lock);
04912    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04913       if (p->pri->pri) {      
04914          if (!pri_grab(p, p->pri)) {
04915                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04916                pri_rel(p->pri);
04917          } else
04918                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04919       }
04920       p->proceeding=1;
04921    }
04922    ast_mutex_unlock(&p->lock);
04923 #endif
04924 #endif
04925    /* Write a frame of (presumably voice) data */
04926    if (frame->frametype != AST_FRAME_VOICE) {
04927       if (frame->frametype != AST_FRAME_IMAGE)
04928          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04929       return 0;
04930    }
04931    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04932        (frame->subclass != AST_FORMAT_ULAW) &&
04933        (frame->subclass != AST_FORMAT_ALAW)) {
04934       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04935       return -1;
04936    }
04937    if (p->dialing) {
04938       if (option_debug)
04939          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
04940       return 0;
04941    }
04942    if (!p->owner) {
04943       if (option_debug)
04944          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
04945       return 0;
04946    }
04947    if (p->cidspill) {
04948       if (option_debug)
04949          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
04950       return 0;
04951    }
04952    /* Return if it's not valid data */
04953    if (!frame->data || !frame->datalen)
04954       return 0;
04955    if (frame->datalen > sizeof(outbuf) * 2) {
04956       ast_log(LOG_WARNING, "Frame too large\n");
04957       return 0;
04958    }
04959 
04960    if (frame->subclass == AST_FORMAT_SLINEAR) {
04961       if (!p->subs[index].linear) {
04962          p->subs[index].linear = 1;
04963          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04964          if (res)
04965             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
04966       }
04967       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
04968    } else {
04969       /* x-law already */
04970       if (p->subs[index].linear) {
04971          p->subs[index].linear = 0;
04972          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04973          if (res)
04974             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
04975       }
04976       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
04977    }
04978    if (res < 0) {
04979       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
04980       return -1;
04981    } 
04982    return 0;
04983 }
04984 
04985 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
04986 {
04987    struct zt_pvt *p = chan->tech_pvt;
04988    int res=-1;
04989    int index;
04990    int func = ZT_FLASH;
04991    ast_mutex_lock(&p->lock);
04992    index = zt_get_index(chan, p, 0);
04993    ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
04994    if (index == SUB_REAL) {
04995       switch (condition) {
04996       case AST_CONTROL_BUSY:
04997 #ifdef HAVE_PRI
04998          if (p->priindication_oob && p->sig == SIG_PRI) {
04999             chan->hangupcause = AST_CAUSE_USER_BUSY;
05000             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05001             res = 0;
05002          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05003             if (p->pri->pri) {      
05004                if (!pri_grab(p, p->pri)) {
05005                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05006                   pri_rel(p->pri);
05007                }
05008                else
05009                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05010             }
05011             p->progress = 1;
05012             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05013          } else
05014 #endif
05015             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05016          break;
05017       case AST_CONTROL_RINGING:
05018 #ifdef HAVE_PRI
05019          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05020             if (p->pri->pri) {      
05021                if (!pri_grab(p, p->pri)) {
05022                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
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->alerting = 1;
05029          }
05030 #endif
05031          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05032          if (chan->_state != AST_STATE_UP) {
05033             if ((chan->_state != AST_STATE_RING) ||
05034                ((p->sig != SIG_FXSKS) &&
05035                 (p->sig != SIG_FXSLS) &&
05036                 (p->sig != SIG_FXSGS)))
05037                ast_setstate(chan, AST_STATE_RINGING);
05038          }
05039          break;
05040       case AST_CONTROL_PROCEEDING:
05041          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05042 #ifdef HAVE_PRI
05043          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05044             if (p->pri->pri) {      
05045                if (!pri_grab(p, p->pri)) {
05046                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05047                   pri_rel(p->pri);
05048                }
05049                else
05050                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05051             }
05052             p->proceeding = 1;
05053          }
05054 #endif
05055          /* don't continue in ast_indicate */
05056          res = 0;
05057          break;
05058       case AST_CONTROL_PROGRESS:
05059          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05060 #ifdef HAVE_PRI
05061          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05062          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05063             if (p->pri->pri) {      
05064                if (!pri_grab(p, p->pri)) {
05065                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05066                   pri_rel(p->pri);
05067                }
05068                else
05069                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05070             }
05071             p->progress = 1;
05072          }
05073 #endif
05074          /* don't continue in ast_indicate */
05075          res = 0;
05076          break;
05077       case AST_CONTROL_CONGESTION:
05078          chan->hangupcause = AST_CAUSE_CONGESTION;
05079 #ifdef HAVE_PRI
05080          if (p->priindication_oob && p->sig == SIG_PRI) {
05081             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05082             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05083             res = 0;
05084          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05085             if (p->pri) {     
05086                if (!pri_grab(p, p->pri)) {
05087                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05088                   pri_rel(p->pri);
05089                } else
05090                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05091             }
05092             p->progress = 1;
05093             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05094          } else
05095 #endif
05096             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05097          break;
05098       case AST_CONTROL_HOLD:
05099 #ifdef HAVE_PRI
05100          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05101             if (!pri_grab(p, p->pri)) {
05102                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05103                pri_rel(p->pri);
05104             } else
05105                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05106          } else
05107 #endif
05108             ast_moh_start(chan, data, p->mohinterpret);
05109          break;
05110       case AST_CONTROL_UNHOLD:
05111 #ifdef HAVE_PRI
05112          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05113             if (!pri_grab(p, p->pri)) {
05114                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05115                pri_rel(p->pri);
05116             } else
05117                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05118          } else
05119 #endif
05120             ast_moh_stop(chan);
05121          break;
05122       case AST_CONTROL_RADIO_KEY:
05123          if (p->radio) 
05124              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05125          res = 0;
05126          break;
05127       case AST_CONTROL_RADIO_UNKEY:
05128          if (p->radio)
05129              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05130          res = 0;
05131          break;
05132       case AST_CONTROL_FLASH:
05133          /* flash hookswitch */
05134          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05135             /* Clear out the dial buffer */
05136             p->dop.dialstr[0] = '\0';
05137             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05138                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05139                   chan->name, strerror(errno));
05140             } else
05141                res = 0;
05142          } else
05143             res = 0;
05144          break;
05145       case -1:
05146          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05147          break;
05148       }
05149    } else
05150       res = 0;
05151    ast_mutex_unlock(&p->lock);
05152    return res;
05153 }
05154 
05155 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05156 {
05157    struct ast_channel *tmp;
05158    int deflaw;
05159    int res;
05160    int x,y;
05161    int features;
05162    char *b2 = 0;
05163    ZT_PARAMS ps;
05164    if (i->subs[index].owner) {
05165       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05166       return NULL;
05167    }
05168    y = 1;
05169    do {
05170       if (b2)
05171          free(b2);
05172 #ifdef HAVE_PRI
05173       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05174          asprintf(&b2, "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05175       else
05176 #endif
05177       if (i->channel == CHAN_PSEUDO)
05178          asprintf(&b2, "Zap/pseudo-%ld", ast_random());
05179       else  
05180          asprintf(&b2, "Zap/%d-%d", i->channel, y);
05181       for (x = 0; x < 3; x++) {
05182          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05183             break;
05184       }
05185       y++;
05186    } while (x < 3);
05187    tmp = ast_channel_alloc(0, state, 0, 0, i->accountcode, i->exten, i->context, i->amaflags, b2);
05188    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05189       free(b2);
05190    if (!tmp)
05191       return NULL;
05192    tmp->tech = &zap_tech;
05193    ps.channo = i->channel;
05194    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05195    if (res) {
05196       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05197       ps.curlaw = ZT_LAW_MULAW;
05198    }
05199    if (ps.curlaw == ZT_LAW_ALAW)
05200       deflaw = AST_FORMAT_ALAW;
05201    else
05202       deflaw = AST_FORMAT_ULAW;
05203    if (law) {
05204       if (law == ZT_LAW_ALAW)
05205          deflaw = AST_FORMAT_ALAW;
05206       else
05207          deflaw = AST_FORMAT_ULAW;
05208    }
05209    tmp->fds[0] = i->subs[index].zfd;
05210    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05211    /* Start out assuming ulaw since it's smaller :) */
05212    tmp->rawreadformat = deflaw;
05213    tmp->readformat = deflaw;
05214    tmp->rawwriteformat = deflaw;
05215    tmp->writeformat = deflaw;
05216    i->subs[index].linear = 0;
05217    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05218    features = 0;
05219    if (i->busydetect && CANBUSYDETECT(i))
05220       features |= DSP_FEATURE_BUSY_DETECT;
05221    if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05222       features |= DSP_FEATURE_CALL_PROGRESS;
05223    if ((!i->outgoing && (i->callprogress & 4)) || 
05224        (i->outgoing && (i->callprogress & 2))) {
05225       features |= DSP_FEATURE_FAX_DETECT;
05226    }
05227 #ifdef ZT_TONEDETECT
05228    x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05229    if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05230 #endif      
05231       i->hardwaredtmf = 0;
05232       features |= DSP_FEATURE_DTMF_DETECT;
05233 #ifdef ZT_TONEDETECT
05234    } else if (NEED_MFDETECT(i)) {
05235       i->hardwaredtmf = 1;
05236       features |= DSP_FEATURE_DTMF_DETECT;
05237    }
05238 #endif
05239    if (features) {
05240       if (i->dsp) {
05241          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05242       } else {
05243          if (i->channel != CHAN_PSEUDO)
05244             i->dsp = ast_dsp_new();
05245          else
05246             i->dsp = NULL;
05247          if (i->dsp) {
05248             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05249 #ifdef HAVE_PRI
05250             /* We cannot do progress detection until receives PROGRESS message */
05251             if (i->outgoing && (i->sig == SIG_PRI)) {
05252                /* Remember requested DSP features, don't treat
05253                   talking as ANSWER */
05254                features = 0;
05255             }
05256 #endif
05257             ast_dsp_set_features(i->dsp, features);
05258             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05259             if (!ast_strlen_zero(progzone))
05260                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05261             if (i->busydetect && CANBUSYDETECT(i)) {
05262                ast_dsp_set_busy_count(i->dsp, i->busycount);
05263                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05264             }
05265          }
05266       }
05267    }
05268       
05269    if (state == AST_STATE_RING)
05270       tmp->rings = 1;
05271    tmp->tech_pvt = i;
05272    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05273       /* Only FXO signalled stuff can be picked up */
05274       tmp->callgroup = i->callgroup;
05275       tmp->pickupgroup = i->pickupgroup;
05276    }
05277    if (!ast_strlen_zero(i->language))
05278       ast_string_field_set(tmp, language, i->language);
05279    if (!i->owner)
05280       i->owner = tmp;
05281    if (!ast_strlen_zero(i->accountcode))
05282       ast_string_field_set(tmp, accountcode, i->accountcode);
05283    if (i->amaflags)
05284       tmp->amaflags = i->amaflags;
05285    i->subs[index].owner = tmp;
05286    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05287    ast_string_field_set(tmp, call_forward, i->call_forward);
05288    /* If we've been told "no ADSI" then enforce it */
05289    if (!i->adsi)
05290       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05291    if (!ast_strlen_zero(i->exten))
05292       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05293    if (!ast_strlen_zero(i->rdnis))
05294       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05295    if (!ast_strlen_zero(i->dnid))
05296       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05297 
05298    /* Don't use ast_set_callerid() here because it will
05299     * generate a needless NewCallerID event */
05300 #ifdef PRI_ANI
05301    tmp->cid.cid_num = ast_strdup(i->cid_num);
05302    tmp->cid.cid_name = ast_strdup(i->cid_name);
05303    if (!ast_strlen_zero(i->cid_ani))
05304       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05305    else  
05306       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05307 #else
05308    tmp->cid.cid_num = ast_strdup(i->cid_num);
05309    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05310    tmp->cid.cid_name = ast_strdup(i->cid_name);
05311 #endif
05312    tmp->cid.cid_pres = i->callingpres;
05313    tmp->cid.cid_ton = i->cid_ton;
05314 #ifdef HAVE_PRI
05315    tmp->transfercapability = transfercapability;
05316    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05317    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05318       i->digital = 1;
05319    /* Assume calls are not idle calls unless we're told differently */
05320    i->isidlecall = 0;
05321    i->alreadyhungup = 0;
05322 #endif
05323    /* clear the fake event in case we posted one before we had ast_channel */
05324    i->fake_event = 0;
05325    /* Assure there is no confmute on this channel */
05326    zt_confmute(i, 0);
05327    /* Configure the new channel jb */
05328    ast_jb_configure(tmp, &global_jbconf);
05329    if (startpbx) {
05330       if (ast_pbx_start(tmp)) {
05331          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05332          ast_hangup(tmp);
05333          i->owner = NULL;
05334          return NULL;
05335       }
05336    }
05337 
05338    ast_module_ref(ast_module_info->self);
05339    
05340    return tmp;
05341 }
05342 
05343 
05344 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05345 {
05346    char c;
05347 
05348    *str = 0; /* start with empty output buffer */
05349    for (;;)
05350    {
05351       /* Wait for the first digit (up to specified ms). */
05352       c = ast_waitfordigit(chan, ms);
05353       /* if timeout, hangup or error, return as such */
05354       if (c < 1)
05355          return c;
05356       *str++ = c;
05357       *str = 0;
05358       if (strchr(term, c))
05359          return 1;
05360    }
05361 }
05362 
05363 static int zt_wink(struct zt_pvt *p, int index)
05364 {
05365    int j;
05366    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05367    for (;;)
05368    {
05369          /* set bits of interest */
05370       j = ZT_IOMUX_SIGEVENT;
05371           /* wait for some happening */
05372       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05373          /* exit loop if we have it */
05374       if (j & ZT_IOMUX_SIGEVENT) break;
05375    }
05376      /* get the event info */
05377    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05378    return 0;
05379 }
05380 
05381 static void *ss_thread(void *data)
05382 {
05383    struct ast_channel *chan = data;
05384    struct zt_pvt *p = chan->tech_pvt;
05385    char exten[AST_MAX_EXTENSION] = "";
05386    char exten2[AST_MAX_EXTENSION] = "";
05387    unsigned char buf[256];
05388    char dtmfcid[300];
05389    char dtmfbuf[300];
05390    struct callerid_state *cs = NULL;
05391    char *name = NULL, *number = NULL;
05392    int distMatches;
05393    int curRingData[3];
05394    int receivedRingT;
05395    int counter1;
05396    int counter;
05397    int samples = 0;
05398    struct ast_smdi_md_message *smdi_msg = NULL;
05399    int flags;
05400    int i;
05401    int timeout;
05402    int getforward = 0;
05403    char *s1, *s2;
05404    int len = 0;
05405    int res;
05406    int index;
05407 
05408    /* in the bizarre case where the channel has become a zombie before we
05409       even get started here, abort safely
05410    */
05411    if (!p) {
05412       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05413       ast_hangup(chan);
05414       return NULL;
05415    }
05416 
05417    if (option_verbose > 2) 
05418       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05419    index = zt_get_index(chan, p, 1);
05420    if (index < 0) {
05421       ast_log(LOG_WARNING, "Huh?\n");
05422       ast_hangup(chan);
05423       return NULL;
05424    }
05425    if (p->dsp)
05426       ast_dsp_digitreset(p->dsp);
05427    switch (p->sig) {
05428 #ifdef HAVE_PRI
05429    case SIG_PRI:
05430       /* Now loop looking for an extension */
05431       ast_copy_string(exten, p->exten, sizeof(exten));
05432       len = strlen(exten);
05433       res = 0;
05434       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05435          if (len && !ast_ignore_pattern(chan->context, exten))
05436             tone_zone_play_tone(p->subs[index].zfd, -1);
05437          else
05438             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05439          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05440             timeout = matchdigittimeout;
05441          else
05442             timeout = gendigittimeout;
05443          res = ast_waitfordigit(chan, timeout);
05444          if (res < 0) {
05445             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05446             ast_hangup(chan);
05447             return NULL;
05448          } else if (res) {
05449             exten[len++] = res;
05450             exten[len] = '\0';
05451          } else
05452             break;
05453       }
05454       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05455       if (ast_strlen_zero(exten)) {
05456          if (option_verbose > 2)
05457             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05458          exten[0] = 's';
05459          exten[1] = '\0';
05460       }
05461       tone_zone_play_tone(p->subs[index].zfd, -1);
05462       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05463          /* Start the real PBX */
05464          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05465          if (p->dsp) ast_dsp_digitreset(p->dsp);
05466          zt_enable_ec(p);
05467          ast_setstate(chan, AST_STATE_RING);
05468          res = ast_pbx_run(chan);
05469          if (res) {
05470             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05471          }
05472       } else {
05473          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05474          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05475          ast_hangup(chan);
05476          p->exten[0] = '\0';
05477          /* Since we send release complete here, we won't get one */
05478          p->call = NULL;
05479       }
05480       return NULL;
05481       break;
05482 #endif
05483    case SIG_FEATD:
05484    case SIG_FEATDMF:
05485    case SIG_FEATDMF_TA:
05486    case SIG_E911:
05487    case SIG_FGC_CAMAMF:
05488    case SIG_FEATB:
05489    case SIG_EMWINK:
05490    case SIG_SF_FEATD:
05491    case SIG_SF_FEATDMF:
05492    case SIG_SF_FEATB:
05493    case SIG_SFWINK:
05494       if (zt_wink(p, index))  
05495          return NULL;
05496       /* Fall through */
05497    case SIG_EM:
05498    case SIG_EM_E1:
05499    case SIG_SF:
05500    case SIG_FGC_CAMA:
05501       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05502       if (p->dsp)
05503          ast_dsp_digitreset(p->dsp);
05504       /* set digit mode appropriately */
05505       if (p->dsp) {
05506          if (NEED_MFDETECT(p))
05507             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05508          else 
05509             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05510       }
05511       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05512       /* Wait for the first digit only if immediate=no */
05513       if (!p->immediate)
05514          /* Wait for the first digit (up to 5 seconds). */
05515          res = ast_waitfordigit(chan, 5000);
05516       else
05517          res = 0;
05518       if (res > 0) {
05519          /* save first char */
05520          dtmfbuf[0] = res;
05521          switch (p->sig) {
05522          case SIG_FEATD:
05523          case SIG_SF_FEATD:
05524             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05525             if (res > 0)
05526                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05527             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05528             break;
05529          case SIG_FEATDMF_TA:
05530             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05531             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05532             if (zt_wink(p, index)) return NULL;
05533             dtmfbuf[0] = 0;
05534             /* Wait for the first digit (up to 5 seconds). */
05535             res = ast_waitfordigit(chan, 5000);
05536             if (res <= 0) break;
05537             dtmfbuf[0] = res;
05538             /* fall through intentionally */
05539          case SIG_FEATDMF:
05540          case SIG_E911:
05541          case SIG_FGC_CAMAMF:
05542          case SIG_SF_FEATDMF:
05543             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05544             /* if international caca, do it again to get real ANO */
05545             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05546             {
05547                if (zt_wink(p, index)) return NULL;
05548                dtmfbuf[0] = 0;
05549                /* Wait for the first digit (up to 5 seconds). */
05550                res = ast_waitfordigit(chan, 5000);
05551                if (res <= 0) break;
05552                dtmfbuf[0] = res;
05553                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05554             }
05555             if (res > 0) {
05556                /* if E911, take off hook */
05557                if (p->sig == SIG_E911)
05558                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05559                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05560             }
05561             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05562             break;
05563          case SIG_FEATB:
05564          case SIG_SF_FEATB:
05565             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05566             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05567             break;
05568          case SIG_EMWINK:
05569             /* if we received a '*', we are actually receiving Feature Group D
05570                dial syntax, so use that mode; otherwise, fall through to normal
05571                mode
05572             */
05573             if (res == '*') {
05574                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05575                if (res > 0)
05576                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05577                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05578                break;
05579             }
05580          default:
05581             /* If we got the first digit, get the rest */
05582             len = 1;
05583             dtmfbuf[len] = '\0';
05584             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05585                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05586                   timeout = matchdigittimeout;
05587                } else {
05588                   timeout = gendigittimeout;
05589                }
05590                res = ast_waitfordigit(chan, timeout);
05591                if (res < 0) {
05592                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05593                   ast_hangup(chan);
05594                   return NULL;
05595                } else if (res) {
05596                   dtmfbuf[len++] = res;
05597                   dtmfbuf[len] = '\0';
05598                } else {
05599                   break;
05600                }
05601             }
05602             break;
05603          }
05604       }
05605       if (res == -1) {
05606          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05607          ast_hangup(chan);
05608          return NULL;
05609       } else if (res < 0) {
05610          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05611          ast_hangup(chan);
05612          return NULL;
05613       }
05614 
05615       if (p->sig == SIG_FGC_CAMA) {
05616          char anibuf[100];
05617 
05618          if (ast_safe_sleep(chan,1000) == -1) {
05619                            ast_hangup(chan);
05620                            return NULL;
05621          }
05622                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05623                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05624                         res = my_getsigstr(chan, anibuf, "#", 10000);
05625                         if ((res > 0) && (strlen(anibuf) > 2)) {
05626             if (anibuf[strlen(anibuf) - 1] == '#')
05627                anibuf[strlen(anibuf) - 1] = 0;
05628             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05629          }
05630                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05631       }
05632 
05633       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05634       if (ast_strlen_zero(exten))
05635          ast_copy_string(exten, "s", sizeof(exten));
05636       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05637          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05638          if (exten[0] == '*') {
05639             char *stringp=NULL;
05640             ast_copy_string(exten2, exten, sizeof(exten2));
05641             /* Parse out extension and callerid */
05642             stringp=exten2 +1;
05643             s1 = strsep(&stringp, "*");
05644             s2 = strsep(&stringp, "*");
05645             if (s2) {
05646                if (!ast_strlen_zero(p->cid_num))
05647                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05648                else
05649                   ast_set_callerid(chan, s1, NULL, s1);
05650                ast_copy_string(exten, s2, sizeof(exten));
05651             } else
05652                ast_copy_string(exten, s1, sizeof(exten));
05653          } else if (p->sig == SIG_FEATD)
05654             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05655       }
05656       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
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                   if (*(s1 + 2))
05669                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05670                ast_copy_string(exten, s2 + 1, sizeof(exten));
05671             } else
05672                ast_copy_string(exten, s1 + 2, sizeof(exten));
05673          } else
05674             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05675       }
05676       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05677          if (exten[0] == '*') {
05678             char *stringp=NULL;
05679             ast_copy_string(exten2, exten, sizeof(exten2));
05680             /* Parse out extension and callerid */
05681             stringp=exten2 +1;
05682             s1 = strsep(&stringp, "#");
05683             s2 = strsep(&stringp, "#");
05684             if (s2 && (*(s2 + 1) == '0')) {
05685                if (*(s2 + 2))
05686                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05687             }
05688             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05689             else ast_copy_string(exten, "911", sizeof(exten));
05690          } else
05691             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05692       }
05693       if (p->sig == SIG_FEATB) {
05694          if (exten[0] == '*') {
05695             char *stringp=NULL;
05696             ast_copy_string(exten2, exten, sizeof(exten2));
05697             /* Parse out extension and callerid */
05698             stringp=exten2 +1;
05699             s1 = strsep(&stringp, "#");
05700             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05701          } else
05702             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05703       }
05704       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05705          zt_wink(p, index);
05706                         /* some switches require a minimum guard time between
05707                            the last FGD wink and something that answers
05708                            immediately. This ensures it */
05709                         if (ast_safe_sleep(chan,100)) return NULL;
05710       }
05711       zt_enable_ec(p);
05712       if (NEED_MFDETECT(p)) {
05713          if (p->dsp) {
05714             if (!p->hardwaredtmf)
05715                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05716             else {
05717                ast_dsp_free(p->dsp);
05718                p->dsp = NULL;
05719             }
05720          }
05721       }
05722 
05723       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05724          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05725          if (p->dsp) ast_dsp_digitreset(p->dsp);
05726          res = ast_pbx_run(chan);
05727          if (res) {
05728             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05729             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05730          }
05731          return NULL;
05732       } else {
05733          if (option_verbose > 2)
05734             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05735          sleep(2);
05736          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05737          if (res < 0)
05738             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05739          else
05740             sleep(1);
05741          res = ast_streamfile(chan, "ss-noservice", chan->language);
05742          if (res >= 0)
05743             ast_waitstream(chan, "");
05744          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05745          ast_hangup(chan);
05746          return NULL;
05747       }
05748       break;
05749    case SIG_FXOLS:
05750    case SIG_FXOGS:
05751    case SIG_FXOKS:
05752       /* Read the first digit */
05753       timeout = firstdigittimeout;
05754       /* If starting a threeway call, never timeout on the first digit so someone
05755          can use flash-hook as a "hold" feature */
05756       if (p->subs[SUB_THREEWAY].owner) 
05757          timeout = 999999;
05758       while (len < AST_MAX_EXTENSION-1) {
05759          /* Read digit unless it's supposed to be immediate, in which case the
05760             only answer is 's' */
05761          if (p->immediate) 
05762             res = 's';
05763          else
05764             res = ast_waitfordigit(chan, timeout);
05765          timeout = 0;
05766          if (res < 0) {
05767             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05768             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05769             ast_hangup(chan);
05770             return NULL;
05771          } else if (res)  {
05772             exten[len++]=res;
05773             exten[len] = '\0';
05774          }
05775          if (!ast_ignore_pattern(chan->context, exten))
05776             tone_zone_play_tone(p->subs[index].zfd, -1);
05777          else
05778             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05779          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05780             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05781                if (getforward) {
05782                   /* Record this as the forwarding extension */
05783                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05784                   if (option_verbose > 2)
05785                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05786                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05787                   if (res)
05788                      break;
05789                   usleep(500000);
05790                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05791                   sleep(1);
05792                   memset(exten, 0, sizeof(exten));
05793                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05794                   len = 0;
05795                   getforward = 0;
05796                } else  {
05797                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05798                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05799                   if (!ast_strlen_zero(p->cid_num)) {
05800                      if (!p->hidecallerid)
05801                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05802                      else
05803                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05804                   }
05805                   if (!ast_strlen_zero(p->cid_name)) {
05806                      if (!p->hidecallerid)
05807                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05808                   }
05809                   ast_setstate(chan, AST_STATE_RING);
05810                   zt_enable_ec(p);
05811                   res = ast_pbx_run(chan);
05812                   if (res) {
05813                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05814                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05815                   }
05816                   return NULL;
05817                }
05818             } else {
05819                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05820                   so just set the timeout to matchdigittimeout and wait some more */
05821                timeout = matchdigittimeout;
05822             }
05823          } else if (res == 0) {
05824             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05825             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05826             zt_wait_event(p->subs[index].zfd);
05827             ast_hangup(chan);
05828             return NULL;
05829          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05830             if (option_verbose > 2) 
05831                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05832             /* Disable call waiting if enabled */
05833             p->callwaiting = 0;
05834             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05835             if (res) {
05836                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05837                   chan->name, strerror(errno));
05838             }
05839             len = 0;
05840             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05841             memset(exten, 0, sizeof(exten));
05842             timeout = firstdigittimeout;
05843                
05844          } else if (!strcmp(exten,ast_pickup_ext())) {
05845             /* Scan all channels and see if any there
05846              * ringing channqels with that have call groups
05847              * that equal this channels pickup group  
05848              */
05849             if (index == SUB_REAL) {
05850                /* Switch us from Third call to Call Wait */
05851                if (p->subs[SUB_THREEWAY].owner) {
05852                   /* If you make a threeway call and the *8# a call, it should actually 
05853                      look like a callwait */
05854                   alloc_sub(p, SUB_CALLWAIT);   
05855                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05856                   unalloc_sub(p, SUB_THREEWAY);
05857                }
05858                zt_enable_ec(p);
05859                if (ast_pickup_call(chan)) {
05860                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05861                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05862                   zt_wait_event(p->subs[index].zfd);
05863                }
05864                ast_hangup(chan);
05865                return NULL;
05866             } else {
05867                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05868                ast_hangup(chan);
05869                return NULL;
05870             }
05871             
05872          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05873             if (option_verbose > 2) 
05874                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05875             /* Disable Caller*ID if enabled */
05876             p->hidecallerid = 1;
05877             if (chan->cid.cid_num)
05878                free(chan->cid.cid_num);
05879             chan->cid.cid_num = NULL;
05880             if (chan->cid.cid_name)
05881                free(chan->cid.cid_name);
05882             chan->cid.cid_name = NULL;
05883             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05884             if (res) {
05885                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05886                   chan->name, strerror(errno));
05887             }
05888             len = 0;
05889             memset(exten, 0, sizeof(exten));
05890             timeout = firstdigittimeout;
05891          } else if (p->callreturn && !strcmp(exten, "*69")) {
05892             res = 0;
05893             if (!ast_strlen_zero(p->lastcid_num)) {
05894                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05895             }
05896             if (!res)
05897                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05898             break;
05899          } else if (!strcmp(exten, "*78")) {
05900             /* Do not disturb */
05901             if (option_verbose > 2)
05902                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05903             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05904                      "Channel: Zap/%d\r\n"
05905                      "Status: enabled\r\n", p->channel);
05906             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05907             p->dnd = 1;
05908             getforward = 0;
05909             memset(exten, 0, sizeof(exten));
05910             len = 0;
05911          } else if (!strcmp(exten, "*79")) {
05912             /* Do not disturb */
05913             if (option_verbose > 2)
05914                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05915             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05916                      "Channel: Zap/%d\r\n"
05917                      "Status: disabled\r\n", p->channel);
05918             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05919             p->dnd = 0;
05920             getforward = 0;
05921             memset(exten, 0, sizeof(exten));
05922             len = 0;
05923          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05924             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05925             getforward = 1;
05926             memset(exten, 0, sizeof(exten));
05927             len = 0;
05928          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05929             if (option_verbose > 2)
05930                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05931             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05932             memset(p->call_forward, 0, sizeof(p->call_forward));
05933             getforward = 0;
05934             memset(exten, 0, sizeof(exten));
05935             len = 0;
05936          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
05937                   p->subs[SUB_THREEWAY].owner &&
05938                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05939             /* This is a three way call, the main call being a real channel, 
05940                and we're parking the first call. */
05941             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
05942             if (option_verbose > 2)
05943                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
05944             break;
05945          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
05946             if (option_verbose > 2)
05947                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
05948             res = ast_db_put("blacklist", p->lastcid_num, "1");
05949             if (!res) {
05950                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05951                memset(exten, 0, sizeof(exten));
05952                len = 0;
05953             }
05954          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
05955             if (option_verbose > 2) 
05956                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
05957             /* Enable Caller*ID if enabled */
05958             p->hidecallerid = 0;
05959             if (chan->cid.cid_num)
05960                free(chan->cid.cid_num);
05961             chan->cid.cid_num = NULL;
05962             if (chan->cid.cid_name)
05963                free(chan->cid.cid_name);
05964             chan->cid.cid_name = NULL;
05965             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
05966             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05967             if (res) {
05968                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05969                   chan->name, strerror(errno));
05970             }
05971             len = 0;
05972             memset(exten, 0, sizeof(exten));
05973             timeout = firstdigittimeout;
05974          } else if (!strcmp(exten, "*0")) {
05975             struct ast_channel *nbridge = 
05976                p->subs[SUB_THREEWAY].owner;
05977             struct zt_pvt *pbridge = NULL;
05978               /* set up the private struct of the bridged one, if any */
05979             if (nbridge && ast_bridged_channel(nbridge)) 
05980                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
05981             if (nbridge && pbridge && 
05982                 (nbridge->tech == &zap_tech) && 
05983                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
05984                 ISTRUNK(pbridge)) {
05985                int func = ZT_FLASH;
05986                /* Clear out the dial buffer */
05987                p->dop.dialstr[0] = '\0';
05988                /* flash hookswitch */
05989                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05990                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05991                      nbridge->name, strerror(errno));
05992                }
05993                swap_subs(p, SUB_REAL, SUB_THREEWAY);
05994                unalloc_sub(p, SUB_THREEWAY);
05995                p->owner = p->subs[SUB_REAL].owner;
05996                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
05997                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
05998                ast_hangup(chan);
05999                return NULL;
06000             } else {
06001                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06002                zt_wait_event(p->subs[index].zfd);
06003                tone_zone_play_tone(p->subs[index].zfd, -1);
06004                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06005                unalloc_sub(p, SUB_THREEWAY);
06006                p->owner = p->subs[SUB_REAL].owner;
06007                ast_hangup(chan);
06008                return NULL;
06009             }              
06010          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06011                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06012             if (option_debug)
06013                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);
06014             break;
06015          }
06016          if (!timeout)
06017             timeout = gendigittimeout;
06018          if (len && !ast_ignore_pattern(chan->context, exten))
06019             tone_zone_play_tone(p->subs[index].zfd, -1);
06020       }
06021       break;
06022    case SIG_FXSLS:
06023    case SIG_FXSGS:
06024    case SIG_FXSKS:
06025 #ifdef HAVE_PRI
06026       if (p->pri) {
06027          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06028          struct ast_frame *f;
06029          int res;
06030          time_t start;
06031 
06032          time(&start);
06033          ast_setstate(chan, AST_STATE_RING);
06034          while (time(NULL) < start + 3) {
06035             res = ast_waitfor(chan, 1000);
06036             if (res) {
06037                f = ast_read(chan);
06038                if (!f) {
06039                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06040                   ast_hangup(chan);
06041                   return NULL;
06042                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06043                   res = 1;
06044                } else
06045                   res = 0;
06046                ast_frfree(f);
06047                if (res) {
06048                   ast_log(LOG_DEBUG, "Got ring!\n");
06049                   res = 0;
06050                   break;
06051                }
06052             }
06053          }
06054       }
06055 #endif
06056       /* check for SMDI messages */
06057       if (p->use_smdi && p->smdi_iface) {
06058          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06059 
06060          if (smdi_msg != NULL) {
06061             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06062 
06063             if (smdi_msg->type == 'B')
06064                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06065             else if (smdi_msg->type == 'N')
06066                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06067 
06068             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06069          } else {
06070             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06071          }
06072       }
06073 
06074       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06075             number = smdi_msg->calling_st;
06076 
06077       /* If we want caller id, we're in a prering state due to a polarity reversal
06078        * and we're set to use a polarity reversal to trigger the start of caller id,
06079        * grab the caller id and wait for ringing to start... */
06080       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06081          /* If set to use DTMF CID signalling, listen for DTMF */
06082          if (p->cid_signalling == CID_SIG_DTMF) {
06083             int i = 0;
06084             cs = NULL;
06085             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06086                "channel %s\n", chan->name);
06087             zt_setlinear(p->subs[index].zfd, 0);
06088             res = 2000;
06089             for (;;) {
06090                struct ast_frame *f;
06091                res = ast_waitfor(chan, res);
06092                if (res <= 0) {
06093                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06094                      "Exiting simple switch\n");
06095                   ast_hangup(chan);
06096                   return NULL;
06097                } 
06098                f = ast_read(chan);
06099                if (f->frametype == AST_FRAME_DTMF) {
06100                   dtmfbuf[i++] = f->subclass;
06101                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06102                   res = 2000;
06103                }
06104                ast_frfree(f);
06105                if (chan->_state == AST_STATE_RING ||
06106                    chan->_state == AST_STATE_RINGING) 
06107                   break; /* Got ring */
06108             }
06109             dtmfbuf[i] = '\0';
06110             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06111             /* Got cid and ring. */
06112             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06113             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06114             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06115                dtmfcid, flags);
06116             /* If first byte is NULL, we have no cid */
06117             if (!ast_strlen_zero(dtmfcid)) 
06118                number = dtmfcid;
06119             else
06120                number = NULL;
06121          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06122          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06123             cs = callerid_new(p->cid_signalling);
06124             if (cs) {
06125                samples = 0;
06126 #if 1
06127                bump_gains(p);
06128 #endif            
06129                /* Take out of linear mode for Caller*ID processing */
06130                zt_setlinear(p->subs[index].zfd, 0);
06131                
06132                /* First we wait and listen for the Caller*ID */
06133                for (;;) {  
06134                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06135                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06136                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06137                      callerid_free(cs);
06138                      ast_hangup(chan);
06139                      return NULL;
06140                   }
06141                   if (i & ZT_IOMUX_SIGEVENT) {
06142                      res = zt_get_event(p->subs[index].zfd);
06143                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06144 
06145                      if (p->cid_signalling == CID_SIG_V23_JP) {
06146 #ifdef ZT_EVENT_RINGBEGIN
06147                         if (res == ZT_EVENT_RINGBEGIN) {
06148                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06149                            usleep(1);
06150                         }
06151 #endif
06152                      } else {
06153                         res = 0;
06154                         break;
06155                      }
06156                   } else if (i & ZT_IOMUX_READ) {
06157                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06158                      if (res < 0) {
06159                         if (errno != ELAST) {
06160                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06161                            callerid_free(cs);
06162                            ast_hangup(chan);
06163                            return NULL;
06164                         }
06165                         break;
06166                      }
06167                      samples += res;
06168 
06169                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06170                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06171                      } else {
06172                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06173                      }
06174 
06175                      if (res < 0) {
06176                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06177                         break;
06178                      } else if (res)
06179                         break;
06180                      else if (samples > (8000 * 10))
06181                         break;
06182                   }
06183                }
06184                if (res == 1) {
06185                   callerid_get(cs, &name, &number, &flags);
06186                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06187                }
06188                if (res < 0) {
06189                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06190                }
06191 
06192                if (p->cid_signalling == CID_SIG_V23_JP) {
06193                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06194                   usleep(1);
06195                   res = 4000;
06196                } else {
06197 
06198                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06199                   res = 2000;
06200                }
06201 
06202                for (;;) {
06203                   struct ast_frame *f;
06204                   res = ast_waitfor(chan, res);
06205                   if (res <= 0) {
06206                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06207                         "Exiting simple switch\n");
06208                      ast_hangup(chan);
06209                      return NULL;
06210                   } 
06211                   f = ast_read(chan);
06212                   ast_frfree(f);
06213                   if (chan->_state == AST_STATE_RING ||
06214                       chan->_state == AST_STATE_RINGING) 
06215                      break; /* Got ring */
06216                }
06217    
06218                /* We must have a ring by now, so, if configured, lets try to listen for
06219                 * distinctive ringing */ 
06220                if (p->usedistinctiveringdetection == 1) {
06221                   len = 0;
06222                   distMatches = 0;
06223                   /* Clear the current ring data array so we dont have old data in it. */
06224                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06225                      curRingData[receivedRingT] = 0;
06226                   receivedRingT = 0;
06227                   counter = 0;
06228                   counter1 = 0;
06229                   /* Check to see if context is what it should be, if not set to be. */
06230                   if (strcmp(p->context,p->defcontext) != 0) {
06231                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06232                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06233                   }
06234       
06235                   for (;;) {  
06236                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06237                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06238                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06239                         callerid_free(cs);
06240                         ast_hangup(chan);
06241                         return NULL;
06242                      }
06243                      if (i & ZT_IOMUX_SIGEVENT) {
06244                         res = zt_get_event(p->subs[index].zfd);
06245                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06246                         res = 0;
06247                         /* Let us detect distinctive ring */
06248       
06249                         curRingData[receivedRingT] = p->ringt;
06250       
06251                         if (p->ringt < p->ringt_base/2)
06252                            break;
06253                         /* Increment the ringT counter so we can match it against
06254                            values in zapata.conf for distinctive ring */
06255                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06256                            break;
06257                      } else if (i & ZT_IOMUX_READ) {
06258                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06259                         if (res < 0) {
06260                            if (errno != ELAST) {
06261                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06262                               callerid_free(cs);
06263                               ast_hangup(chan);
06264                               return NULL;
06265                            }
06266                            break;
06267                         }
06268                         if (p->ringt) 
06269                            p->ringt--;
06270                         if (p->ringt == 1) {
06271                            res = -1;
06272                            break;
06273                         }
06274                      }
06275                   }
06276                   if (option_verbose > 2)
06277                      /* this only shows up if you have n of the dring patterns filled in */
06278                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06279    
06280                   for (counter = 0; counter < 3; counter++) {
06281                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06282                      channel */
06283                      distMatches = 0;
06284                      for (counter1 = 0; counter1 < 3; counter1++) {
06285                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06286                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06287                            distMatches++;
06288                         }
06289                      }
06290                      if (distMatches == 3) {
06291                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06292                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06293                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06294                         if (option_verbose > 2)
06295                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06296                         break;
06297                      }
06298                   }
06299                }
06300                /* Restore linear mode (if appropriate) for Caller*ID processing */
06301                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06302 #if 1
06303                restore_gains(p);
06304 #endif            
06305             } else
06306                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06307          } else {
06308             ast_log(LOG_WARNING, "Channel %s in prering "
06309                "state, but I have nothing to do. "
06310                "Terminating simple switch, should be "
06311                "restarted by the actual ring.\n", 
06312                chan->name);
06313             ast_hangup(chan);
06314             return NULL;
06315          }
06316       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06317          /* FSK Bell202 callerID */
06318          cs = callerid_new(p->cid_signalling);
06319          if (cs) {
06320 #if 1
06321             bump_gains(p);
06322 #endif            
06323             samples = 0;
06324             len = 0;
06325             distMatches = 0;
06326             /* Clear the current ring data array so we dont have old data in it. */
06327             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06328                curRingData[receivedRingT] = 0;
06329             receivedRingT = 0;
06330             counter = 0;
06331             counter1 = 0;
06332             /* Check to see if context is what it should be, if not set to be. */
06333             if (strcmp(p->context,p->defcontext) != 0) {
06334                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06335                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06336             }
06337 
06338             /* Take out of linear mode for Caller*ID processing */
06339             zt_setlinear(p->subs[index].zfd, 0);
06340             for (;;) {  
06341                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06342                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06343                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06344                   callerid_free(cs);
06345                   ast_hangup(chan);
06346                   return NULL;
06347                }
06348                if (i & ZT_IOMUX_SIGEVENT) {
06349                   res = zt_get_event(p->subs[index].zfd);
06350                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06351                   res = 0;
06352                   /* Let us detect callerid when the telco uses distinctive ring */
06353 
06354                   curRingData[receivedRingT] = p->ringt;
06355 
06356                   if (p->ringt < p->ringt_base/2)
06357                      break;
06358                   /* Increment the ringT counter so we can match it against
06359                      values in zapata.conf for distinctive ring */
06360                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06361                      break;
06362                } else if (i & ZT_IOMUX_READ) {
06363                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06364                   if (res < 0) {
06365                      if (errno != ELAST) {
06366                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06367                         callerid_free(cs);
06368                         ast_hangup(chan);
06369                         return NULL;
06370                      }
06371                      break;
06372                   }
06373                   if (p->ringt) 
06374                      p->ringt--;
06375                   if (p->ringt == 1) {
06376                      res = -1;
06377                      break;
06378                   }
06379                   samples += res;
06380                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06381                   if (res < 0) {
06382                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06383                      break;
06384                   } else if (res)
06385                      break;
06386                   else if (samples > (8000 * 10))
06387                      break;
06388                }
06389             }
06390             if (res == 1) {
06391                callerid_get(cs, &name, &number, &flags);
06392                if (option_debug)
06393                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06394             }
06395             if (distinctiveringaftercid == 1) {
06396                /* Clear the current ring data array so we dont have old data in it. */
06397                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06398                   curRingData[receivedRingT] = 0;
06399                }
06400                receivedRingT = 0;
06401                if (option_verbose > 2)
06402                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06403                for (;;) {
06404                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06405                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06406                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06407                      callerid_free(cs);
06408                      ast_hangup(chan);
06409                      return NULL;
06410                   }
06411                   if (i & ZT_IOMUX_SIGEVENT) {
06412                      res = zt_get_event(p->subs[index].zfd);
06413                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06414                      res = 0;
06415                      /* Let us detect callerid when the telco uses distinctive ring */
06416 
06417                      curRingData[receivedRingT] = p->ringt;
06418 
06419                      if (p->ringt < p->ringt_base/2)
06420                         break;
06421                      /* Increment the ringT counter so we can match it against
06422                         values in zapata.conf for distinctive ring */
06423                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06424                         break;
06425                   } else if (i & ZT_IOMUX_READ) {
06426                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06427                      if (res < 0) {
06428                         if (errno != ELAST) {
06429                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06430                            callerid_free(cs);
06431                            ast_hangup(chan);
06432                            return NULL;
06433                         }
06434                         break;
06435                      }
06436                   if (p->ringt)
06437                      p->ringt--;
06438                      if (p->ringt == 1) {
06439                         res = -1;
06440                         break;
06441                      }
06442                   }
06443                }
06444             }
06445             if (p->usedistinctiveringdetection == 1) {
06446                if (option_verbose > 2)
06447                   /* this only shows up if you have n of the dring patterns filled in */
06448                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06449 
06450                for (counter = 0; counter < 3; counter++) {
06451                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06452                   channel */
06453                   if (option_verbose > 2)
06454                      /* this only shows up if you have n of the dring patterns filled in */
06455                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06456                         p->drings.ringnum[counter].ring[0],
06457                         p->drings.ringnum[counter].ring[1],
06458                         p->drings.ringnum[counter].ring[2]);
06459                   distMatches = 0;
06460                   for (counter1 = 0; counter1 < 3; counter1++) {
06461                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06462                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06463                         distMatches++;
06464                      }
06465                   }
06466                   if (distMatches == 3) {
06467                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06468                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06469                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06470                      if (option_verbose > 2)
06471                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06472                      break;
06473                   }
06474                }
06475             }
06476             /* Restore linear mode (if appropriate) for Caller*ID processing */
06477             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06478 #if 1
06479             restore_gains(p);
06480 #endif            
06481             if (res < 0) {
06482                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06483             }
06484          } else
06485             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06486       }
06487       else
06488          cs = NULL;
06489 
06490       if (number)
06491          ast_shrink_phone_number(number);
06492       ast_set_callerid(chan, number, name, number);
06493 
06494       if (smdi_msg)
06495          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06496 
06497       if (cs)
06498          callerid_free(cs);
06499 
06500       ast_setstate(chan, AST_STATE_RING);
06501       chan->rings = 1;
06502       p->ringt = p->ringt_base;
06503       res = ast_pbx_run(chan);
06504       if (res) {
06505          ast_hangup(chan);
06506          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06507       }
06508       return NULL;
06509    default:
06510       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06511       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06512       if (res < 0)
06513             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06514    }
06515    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06516    if (res < 0)
06517          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06518    ast_hangup(chan);
06519    return NULL;
06520 }
06521 
06522 /* destroy a zaptel channel, identified by its number */
06523 static int zap_destroy_channel_bynum(int channel)
06524 {
06525    struct zt_pvt *tmp = NULL;
06526    struct zt_pvt *prev = NULL;
06527 
06528    tmp = iflist;
06529    while (tmp) {
06530       if (tmp->channel == channel) {
06531          destroy_channel(prev, tmp, 1);
06532          return RESULT_SUCCESS;
06533       }
06534       prev = tmp;
06535       tmp = tmp->next;
06536    }
06537    return RESULT_FAILURE;
06538 }
06539 
06540 static int handle_init_event(struct zt_pvt *i, int event)
06541 {
06542    int res;
06543    pthread_t threadid;
06544    pthread_attr_t attr;
06545    struct ast_channel *chan;
06546    pthread_attr_init(&attr);
06547    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06548    /* Handle an event on a given channel for the monitor thread. */
06549    switch (event) {
06550    case ZT_EVENT_NONE:
06551    case ZT_EVENT_BITSCHANGED:
06552       break;
06553    case ZT_EVENT_WINKFLASH:
06554    case ZT_EVENT_RINGOFFHOOK:
06555       if (i->inalarm) break;
06556       if (i->radio) break;
06557       /* Got a ring/answer.  What kind of channel are we? */
06558       switch (i->sig) {
06559       case SIG_FXOLS:
06560       case SIG_FXOGS:
06561       case SIG_FXOKS:
06562          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06563          if (res && (errno == EBUSY))
06564             break;
06565          if (i->cidspill) {
06566             /* Cancel VMWI spill */
06567             free(i->cidspill);
06568             i->cidspill = NULL;
06569          }
06570          if (i->immediate) {
06571             zt_enable_ec(i);
06572             /* The channel is immediately up.  Start right away */
06573             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06574             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06575             if (!chan) {
06576                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06577                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06578                if (res < 0)
06579                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06580             }
06581          } else {
06582             /* Check for callerid, digits, etc */
06583             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06584             if (chan) {
06585                if (has_voicemail(i))
06586                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06587                else
06588                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06589                if (res < 0) 
06590                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
06591                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06592                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06593                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06594                   if (res < 0)
06595                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06596                   ast_hangup(chan);
06597                }
06598             } else
06599                ast_log(LOG_WARNING, "Unable to create channel\n");
06600          }
06601          break;
06602       case SIG_FXSLS:
06603       case SIG_FXSGS:
06604       case SIG_FXSKS:
06605             i->ringt = i->ringt_base;
06606             /* Fall through */
06607       case SIG_EMWINK:
06608       case SIG_FEATD:
06609       case SIG_FEATDMF:
06610       case SIG_FEATDMF_TA:
06611       case SIG_E911:
06612       case SIG_FGC_CAMA:
06613       case SIG_FGC_CAMAMF:
06614       case SIG_FEATB:
06615       case SIG_EM:
06616       case SIG_EM_E1:
06617       case SIG_SFWINK:
06618       case SIG_SF_FEATD:
06619       case SIG_SF_FEATDMF:
06620       case SIG_SF_FEATB:
06621       case SIG_SF:
06622             /* Check for callerid, digits, etc */
06623             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06624             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06625                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06626                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06627                if (res < 0)
06628                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06629                ast_hangup(chan);
06630             } else if (!chan) {
06631                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06632             }
06633             break;
06634       default:
06635          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06636          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06637          if (res < 0)
06638                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06639          return -1;
06640       }
06641       break;
06642    case ZT_EVENT_NOALARM:
06643       i->inalarm = 0;
06644       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06645       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06646          "Channel: %d\r\n", i->channel);
06647       break;
06648    case ZT_EVENT_ALARM:
06649       i->inalarm = 1;
06650       res = get_alarms(i);
06651       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06652       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06653          "Alarm: %s\r\n"
06654          "Channel: %d\r\n",
06655          alarm2str(res), i->channel);
06656       /* fall thru intentionally */
06657    case ZT_EVENT_ONHOOK:
06658       if (i->radio)
06659          break;
06660       /* Back on hook.  Hang up. */
06661       switch (i->sig) {
06662       case SIG_FXOLS:
06663       case SIG_FXOGS:
06664       case SIG_FEATD:
06665       case SIG_FEATDMF:
06666       case SIG_FEATDMF_TA:
06667       case SIG_E911:
06668       case SIG_FGC_CAMA:
06669       case SIG_FGC_CAMAMF:
06670       case SIG_FEATB:
06671       case SIG_EM:
06672       case SIG_EM_E1:
06673       case SIG_EMWINK:
06674       case SIG_SF_FEATD:
06675       case SIG_SF_FEATDMF:
06676       case SIG_SF_FEATB:
06677       case SIG_SF:
06678       case SIG_SFWINK:
06679       case SIG_FXSLS:
06680       case SIG_FXSGS:
06681       case SIG_FXSKS:
06682       case SIG_GR303FXSKS:
06683          zt_disable_ec(i);
06684          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06685          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06686          break;
06687       case SIG_GR303FXOKS:
06688       case SIG_FXOKS:
06689          zt_disable_ec(i);
06690          /* Diddle the battery for the zhone */
06691 #ifdef ZHONE_HACK
06692          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06693          usleep(1);
06694 #endif         
06695          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06696          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06697          break;
06698       case SIG_PRI:
06699          zt_disable_ec(i);
06700          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06701          break;
06702       default:
06703          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06704          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06705          return -1;
06706       }
06707       break;
06708    case ZT_EVENT_POLARITY:
06709       switch (i->sig) {
06710       case SIG_FXSLS:
06711       case SIG_FXSKS:
06712       case SIG_FXSGS:
06713          if (i->cid_start == CID_START_POLARITY) {
06714             i->polarity = POLARITY_REV;
06715             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06716                    "CID detection on channel %d\n",
06717                    i->channel);
06718             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06719             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06720                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06721             }
06722          }
06723          break;
06724       default:
06725          ast_log(LOG_WARNING, "handle_init_event detected "
06726             "polarity reversal on non-FXO (SIG_FXS) "
06727             "interface %d\n", i->channel);
06728       }
06729       break;
06730    case ZT_EVENT_REMOVED: /* destroy channel */
06731       ast_log(LOG_NOTICE, 
06732             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
06733             i->channel);
06734       zap_destroy_channel_bynum(i->channel);
06735       break;
06736    }
06737    pthread_attr_destroy(&attr);
06738    return 0;
06739 }
06740 
06741 static void *do_monitor(void *data)
06742 {
06743    int count, res, res2, spoint, pollres=0;
06744    struct zt_pvt *i;
06745    struct zt_pvt *last = NULL;
06746    time_t thispass = 0, lastpass = 0;
06747    int found;
06748    char buf[1024];
06749    struct pollfd *pfds=NULL;
06750    int lastalloc = -1;
06751    /* This thread monitors all the frame relay interfaces which are not yet in use
06752       (and thus do not have a separate thread) indefinitely */
06753    /* From here on out, we die whenever asked */
06754 #if 0
06755    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06756       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06757       return NULL;
06758    }
06759    ast_log(LOG_DEBUG, "Monitor starting...\n");
06760 #endif
06761    for (;;) {
06762       /* Lock the interface list */
06763       ast_mutex_lock(&iflock);
06764       if (!pfds || (lastalloc != ifcount)) {
06765          if (pfds)
06766             free(pfds);
06767          if (ifcount) {
06768             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
06769                ast_mutex_unlock(&iflock);
06770                return NULL;
06771             }
06772          }
06773          lastalloc = ifcount;
06774       }
06775       /* Build the stuff we're going to poll on, that is the socket of every
06776          zt_pvt that does not have an associated owner channel */
06777       count = 0;
06778       i = iflist;
06779       while (i) {
06780          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06781             if (!i->owner && !i->subs[SUB_REAL].owner) {
06782                /* This needs to be watched, as it lacks an owner */
06783                pfds[count].fd = i->subs[SUB_REAL].zfd;
06784                pfds[count].events = POLLPRI;
06785                pfds[count].revents = 0;
06786                /* Message waiting or r2 channels also get watched for reading */
06787                if (i->cidspill)
06788                   pfds[count].events |= POLLIN;
06789                count++;
06790             }
06791          }
06792          i = i->next;
06793       }
06794       /* Okay, now that we know what to do, release the interface lock */
06795       ast_mutex_unlock(&iflock);
06796       
06797       pthread_testcancel();
06798       /* Wait at least a second for something to happen */
06799       res = poll(pfds, count, 1000);
06800       pthread_testcancel();
06801       /* Okay, poll has finished.  Let's see what happened.  */
06802       if (res < 0) {
06803          if ((errno != EAGAIN) && (errno != EINTR))
06804             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06805          continue;
06806       }
06807       /* Alright, lock the interface list again, and let's look and see what has
06808          happened */
06809       ast_mutex_lock(&iflock);
06810       found = 0;
06811       spoint = 0;
06812       lastpass = thispass;
06813       thispass = time(NULL);
06814       i = iflist;
06815       while (i) {
06816          if (thispass != lastpass) {
06817             if (!found && ((i == last) || ((i == iflist) && !last))) {
06818                last = i;
06819                if (last) {
06820                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06821                      (last->sig & __ZT_SIG_FXO)) {
06822                      res = ast_app_has_voicemail(last->mailbox, NULL);
06823                      if (last->msgstate != res) {
06824                         int x;
06825                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06826                         x = ZT_FLUSH_BOTH;
06827                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06828                         if (res2)
06829                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06830                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
06831                            /* Turn on on hook transfer for 4 seconds */
06832                            x = 4000;
06833                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06834                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06835                            last->cidpos = 0;
06836                            last->msgstate = res;
06837                            last->onhooktime = thispass;
06838                         }
06839                         found ++;
06840                      }
06841                   }
06842                   last = last->next;
06843                }
06844             }
06845          }
06846          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06847             if (i->radio && !i->owner)
06848             {
06849                res = zt_get_event(i->subs[SUB_REAL].zfd);
06850                if (res)
06851                {
06852                   if (option_debug)
06853                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06854                   /* Don't hold iflock while handling init events */
06855                   ast_mutex_unlock(&iflock);
06856                   handle_init_event(i, res);
06857                   ast_mutex_lock(&iflock);   
06858                }
06859                i = i->next;
06860                continue;
06861             }              
06862             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06863             if (pollres & POLLIN) {
06864                if (i->owner || i->subs[SUB_REAL].owner) {
06865 #ifdef HAVE_PRI
06866                   if (!i->pri)
06867 #endif                  
06868                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06869                   i = i->next;
06870                   continue;
06871                }
06872                if (!i->cidspill) {
06873                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06874                   i = i->next;
06875                   continue;
06876                }
06877                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06878                if (res > 0) {
06879                   /* We read some number of bytes.  Write an equal amount of data */
06880                   if (res > i->cidlen - i->cidpos) 
06881                      res = i->cidlen - i->cidpos;
06882                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06883                   if (res2 > 0) {
06884                      i->cidpos += res2;
06885                      if (i->cidpos >= i->cidlen) {
06886                         free(i->cidspill);
06887                         i->cidspill = 0;
06888                         i->cidpos = 0;
06889                         i->cidlen = 0;
06890                      }
06891                   } else {
06892                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06893                      i->msgstate = -1;
06894                   }
06895                } else {
06896                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06897                }
06898                if (option_debug)
06899                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06900                /* Don't hold iflock while handling init events -- race with chlock */
06901                ast_mutex_unlock(&iflock);
06902                handle_init_event(i, res);
06903                ast_mutex_lock(&iflock);   
06904             }
06905             if (pollres & POLLPRI) {
06906                if (i->owner || i->subs[SUB_REAL].owner) {
06907 #ifdef HAVE_PRI
06908                   if (!i->pri)
06909 #endif                  
06910                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06911                   i = i->next;
06912                   continue;
06913                }
06914                res = zt_get_event(i->subs[SUB_REAL].zfd);
06915                if (option_debug)
06916                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06917                /* Don't hold iflock while handling init events */
06918                ast_mutex_unlock(&iflock);
06919                handle_init_event(i, res);
06920                ast_mutex_lock(&iflock);   
06921             }
06922          }
06923          i=i->next;
06924       }
06925       ast_mutex_unlock(&iflock);
06926    }
06927    /* Never reached */
06928    return NULL;
06929    
06930 }
06931 
06932 static int restart_monitor(void)
06933 {
06934    pthread_attr_t attr;
06935    pthread_attr_init(&attr);
06936    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06937    /* If we're supposed to be stopped -- stay stopped */
06938    if (monitor_thread == AST_PTHREADT_STOP)
06939       return 0;
06940    ast_mutex_lock(&monlock);
06941    if (monitor_thread == pthread_self()) {
06942       ast_mutex_unlock(&monlock);
06943       ast_log(LOG_WARNING, "Cannot kill myself\n");
06944       return -1;
06945    }
06946    if (monitor_thread != AST_PTHREADT_NULL) {
06947       /* Wake up the thread */
06948       pthread_kill(monitor_thread, SIGURG);
06949    } else {
06950       /* Start a new monitor */
06951       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
06952          ast_mutex_unlock(&monlock);
06953          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
06954          pthread_attr_destroy(&attr);
06955          return -1;
06956       }
06957    }
06958    ast_mutex_unlock(&monlock);
06959    pthread_attr_destroy(&attr);
06960    return 0;
06961 }
06962 
06963 #ifdef HAVE_PRI
06964 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
06965 {
06966    int x;
06967    int trunkgroup;
06968    /* Get appropriate trunk group if there is one */
06969    trunkgroup = pris[*span].mastertrunkgroup;
06970    if (trunkgroup) {
06971       /* Select a specific trunk group */
06972       for (x = 0; x < NUM_SPANS; x++) {
06973          if (pris[x].trunkgroup == trunkgroup) {
06974             *span = x;
06975             return 0;
06976          }
06977       }
06978       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
06979       *span = -1;
06980    } else {
06981       if (pris[*span].trunkgroup) {
06982          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
06983          *span = -1;
06984       } else if (pris[*span].mastertrunkgroup) {
06985          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
06986          *span = -1;
06987       } else {
06988          if (si->totalchans == 31) { /* if it's an E1 */
06989             pris[*span].dchannels[0] = 16 + offset;
06990          } else {
06991             pris[*span].dchannels[0] = 24 + offset;
06992          }
06993          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
06994          pris[*span].offset = offset;
06995          pris[*span].span = *span + 1;
06996       }
06997    }
06998    return 0;
06999 }
07000 
07001 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07002 {
07003    struct zt_spaninfo si;
07004    ZT_PARAMS p;
07005    int fd;
07006    int span;
07007    int ospan=0;
07008    int x,y;
07009    for (x = 0; x < NUM_SPANS; x++) {
07010       if (pris[x].trunkgroup == trunkgroup) {
07011          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07012          return -1;
07013       }
07014    }
07015    for (y = 0; y < NUM_DCHANS; y++) {
07016       if (!channels[y]) 
07017          break;
07018       memset(&si, 0, sizeof(si));
07019       memset(&p, 0, sizeof(p));
07020       fd = open("/dev/zap/channel", O_RDWR);
07021       if (fd < 0) {
07022          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07023          return -1;
07024       }
07025       x = channels[y];
07026       if (ioctl(fd, ZT_SPECIFY, &x)) {
07027          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07028          zt_close(fd);
07029          return -1;
07030       }
07031       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07032          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07033          return -1;
07034       }
07035       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07036          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07037          zt_close(fd);
07038          return -1;
07039       }
07040       span = p.spanno - 1;
07041       if (pris[span].trunkgroup) {
07042          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07043          zt_close(fd);
07044          return -1;
07045       }
07046       if (pris[span].pvts[0]) {
07047          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07048          zt_close(fd);
07049          return -1;
07050       }
07051       if (!y) {
07052          pris[span].trunkgroup = trunkgroup;
07053          pris[span].offset = channels[y] - p.chanpos;
07054          ospan = span;
07055       }
07056       pris[ospan].dchannels[y] = channels[y];
07057       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07058       pris[span].span = span + 1;
07059       zt_close(fd);
07060    }
07061    return 0;   
07062 }
07063 
07064 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07065 {
07066    if (pris[span].mastertrunkgroup) {
07067       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);
07068       return -1;
07069    }
07070    pris[span].mastertrunkgroup = trunkgroup;
07071    pris[span].prilogicalspan = logicalspan;
07072    return 0;
07073 }
07074 
07075 #endif
07076 
07077 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
07078 {
07079    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07080    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07081    char fn[80];
07082 #if 1
07083    struct zt_bufferinfo bi;
07084 #endif
07085    struct zt_spaninfo si;
07086    int res;
07087    int span=0;
07088    int here = 0;
07089    int x;
07090    struct zt_pvt **wlist;
07091    struct zt_pvt **wend;
07092    ZT_PARAMS p;
07093 
07094    wlist = &iflist;
07095    wend = &ifend;
07096 
07097 #ifdef HAVE_PRI
07098    if (pri) {
07099       wlist = &pri->crvs;
07100       wend = &pri->crvend;
07101    }
07102 #endif
07103 
07104    tmp2 = *wlist;
07105    prev = NULL;
07106 
07107    while (tmp2) {
07108       if (!tmp2->destroy) {
07109          if (tmp2->channel == channel) {
07110             tmp = tmp2;
07111             here = 1;
07112             break;
07113          }
07114          if (tmp2->channel > channel) {
07115             break;
07116          }
07117       }
07118       prev = tmp2;
07119       tmp2 = tmp2->next;
07120    }
07121 
07122    if (!here && !reloading) {
07123       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07124          destroy_zt_pvt(&tmp);
07125          return NULL;
07126       }
07127       ast_mutex_init(&tmp->lock);
07128       ifcount++;
07129       for (x = 0; x < 3; x++)
07130          tmp->subs[x].zfd = -1;
07131       tmp->channel = channel;
07132    }
07133 
07134    if (tmp) {
07135       if (!here) {
07136          if ((channel != CHAN_PSEUDO) && !pri) {
07137             snprintf(fn, sizeof(fn), "%d", channel);
07138             /* Open non-blocking */
07139             if (!here)
07140                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07141             /* Allocate a zapata structure */
07142             if (tmp->subs[SUB_REAL].zfd < 0) {
07143                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);
07144                destroy_zt_pvt(&tmp);
07145                return NULL;
07146             }
07147             memset(&p, 0, sizeof(p));
07148             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07149             if (res < 0) {
07150                ast_log(LOG_ERROR, "Unable to get parameters\n");
07151                destroy_zt_pvt(&tmp);
07152                return NULL;
07153             }
07154             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07155                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));
07156                destroy_zt_pvt(&tmp);
07157                return NULL;
07158             }
07159             tmp->law = p.curlaw;
07160             tmp->span = p.spanno;
07161             span = p.spanno - 1;
07162          } else {
07163             if (channel == CHAN_PSEUDO)
07164                conf.chan.sig = 0;
07165             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07166                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07167                return NULL;
07168             }
07169          }
07170 #ifdef HAVE_PRI
07171          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07172             int offset;
07173             int myswitchtype;
07174             int matchesdchan;
07175             int x,y;
07176             offset = 0;
07177             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07178                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07179                destroy_zt_pvt(&tmp);
07180                return NULL;
07181             }
07182             if (span >= NUM_SPANS) {
07183                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07184                destroy_zt_pvt(&tmp);
07185                return NULL;
07186             } else {
07187                si.spanno = 0;
07188                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07189                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07190                   destroy_zt_pvt(&tmp);
07191                   return NULL;
07192                }
07193                /* Store the logical span first based upon the real span */
07194                tmp->logicalspan = pris[span].prilogicalspan;
07195                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07196                if (span < 0) {
07197                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07198                   destroy_zt_pvt(&tmp);
07199                   return NULL;
07200                }
07201                if (conf.chan.sig == SIG_PRI)
07202                   myswitchtype = conf.pri.switchtype;
07203                else
07204                   myswitchtype = PRI_SWITCH_GR303_TMC;
07205                /* Make sure this isn't a d-channel */
07206                matchesdchan=0;
07207                for (x = 0; x < NUM_SPANS; x++) {
07208                   for (y = 0; y < NUM_DCHANS; y++) {
07209                      if (pris[x].dchannels[y] == tmp->channel) {
07210                         matchesdchan = 1;
07211                         break;
07212                      }
07213                   }
07214                }
07215                offset = p.chanpos;
07216                if (!matchesdchan) {
07217                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07218                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07219                      destroy_zt_pvt(&tmp);
07220                      return NULL;
07221                   }
07222                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07223                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07224                      destroy_zt_pvt(&tmp);
07225                      return NULL;
07226                   }
07227                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07228                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07229                      destroy_zt_pvt(&tmp);
07230                      return NULL;
07231                   }
07232                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07233                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07234                      destroy_zt_pvt(&tmp);
07235                      return NULL;
07236                   }
07237                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07238                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07239                      destroy_zt_pvt(&tmp);
07240                      return NULL;
07241                   }
07242                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07243                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07244                      destroy_zt_pvt(&tmp);
07245                      return NULL;
07246                   }
07247                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07248                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07249                      destroy_zt_pvt(&tmp);
07250                      return NULL;
07251                   }
07252                   if (pris[span].numchans >= MAX_CHANNELS) {
07253                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07254                         pris[span].trunkgroup);
07255                      destroy_zt_pvt(&tmp);
07256                      return NULL;
07257                   }
07258                   pris[span].nodetype = conf.pri.nodetype;
07259                   pris[span].switchtype = myswitchtype;
07260                   pris[span].nsf = conf.pri.nsf;
07261                   pris[span].dialplan = conf.pri.dialplan;
07262                   pris[span].localdialplan = conf.pri.localdialplan;
07263                   pris[span].pvts[pris[span].numchans++] = tmp;
07264                   pris[span].minunused = conf.pri.minunused;
07265                   pris[span].minidle = conf.pri.minidle;
07266                   pris[span].overlapdial = conf.pri.overlapdial;
07267                   pris[span].facilityenable = conf.pri.facilityenable;
07268                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07269                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07270                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07271                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07272                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07273                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07274                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07275                   pris[span].resetinterval = conf.pri.resetinterval;
07276                   
07277                   tmp->pri = &pris[span];
07278                   tmp->prioffset = offset;
07279                   tmp->call = NULL;
07280                } else {
07281                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07282                   destroy_zt_pvt(&tmp);
07283                   return NULL;
07284                }
07285             }
07286          } else {
07287             tmp->prioffset = 0;
07288          }
07289 #endif
07290       } else {
07291          conf.chan.sig = tmp->sig;
07292          conf.chan.radio = tmp->radio;
07293          memset(&p, 0, sizeof(p));
07294          if (tmp->subs[SUB_REAL].zfd > -1)
07295             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07296       }
07297       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07298       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07299           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07300          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07301            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07302           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07303          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07304            (conf.chan.sig == SIG_SF_FEATB)) {
07305          p.starttime = 250;
07306       }
07307       if (conf.chan.radio) {
07308          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07309          p.channo = channel;
07310          p.rxwinktime = 1;
07311          p.rxflashtime = 1;
07312          p.starttime = 1;
07313          p.debouncetime = 5;
07314       }
07315       if (!conf.chan.radio) {
07316          p.channo = channel;
07317          /* Override timing settings based on config file */
07318          if (conf.timing.prewinktime >= 0)
07319             p.prewinktime = conf.timing.prewinktime;
07320          if (conf.timing.preflashtime >= 0)
07321             p.preflashtime = conf.timing.preflashtime;
07322          if (conf.timing.winktime >= 0)
07323             p.winktime = conf.timing.winktime;
07324          if (conf.timing.flashtime >= 0)
07325             p.flashtime = conf.timing.flashtime;
07326          if (conf.timing.starttime >= 0)
07327             p.starttime = conf.timing.starttime;
07328          if (conf.timing.rxwinktime >= 0)
07329             p.rxwinktime = conf.timing.rxwinktime;
07330          if (conf.timing.rxflashtime >= 0)
07331             p.rxflashtime = conf.timing.rxflashtime;
07332          if (conf.timing.debouncetime >= 0)
07333             p.debouncetime = conf.timing.debouncetime;
07334       }
07335       
07336       /* dont set parms on a pseudo-channel (or CRV) */
07337       if (tmp->subs[SUB_REAL].zfd >= 0)
07338       {
07339          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07340          if (res < 0) {
07341             ast_log(LOG_ERROR, "Unable to set parameters\n");
07342             destroy_zt_pvt(&tmp);
07343             return NULL;
07344          }
07345       }
07346 #if 1
07347       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07348          memset(&bi, 0, sizeof(bi));
07349          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07350          if (!res) {
07351             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07352             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07353             bi.numbufs = numbufs;
07354             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07355             if (res < 0) {
07356                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07357             }
07358          } else
07359             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07360       }
07361 #endif
07362       tmp->immediate = conf.chan.immediate;
07363       tmp->transfertobusy = conf.chan.transfertobusy;
07364       tmp->sig = conf.chan.sig;
07365       tmp->outsigmod = conf.chan.outsigmod;
07366       tmp->radio = conf.chan.radio;
07367       tmp->ringt_base = ringt_base;
07368       tmp->firstradio = 0;
07369       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07370          tmp->permcallwaiting = conf.chan.callwaiting;
07371       else
07372          tmp->permcallwaiting = 0;
07373       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07374       tmp->destroy = 0;
07375       tmp->drings = drings;
07376       tmp->usedistinctiveringdetection = usedistinctiveringdetection;
07377       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07378       tmp->threewaycalling = conf.chan.threewaycalling;
07379       tmp->adsi = conf.chan.adsi;
07380       tmp->use_smdi = conf.chan.use_smdi;
07381       tmp->permhidecallerid = conf.chan.hidecallerid;
07382       tmp->callreturn = conf.chan.callreturn;
07383       tmp->echocancel = conf.chan.echocancel;
07384       tmp->echotraining = conf.chan.echotraining;
07385       tmp->pulse = conf.chan.pulse;
07386       tmp->echocanbridged = conf.chan.echocanbridged;
07387       tmp->busydetect = conf.chan.busydetect;
07388       tmp->busycount = conf.chan.busycount;
07389       tmp->busy_tonelength = conf.chan.busy_tonelength;
07390       tmp->busy_quietlength = conf.chan.busy_quietlength;
07391       tmp->callprogress = conf.chan.callprogress;
07392       tmp->cancallforward = conf.chan.cancallforward;
07393       tmp->dtmfrelax = conf.chan.dtmfrelax;
07394       tmp->callwaiting = tmp->permcallwaiting;
07395       tmp->hidecallerid = tmp->permhidecallerid;
07396       tmp->channel = channel;
07397       tmp->stripmsd = conf.chan.stripmsd;
07398       tmp->use_callerid = conf.chan.use_callerid;
07399       tmp->cid_signalling = conf.chan.cid_signalling;
07400       tmp->cid_start = conf.chan.cid_start;
07401       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07402       tmp->restrictcid = conf.chan.restrictcid;
07403       tmp->use_callingpres = conf.chan.use_callingpres;
07404       tmp->priindication_oob = conf.chan.priindication_oob;
07405       tmp->priexclusive = conf.chan.priexclusive;
07406       if (tmp->usedistinctiveringdetection) {
07407          if (!tmp->use_callerid) {
07408             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07409             tmp->use_callerid = 1;
07410          }
07411       }
07412 
07413       if (tmp->cid_signalling == CID_SIG_SMDI) {
07414          if (!tmp->use_smdi) {
07415             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07416             tmp->use_smdi = 1;
07417          }
07418       }
07419       if (tmp->use_smdi) {
07420          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07421          if (!(tmp->smdi_iface)) {
07422             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07423             tmp->use_smdi = 0;
07424          }
07425       }
07426 
07427       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07428       tmp->amaflags = conf.chan.amaflags;
07429       if (!here) {
07430          tmp->confno = -1;
07431          tmp->propconfno = -1;
07432       }
07433       tmp->canpark = conf.chan.canpark;
07434       tmp->transfer = conf.chan.transfer;
07435       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07436       ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
07437       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07438       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07439       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07440       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07441       tmp->cid_ton = 0;
07442       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07443       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07444       tmp->msgstate = -1;
07445       tmp->group = conf.chan.group;
07446       tmp->callgroup = conf.chan.callgroup;
07447       tmp->pickupgroup= conf.chan.pickupgroup;
07448       tmp->rxgain = conf.chan.rxgain;
07449       tmp->txgain = conf.chan.txgain;
07450       tmp->tonezone = conf.chan.tonezone;
07451       tmp->onhooktime = time(NULL);
07452       if (tmp->subs[SUB_REAL].zfd > -1) {
07453          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07454          if (tmp->dsp)
07455             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07456          update_conf(tmp);
07457          if (!here) {
07458             if (conf.chan.sig != SIG_PRI)
07459                /* Hang it up to be sure it's good */
07460                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07461          }
07462          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07463 #ifdef HAVE_PRI
07464          /* the dchannel is down so put the channel in alarm */
07465          if (tmp->pri && !pri_is_up(tmp->pri))
07466             tmp->inalarm = 1;
07467          else
07468             tmp->inalarm = 0;
07469 #endif            
07470          memset(&si, 0, sizeof(si));
07471          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07472             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07473             destroy_zt_pvt(&tmp);
07474             return NULL;
07475          }
07476          if (si.alarms) tmp->inalarm = 1;
07477       }
07478 
07479       tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
07480       tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
07481       tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
07482       tmp->sendcalleridafter = conf.chan.sendcalleridafter;
07483 
07484    }
07485    if (tmp && !here) {
07486       /* nothing on the iflist */
07487       if (!*wlist) {
07488          *wlist = tmp;
07489          tmp->prev = NULL;
07490          tmp->next = NULL;
07491          *wend = tmp;
07492       } else {
07493          /* at least one member on the iflist */
07494          struct zt_pvt *working = *wlist;
07495 
07496          /* check if we maybe have to put it on the begining */
07497          if (working->channel > tmp->channel) {
07498             tmp->next = *wlist;
07499             tmp->prev = NULL;
07500             (*wlist)->prev = tmp;
07501             *wlist = tmp;
07502          } else {
07503          /* go through all the members and put the member in the right place */
07504             while (working) {
07505                /* in the middle */
07506                if (working->next) {
07507                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07508                      tmp->next = working->next;
07509                      tmp->prev = working;
07510                      working->next->prev = tmp;
07511                      working->next = tmp;
07512                      break;
07513                   }
07514                } else {
07515                /* the last */
07516                   if (working->channel < tmp->channel) {
07517                      working->next = tmp;
07518                      tmp->next = NULL;
07519                      tmp->prev = working;
07520                      *wend = tmp;
07521                      break;
07522                   }
07523                }
07524                working = working->next;
07525             }
07526          }
07527       }
07528    }
07529    return tmp;
07530 }
07531 
07532 static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
07533 {
07534    int res;
07535    ZT_PARAMS par;
07536 
07537    /* First, check group matching */
07538    if (groupmatch) {
07539       if ((p->group & groupmatch) != groupmatch)
07540          return 0;
07541       *groupmatched = 1;
07542    }
07543    /* Check to see if we have a channel match */
07544    if (channelmatch != -1) {
07545       if (p->channel != channelmatch)
07546          return 0;
07547       *channelmatched = 1;
07548    }
07549    /* We're at least busy at this point */
07550    if (busy) {
07551       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07552          *busy = 1;
07553    }
07554    /* If do not disturb, definitely not */
07555    if (p->dnd)
07556       return 0;
07557    /* If guard time, definitely not */
07558    if (p->guardtime && (time(NULL) < p->guardtime)) 
07559       return 0;
07560       
07561    /* If no owner definitely available */
07562    if (!p->owner) {
07563 #ifdef HAVE_PRI
07564       /* Trust PRI */
07565       if (p->pri) {
07566          if (p->resetting || p->call)
07567             return 0;
07568          else
07569             return 1;
07570       }
07571 #endif
07572       if (!(p->radio || (p->oprmode < 0)))
07573       {
07574          if (!p->sig || (p->sig == SIG_FXSLS))
07575             return 1;
07576          /* Check hook state */
07577          if (p->subs[SUB_REAL].zfd > -1)
07578             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07579          else {
07580             /* Assume not off hook on CVRS */
07581             res = 0;
07582             par.rxisoffhook = 0;
07583          }
07584          if (res) {
07585             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07586          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07587             /* When "onhook" that means no battery on the line, and thus
07588               it is out of service..., if it's on a TDM card... If it's a channel
07589               bank, there is no telling... */
07590             if (par.rxbits > -1)
07591                return 1;
07592             if (par.rxisoffhook)
07593                return 1;
07594             else
07595 #ifdef ZAP_CHECK_HOOKSTATE
07596                return 0;
07597 #else
07598                return 1;
07599 #endif
07600          } else if (par.rxisoffhook) {
07601             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07602             /* Not available when the other end is off hook */
07603             return 0;
07604          }
07605       }
07606       return 1;
07607    }
07608 
07609    /* If it's not an FXO, forget about call wait */
07610    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07611       return 0;
07612 
07613    if (!p->callwaiting) {
07614       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07615       return 0;
07616    }
07617 
07618    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07619       /* If there is already a call waiting call, then we can't take a second one */
07620       return 0;
07621    }
07622    
07623    if ((p->owner->_state != AST_STATE_UP) &&
07624        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07625       /* If the current call is not up, then don't allow the call */
07626       return 0;
07627    }
07628    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07629       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07630       return 0;
07631    }
07632    /* We're cool */
07633    return 1;
07634 }
07635 
07636 static struct zt_pvt *chandup(struct zt_pvt *src)
07637 {
07638    struct zt_pvt *p;
07639    ZT_BUFFERINFO bi;
07640    int res;
07641    
07642    if ((p = ast_malloc(sizeof(*p)))) {
07643       memcpy(p, src, sizeof(struct zt_pvt));
07644       ast_mutex_init(&p->lock);
07645       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07646       /* Allocate a zapata structure */
07647       if (p->subs[SUB_REAL].zfd < 0) {
07648          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07649          destroy_zt_pvt(&p);
07650          return NULL;
07651       }
07652       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07653       if (!res) {
07654          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07655          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07656          bi.numbufs = numbufs;
07657          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07658          if (res < 0) {
07659             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07660          }
07661       } else
07662          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07663    }
07664    p->destroy = 1;
07665    p->next = iflist;
07666    iflist = p;
07667    return p;
07668 }
07669    
07670 
07671 #ifdef HAVE_PRI
07672 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
07673 {
07674    int x;
07675    if (backwards)
07676       x = pri->numchans;
07677    else
07678       x = 0;
07679    for (;;) {
07680       if (backwards && (x < 0))
07681          break;
07682       if (!backwards && (x >= pri->numchans))
07683          break;
07684       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
07685          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
07686             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
07687          return x;
07688       }
07689       if (backwards)
07690          x--;
07691       else
07692          x++;
07693    }
07694    return -1;
07695 }
07696 #endif
07697 
07698 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
07699 {
07700    int groupmatch = 0;
07701    int channelmatch = -1;
07702    int roundrobin = 0;
07703    int callwait = 0;
07704    int busy = 0;
07705    struct zt_pvt *p;
07706    struct ast_channel *tmp = NULL;
07707    char *dest=NULL;
07708    int x;
07709    char *s;
07710    char opt=0;
07711    int res=0, y=0;
07712    int backwards = 0;
07713 #ifdef HAVE_PRI
07714    int crv;
07715    int bearer = -1;
07716    int trunkgroup;
07717    struct zt_pri *pri=NULL;
07718 #endif   
07719    struct zt_pvt *exit, *start, *end;
07720    ast_mutex_t *lock;
07721    int channelmatched = 0;
07722    int groupmatched = 0;
07723    
07724    /* Assume we're locking the iflock */
07725    lock = &iflock;
07726    start = iflist;
07727    end = ifend;
07728    if (data) {
07729       dest = ast_strdupa((char *)data);
07730    } else {
07731       ast_log(LOG_WARNING, "Channel requested with no data\n");
07732       return NULL;
07733    }
07734    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07735       /* Retrieve the group number */
07736       char *stringp=NULL;
07737       stringp=dest + 1;
07738       s = strsep(&stringp, "/");
07739       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07740          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07741          return NULL;
07742       }
07743       groupmatch = 1 << x;
07744       if (toupper(dest[0]) == 'G') {
07745          if (dest[0] == 'G') {
07746             backwards = 1;
07747             p = ifend;
07748          } else
07749             p = iflist;
07750       } else {
07751          if (dest[0] == 'R') {
07752             backwards = 1;
07753             p = round_robin[x]?round_robin[x]->prev:ifend;
07754             if (!p)
07755                p = ifend;
07756          } else {
07757             p = round_robin[x]?round_robin[x]->next:iflist;
07758             if (!p)
07759                p = iflist;
07760          }
07761          roundrobin = 1;
07762       }
07763    } else {
07764       char *stringp=NULL;
07765       stringp=dest;
07766       s = strsep(&stringp, "/");
07767       p = iflist;
07768       if (!strcasecmp(s, "pseudo")) {
07769          /* Special case for pseudo */
07770          x = CHAN_PSEUDO;
07771          channelmatch = x;
07772       } 
07773 #ifdef HAVE_PRI
07774       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07775          if ((trunkgroup < 1) || (crv < 1)) {
07776             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07777             return NULL;
07778          }
07779          res--;
07780          for (x = 0; x < NUM_SPANS; x++) {
07781             if (pris[x].trunkgroup == trunkgroup) {
07782                pri = pris + x;
07783                lock = &pri->lock;
07784                start = pri->crvs;
07785                end = pri->crvend;
07786                break;
07787             }
07788          }
07789          if (!pri) {
07790             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07791             return NULL;
07792          }
07793          channelmatch = crv;
07794          p = pris[x].crvs;
07795       }
07796 #endif   
07797       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07798          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07799          return NULL;
07800       } else {
07801          channelmatch = x;
07802       }
07803    }
07804    /* Search for an unowned channel */
07805    ast_mutex_lock(lock);
07806    exit = p;
07807    while (p && !tmp) {
07808       if (roundrobin)
07809          round_robin[x] = p;
07810 #if 0
07811       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07812 #endif
07813 
07814       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07815          if (option_debug)
07816             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07817             if (p->inalarm) 
07818                goto next;
07819 
07820          callwait = (p->owner != NULL);
07821 #ifdef HAVE_PRI
07822          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07823             if (p->sig != SIG_FXSKS) {
07824                /* Gotta find an actual channel to use for this
07825                   CRV if this isn't a callwait */
07826                bearer = pri_find_empty_chan(pri, 0);
07827                if (bearer < 0) {
07828                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07829                   p = NULL;
07830                   break;
07831                }
07832                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07833             } else {
07834                if (alloc_sub(p, 0)) {
07835                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07836                   p = NULL;
07837                   break;
07838                } else
07839                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07840                p->pri = pri;
07841             }
07842          }
07843 #endif         
07844          if (p->channel == CHAN_PSEUDO) {
07845             p = chandup(p);
07846             if (!p) {
07847                break;
07848             }
07849          }
07850          if (p->owner) {
07851             if (alloc_sub(p, SUB_CALLWAIT)) {
07852                p = NULL;
07853                break;
07854             }
07855          }
07856          p->outgoing = 1;
07857          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07858 #ifdef HAVE_PRI
07859          if (p->bearer) {
07860             /* Log owner to bearer channel, too */
07861             p->bearer->owner = tmp;
07862          }
07863 #endif         
07864          /* Make special notes */
07865          if (res > 1) {
07866             if (opt == 'c') {
07867                /* Confirm answer */
07868                p->confirmanswer = 1;
07869             } else if (opt == 'r') {
07870                /* Distinctive ring */
07871                if (res < 3)
07872                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07873                else
07874                   p->distinctivering = y;
07875             } else if (opt == 'd') {
07876                /* If this is an ISDN call, make it digital */
07877                p->digital = 1;
07878                if (tmp)
07879                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07880             } else {
07881                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07882             }
07883          }
07884          /* Note if the call is a call waiting call */
07885          if (tmp && callwait)
07886             tmp->cdrflags |= AST_CDR_CALLWAIT;
07887          break;
07888       }
07889 next:
07890       if (backwards) {
07891          p = p->prev;
07892          if (!p)
07893             p = end;
07894       } else {
07895          p = p->next;
07896          if (!p)
07897             p = start;
07898       }
07899       /* stop when you roll to the one that we started from */
07900       if (p == exit)
07901          break;
07902    }
07903    ast_mutex_unlock(lock);
07904    restart_monitor();
07905    if (callwait)
07906       *cause = AST_CAUSE_BUSY;
07907    else if (!tmp) {
07908       if (channelmatched) {
07909          if (busy)
07910             *cause = AST_CAUSE_BUSY;
07911       } else if (groupmatched) {
07912          *cause = AST_CAUSE_CONGESTION;
07913       }
07914    }
07915       
07916    return tmp;
07917 }
07918 
07919 
07920 #ifdef HAVE_PRI
07921 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
07922 {
07923    struct zt_pvt *p;
07924    p = pri->crvs;
07925    while (p) {
07926       if (p->channel == crv)
07927          return p;
07928       p = p->next;
07929    }
07930    return NULL;
07931 }
07932 
07933 
07934 static int pri_find_principle(struct zt_pri *pri, int channel)
07935 {
07936    int x;
07937    int span = PRI_SPAN(channel);
07938    int spanfd;
07939    ZT_PARAMS param;
07940    int principle = -1;
07941    int explicit = PRI_EXPLICIT(channel);
07942    channel = PRI_CHANNEL(channel);
07943 
07944    if (!explicit) {
07945       spanfd = pri_active_dchan_fd(pri);
07946       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
07947          return -1;
07948       span = pris[param.spanno - 1].prilogicalspan;
07949    }
07950 
07951    for (x = 0; x < pri->numchans; x++) {
07952       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
07953          principle = x;
07954          break;
07955       }
07956    }
07957    
07958    return principle;
07959 }
07960 
07961 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
07962 {
07963    int x;
07964    struct zt_pvt *crv;
07965    if (!c) {
07966       if (principle < 0)
07967          return -1;
07968       return principle;
07969    }
07970    if ((principle > -1) && 
07971       (principle < pri->numchans) && 
07972       (pri->pvts[principle]) && 
07973       (pri->pvts[principle]->call == c))
07974       return principle;
07975    /* First, check for other bearers */
07976    for (x = 0; x < pri->numchans; x++) {
07977       if (!pri->pvts[x])
07978          continue;
07979       if (pri->pvts[x]->call == c) {
07980          /* Found our call */
07981          if (principle != x) {
07982             if (option_verbose > 2)
07983                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
07984                   pri->pvts[x]->channel, pri->pvts[principle]->channel);
07985             if (pri->pvts[principle]->owner) {
07986                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
07987                   pri->pvts[x]->channel, pri->pvts[principle]->channel, pri->pvts[principle]->channel);
07988                return -1;
07989             }
07990             /* Fix it all up now */
07991             pri->pvts[principle]->owner = pri->pvts[x]->owner;
07992             if (pri->pvts[principle]->owner) {
07993                ast_string_field_build(pri->pvts[principle]->owner, name, 
07994                             "Zap/%d:%d-%d", pri->trunkgroup,
07995                             pri->pvts[principle]->channel, 1);
07996                pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
07997                pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
07998                pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
07999             } else
08000                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);
08001             pri->pvts[principle]->call = pri->pvts[x]->call;
08002             /* Free up the old channel, now not in use */
08003             pri->pvts[x]->subs[SUB_REAL].owner = NULL;
08004             pri->pvts[x]->owner = NULL;
08005             pri->pvts[x]->call = NULL;
08006          }
08007          return principle;
08008       }
08009    }
08010    /* Now check for a CRV with no bearer */
08011    crv = pri->crvs;
08012    while (crv) {
08013       if (crv->call == c) {
08014          /* This is our match...  Perform some basic checks */
08015          if (crv->bearer)
08016             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08017          else if (pri->pvts[principle]->owner) 
08018             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08019          else {
08020             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08021                wakeup the potential sleeper */
08022             zt_close(crv->subs[SUB_REAL].zfd);
08023             pri->pvts[principle]->call = crv->call;
08024             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08025             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08026                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08027                            pri->trunkgroup, crv->channel);
08028             wakeup_sub(crv, SUB_REAL, pri);
08029          }
08030          return principle;
08031       }
08032       crv = crv->next;
08033    }
08034    ast_log(LOG_WARNING, "Call specified, but not found?\n");
08035    return -1;
08036 }
08037 
08038 static void *do_idle_thread(void *vchan)
08039 {
08040    struct ast_channel *chan = vchan;
08041    struct zt_pvt *pvt = chan->tech_pvt;
08042    struct ast_frame *f;
08043    char ex[80];
08044    /* Wait up to 30 seconds for an answer */
08045    int newms, ms = 30000;
08046    if (option_verbose > 2) 
08047       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08048    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08049    if (ast_call(chan, ex, 0)) {
08050       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08051       ast_hangup(chan);
08052       return NULL;
08053    }
08054    while ((newms = ast_waitfor(chan, ms)) > 0) {
08055       f = ast_read(chan);
08056       if (!f) {
08057          /* Got hangup */
08058          break;
08059       }
08060       if (f->frametype == AST_FRAME_CONTROL) {
08061          switch (f->subclass) {
08062          case AST_CONTROL_ANSWER:
08063             /* Launch the PBX */
08064             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08065             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08066             chan->priority = 1;
08067             if (option_verbose > 3) 
08068                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08069             ast_pbx_run(chan);
08070             /* It's already hungup, return immediately */
08071             return NULL;
08072          case AST_CONTROL_BUSY:
08073             if (option_verbose > 3) 
08074                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08075             break;
08076          case AST_CONTROL_CONGESTION:
08077             if (option_verbose > 3) 
08078                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08079             break;
08080          };
08081       }
08082       ast_frfree(f);
08083       ms = newms;
08084    }
08085    /* Hangup the channel since nothing happend */
08086    ast_hangup(chan);
08087    return NULL;
08088 }
08089 
08090 #ifndef PRI_RESTART
08091 #error "Upgrade your libpri"
08092 #endif
08093 static void zt_pri_message(struct pri *pri, char *s)
08094 {
08095    int x, y;
08096    int dchan = -1, span = -1;
08097    int dchancount = 0;
08098 
08099    if (pri) {
08100       for (x = 0; x < NUM_SPANS; x++) {
08101          for (y = 0; y < NUM_DCHANS; y++) {
08102             if (pris[x].dchans[y])
08103                dchancount++;
08104 
08105             if (pris[x].dchans[y] == pri)
08106                dchan = y;
08107          }
08108          if (dchan >= 0) {
08109             span = x;
08110             break;
08111          }
08112          dchancount = 0;
08113       }
08114       if ((dchan >= 0) && (span >= 0)) {
08115          if (dchancount > 1)
08116             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
08117          else
08118             ast_verbose("%s", s);
08119       } else
08120          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08121    } else
08122       ast_verbose("%s", s);
08123 
08124    ast_mutex_lock(&pridebugfdlock);
08125 
08126    if (pridebugfd >= 0)
08127       write(pridebugfd, s, strlen(s));
08128 
08129    ast_mutex_unlock(&pridebugfdlock);
08130 }
08131 
08132 static void zt_pri_error(struct pri *pri, char *s)
08133 {
08134    int x, y;
08135    int dchan = -1, span = -1;
08136    int dchancount = 0;
08137 
08138    if (pri) {
08139       for (x = 0; x < NUM_SPANS; x++) {
08140          for (y = 0; y < NUM_DCHANS; y++) {
08141             if (pris[x].dchans[y])
08142                dchancount++;
08143 
08144             if (pris[x].dchans[y] == pri)
08145                dchan = y;
08146          }
08147          if (dchan >= 0) {
08148             span = x;
08149             break;
08150          }
08151          dchancount = 0;
08152       }
08153       if ((dchan >= 0) && (span >= 0)) {
08154          if (dchancount > 1)
08155             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
08156          else
08157             ast_log(LOG_ERROR, "%s", s);
08158       } else
08159          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08160    } else
08161       ast_log(LOG_ERROR, "%s", s);
08162 
08163    ast_mutex_lock(&pridebugfdlock);
08164 
08165    if (pridebugfd >= 0)
08166       write(pridebugfd, s, strlen(s));
08167 
08168    ast_mutex_unlock(&pridebugfdlock);
08169 }
08170 
08171 static int pri_check_restart(struct zt_pri *pri)
08172 {
08173    do {
08174       pri->resetpos++;
08175    } while ((pri->resetpos < pri->numchans) &&
08176        (!pri->pvts[pri->resetpos] ||
08177         pri->pvts[pri->resetpos]->call ||
08178         pri->pvts[pri->resetpos]->resetting));
08179    if (pri->resetpos < pri->numchans) {
08180       /* Mark the channel as resetting and restart it */
08181       pri->pvts[pri->resetpos]->resetting = 1;
08182       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08183    } else {
08184       pri->resetting = 0;
08185       time(&pri->lastreset);
08186    }
08187    return 0;
08188 }
08189 
08190 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08191 {
08192    int x;
08193    int redo;
08194    ast_mutex_unlock(&pri->lock);
08195    ast_mutex_lock(&p->lock);
08196    do {
08197       redo = 0;
08198       for (x = 0; x < 3; x++) {
08199          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08200             redo++;
08201             ast_mutex_unlock(&p->lock);
08202             usleep(1);
08203             ast_mutex_lock(&p->lock);
08204          }
08205          if (p->subs[x].owner) {
08206             ast_queue_hangup(p->subs[x].owner);
08207             ast_mutex_unlock(&p->subs[x].owner->lock);
08208          }
08209       }
08210    } while (redo);
08211    ast_mutex_unlock(&p->lock);
08212    ast_mutex_lock(&pri->lock);
08213    return 0;
08214 }
08215 
08216 static char * redirectingreason2str(int redirectingreason)
08217 {
08218    switch (redirectingreason) {
08219    case 0:
08220       return "UNKNOWN";
08221    case 1:
08222       return "BUSY";
08223    case 2:
08224       return "NO_REPLY";
08225    case 0xF:
08226       return "UNCONDITIONAL";
08227    default:
08228       return "NOREDIRECT";
08229    }
08230 }
08231 
08232 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08233 {
08234    switch (plan) {
08235    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08236       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08237       break;
08238    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08239       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08240       break;
08241    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08242       snprintf(buf, size, "%s%s", pri->localprefix, number);
08243       break;
08244    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08245       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08246       break;
08247    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08248       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08249       break;
08250    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08251       snprintf(buf, size, "%s", number);
08252       break;
08253    }
08254 }
08255 
08256 static int zt_setlaw(int zfd, int law)
08257 {
08258    int res;
08259    res = ioctl(zfd, ZT_SETLAW, &law);
08260    if (res)
08261       return res;
08262    return 0;
08263 }
08264 
08265 static void *pri_dchannel(void *vpri)
08266 {
08267    struct zt_pri *pri = vpri;
08268    pri_event *e;
08269    struct pollfd fds[NUM_DCHANS];
08270    int res;
08271    int chanpos = 0;
08272    int x;
08273    int haveidles;
08274    int activeidles;
08275    int nextidle = -1;
08276    struct ast_channel *c;
08277    struct timeval tv, lowest, *next;
08278    struct timeval lastidle = { 0, 0 };
08279    int doidling=0;
08280    char *cc;
08281    char idlen[80];
08282    struct ast_channel *idle;
08283    pthread_t p;
08284    time_t t;
08285    int i, which=-1;
08286    int numdchans;
08287    int cause=0;
08288    struct zt_pvt *crv;
08289    pthread_t threadid;
08290    pthread_attr_t attr;
08291    char ani2str[6];
08292    char plancallingnum[256];
08293    char plancallingani[256];
08294    char calledtonstr[10];
08295    
08296    gettimeofday(&lastidle, NULL);
08297    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08298       /* Need to do idle dialing, check to be sure though */
08299       cc = strchr(pri->idleext, '@');
08300       if (cc) {
08301          *cc = '\0';
08302          cc++;
08303          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08304 #if 0
08305          /* Extensions may not be loaded yet */
08306          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08307             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08308          else
08309 #endif
08310             doidling = 1;
08311       } else
08312          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08313    }
08314    for (;;) {
08315       for (i = 0; i < NUM_DCHANS; i++) {
08316          if (!pri->dchannels[i])
08317             break;
08318          fds[i].fd = pri->fds[i];
08319          fds[i].events = POLLIN | POLLPRI;
08320          fds[i].revents = 0;
08321       }
08322       numdchans = i;
08323       time(&t);
08324       ast_mutex_lock(&pri->lock);
08325       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08326          if (pri->resetting && pri_is_up(pri)) {
08327             if (pri->resetpos < 0)
08328                pri_check_restart(pri);
08329          } else {
08330             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08331                pri->resetting = 1;
08332                pri->resetpos = -1;
08333             }
08334          }
08335       }
08336       /* Look for any idle channels if appropriate */
08337       if (doidling && pri_is_up(pri)) {
08338          nextidle = -1;
08339          haveidles = 0;
08340          activeidles = 0;
08341          for (x = pri->numchans; x >= 0; x--) {
08342             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08343                 !pri->pvts[x]->call) {
08344                if (haveidles < pri->minunused) {
08345                   haveidles++;
08346                } else if (!pri->pvts[x]->resetting) {
08347                   nextidle = x;
08348                   break;
08349                }
08350             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08351                activeidles++;
08352          }
08353          if (nextidle > -1) {
08354             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08355                /* Don't create a new idle call more than once per second */
08356                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08357                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08358                if (idle) {
08359                   pri->pvts[nextidle]->isidlecall = 1;
08360                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08361                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08362                      zt_hangup(idle);
08363                   }
08364                } else
08365                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08366                gettimeofday(&lastidle, NULL);
08367             }
08368          } else if ((haveidles < pri->minunused) &&
08369                (activeidles > pri->minidle)) {
08370             /* Mark something for hangup if there is something 
08371                that can be hungup */
08372             for (x = pri->numchans; x >= 0; x--) {
08373                /* find a candidate channel */
08374                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08375                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08376                   haveidles++;
08377                   /* Stop if we have enough idle channels or
08378                     can't spare any more active idle ones */
08379                   if ((haveidles >= pri->minunused) ||
08380                       (activeidles <= pri->minidle))
08381                      break;
08382                } 
08383             }
08384          }
08385       }
08386       /* Start with reasonable max */
08387       lowest = ast_tv(60, 0);
08388       for (i = 0; i < NUM_DCHANS; i++) {
08389          /* Find lowest available d-channel */
08390          if (!pri->dchannels[i])
08391             break;
08392          if ((next = pri_schedule_next(pri->dchans[i]))) {
08393             /* We need relative time here */
08394             tv = ast_tvsub(*next, ast_tvnow());
08395             if (tv.tv_sec < 0) {
08396                tv = ast_tv(0,0);
08397             }
08398             if (doidling || pri->resetting) {
08399                if (tv.tv_sec > 1) {
08400                   tv = ast_tv(1, 0);
08401                }
08402             } else {
08403                if (tv.tv_sec > 60) {
08404                   tv = ast_tv(60, 0);
08405                }
08406             }
08407          } else if (doidling || pri->resetting) {
08408             /* Make sure we stop at least once per second if we're
08409                monitoring idle channels */
08410             tv = ast_tv(1,0);
08411          } else {
08412             /* Don't poll for more than 60 seconds */
08413             tv = ast_tv(60, 0);
08414          }
08415          if (!i || ast_tvcmp(tv, lowest) < 0) {
08416             lowest = tv;
08417          }
08418       }
08419       ast_mutex_unlock(&pri->lock);
08420 
08421       e = NULL;
08422       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
08423 
08424       ast_mutex_lock(&pri->lock);
08425       if (!res) {
08426          for (which = 0; which < NUM_DCHANS; which++) {
08427             if (!pri->dchans[which])
08428                break;
08429             /* Just a timeout, run the scheduler */
08430             e = pri_schedule_run(pri->dchans[which]);
08431             if (e)
08432                break;
08433          }
08434       } else if (res > -1) {
08435          for (which = 0; which < NUM_DCHANS; which++) {
08436             if (!pri->dchans[which])
08437                break;
08438             if (fds[which].revents & POLLPRI) {
08439                /* Check for an event */
08440                x = 0;
08441                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
08442                if (x) 
08443                   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);
08444                /* Keep track of alarm state */  
08445                if (x == ZT_EVENT_ALARM) {
08446                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
08447                   pri_find_dchan(pri);
08448                } else if (x == ZT_EVENT_NOALARM) {
08449                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
08450                   pri_restart(pri->dchans[which]);
08451                }
08452             
08453                if (option_debug)
08454                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
08455             } else if (fds[which].revents & POLLIN) {
08456                e = pri_check_event(pri->dchans[which]);
08457             }
08458             if (e)
08459                break;
08460          }
08461       } else if (errno != EINTR)
08462          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
08463 
08464       if (e) {
08465          if (pri->debug)
08466             pri_dump_event(pri->dchans[which], e);
08467          if (e->e != PRI_EVENT_DCHAN_DOWN)
08468             pri->dchanavail[which] |= DCHAN_UP;
08469 
08470          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
08471             /* Must be an NFAS group that has the secondary dchan active */
08472             pri->pri = pri->dchans[which];
08473 
08474          switch (e->e) {
08475          case PRI_EVENT_DCHAN_UP:
08476             if (option_verbose > 1) 
08477                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
08478             pri->dchanavail[which] |= DCHAN_UP;
08479             if (!pri->pri) pri_find_dchan(pri);
08480 
08481             /* Note presense of D-channel */
08482             time(&pri->lastreset);
08483 
08484             /* Restart in 5 seconds */
08485             if (pri->resetinterval > -1) {
08486                pri->lastreset -= pri->resetinterval;
08487                pri->lastreset += 5;
08488             }
08489             pri->resetting = 0;
08490             /* Take the channels from inalarm condition */
08491             for (i = 0; i < pri->numchans; i++)
08492                if (pri->pvts[i]) {
08493                   pri->pvts[i]->inalarm = 0;
08494                }
08495             break;
08496          case PRI_EVENT_DCHAN_DOWN:
08497             if (option_verbose > 1) 
08498                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
08499             pri->dchanavail[which] &= ~DCHAN_UP;
08500             pri_find_dchan(pri);
08501             if (!pri_is_up(pri)) {
08502                pri->resetting = 0;
08503                /* Hangup active channels and put them in alarm mode */
08504                for (i = 0; i < pri->numchans; i++) {
08505                   struct zt_pvt *p = pri->pvts[i];
08506                   if (p) {
08507                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08508                         /* T309 is not enabled : hangup calls when alarm occurs */
08509                         if (p->call) {
08510                            if (p->pri && p->pri->pri) {
08511                               pri_hangup(p->pri->pri, p->call, -1);
08512                               pri_destroycall(p->pri->pri, p->call);
08513                               p->call = NULL;
08514                            } else
08515                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
08516                         }
08517                         if (p->realcall) {
08518                            pri_hangup_all(p->realcall, pri);
08519                         } else if (p->owner)
08520                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08521                      }
08522                      p->inalarm = 1;
08523                   }
08524                }
08525             }
08526             break;
08527          case PRI_EVENT_RESTART:
08528             if (e->restart.channel > -1) {
08529                chanpos = pri_find_principle(pri, e->restart.channel);
08530                if (chanpos < 0)
08531                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
08532                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08533                else {
08534                   if (option_verbose > 2)
08535                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
08536                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08537                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08538                   if (pri->pvts[chanpos]->call) {
08539                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
08540                      pri->pvts[chanpos]->call = NULL;
08541                   }
08542                   /* Force soft hangup if appropriate */
08543                   if (pri->pvts[chanpos]->realcall) 
08544                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08545                   else if (pri->pvts[chanpos]->owner)
08546                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08547                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08548                }
08549             } else {
08550                if (option_verbose > 2)
08551                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
08552                for (x = 0; x < pri->numchans; x++)
08553                   if (pri->pvts[x]) {
08554                      ast_mutex_lock(&pri->pvts[x]->lock);
08555                      if (pri->pvts[x]->call) {
08556                         pri_destroycall(pri->pri, pri->pvts[x]->call);
08557                         pri->pvts[x]->call = NULL;
08558                      }
08559                      if (pri->pvts[chanpos]->realcall) 
08560                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08561                      else if (pri->pvts[x]->owner)
08562                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08563                      ast_mutex_unlock(&pri->pvts[x]->lock);
08564                   }
08565             }
08566             break;
08567          case PRI_EVENT_KEYPAD_DIGIT:
08568             chanpos = pri_find_principle(pri, e->digit.channel);
08569             if (chanpos < 0) {
08570                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
08571                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
08572             } else {
08573                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
08574                if (chanpos > -1) {
08575                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08576                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
08577                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
08578                      /* how to do that */
08579                      int digitlen = strlen(e->digit.digits);
08580                      char digit;
08581                      int i;               
08582                      for (i = 0; i < digitlen; i++) { 
08583                         digit = e->digit.digits[i];
08584                         {
08585                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08586                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08587                         }
08588                      }
08589                   }
08590                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08591                }
08592             }
08593             break;
08594             
08595          case PRI_EVENT_INFO_RECEIVED:
08596             chanpos = pri_find_principle(pri, e->ring.channel);
08597             if (chanpos < 0) {
08598                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
08599                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08600             } else {
08601                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
08602                if (chanpos > -1) {
08603                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08604                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
08605                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
08606                      /* how to do that */
08607                      int digitlen = strlen(e->ring.callednum);
08608                      char digit;
08609                      int i;               
08610                      for (i = 0; i < digitlen; i++) { 
08611                         digit = e->ring.callednum[i];
08612                         {
08613                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08614                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08615                         }
08616                      }
08617                   }
08618                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08619                }
08620             }
08621             break;
08622          case PRI_EVENT_RING:
08623             crv = NULL;
08624             if (e->ring.channel == -1)
08625                chanpos = pri_find_empty_chan(pri, 1);
08626             else
08627                chanpos = pri_find_principle(pri, e->ring.channel);
08628             /* if no channel specified find one empty */
08629             if (chanpos < 0) {
08630                ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 
08631                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08632             } else {
08633                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08634                if (pri->pvts[chanpos]->owner) {
08635                   if (pri->pvts[chanpos]->call == e->ring.call) {
08636                      ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
08637                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08638                      break;
08639                   } else {
08640                      /* This is where we handle initial glare */
08641                      ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiating channel.\n", 
08642                      PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08643                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08644                      chanpos = -1;
08645                   }
08646                }
08647                if (chanpos > -1)
08648                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08649             }
08650             if ((chanpos < 0) && (e->ring.flexible))
08651                chanpos = pri_find_empty_chan(pri, 1);
08652             if (chanpos > -1) {
08653                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08654                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
08655                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
08656                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
08657                   if (crv)
08658                      ast_mutex_lock(&crv->lock);
08659                   if (!crv || crv->owner) {
08660                      pri->pvts[chanpos]->call = NULL;
08661                      if (crv) {
08662                         if (crv->owner)
08663                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08664                         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);
08665                      } else
08666                         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);
08667                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
08668                      if (crv)
08669                         ast_mutex_unlock(&crv->lock);
08670                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08671                      break;
08672                   }
08673                }
08674                pri->pvts[chanpos]->call = e->ring.call;
08675                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
08676                if (pri->pvts[chanpos]->use_callerid) {
08677                   ast_shrink_phone_number(plancallingnum);
08678                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
08679 #ifdef PRI_ANI
08680                   if (!ast_strlen_zero(e->ring.callingani)) {
08681                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
08682                      ast_shrink_phone_number(plancallingani);
08683                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
08684                   } else {
08685                      pri->pvts[chanpos]->cid_ani[0] = '\0';
08686                   }
08687 #endif
08688                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
08689                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
08690                } else {
08691                   pri->pvts[chanpos]->cid_num[0] = '\0';
08692                   pri->pvts[chanpos]->cid_ani[0] = '\0';
08693                   pri->pvts[chanpos]->cid_name[0] = '\0';
08694                   pri->pvts[chanpos]->cid_ton = 0;
08695                }
08696                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
08697                           e->ring.redirectingnum, e->ring.callingplanrdnis);
08698                /* If immediate=yes go to s|1 */
08699                if (pri->pvts[chanpos]->immediate) {
08700                   if (option_verbose > 2)
08701                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
08702                   pri->pvts[chanpos]->exten[0] = 's';
08703                   pri->pvts[chanpos]->exten[1] = '\0';
08704                }
08705                /* Get called number */
08706                else if (!ast_strlen_zero(e->ring.callednum)) {
08707                   ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
08708                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08709                } else
08710                   pri->pvts[chanpos]->exten[0] = '\0';
08711                /* Set DNID on all incoming calls -- even immediate */
08712                if (!ast_strlen_zero(e->ring.callednum))
08713                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08714                /* No number yet, but received "sending complete"? */
08715                if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
08716                   if (option_verbose > 2)
08717                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
08718                   pri->pvts[chanpos]->exten[0] = 's';
08719                   pri->pvts[chanpos]->exten[1] = '\0';
08720                }
08721                /* Make sure extension exists (or in overlap dial mode, can exist) */
08722                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
08723                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08724                   /* Setup law */
08725                   int law;
08726                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
08727                      /* Set to audio mode at this point */
08728                      law = 1;
08729                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08730                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
08731                   }
08732                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
08733                      law = ZT_LAW_ALAW;
08734                   else
08735                      law = ZT_LAW_MULAW;
08736                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
08737                   if (res < 0) 
08738                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
08739                   res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
08740                   if (res < 0)
08741                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
08742                   if (e->ring.complete || !pri->overlapdial) {
08743                      /* Just announce proceeding */
08744                      pri->pvts[chanpos]->proceeding = 1;
08745                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
08746                   } else {
08747                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
08748                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08749                      else
08750                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08751                   }
08752                   /* Get the use_callingpres state */
08753                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
08754                
08755                   /* Start PBX */
08756                   if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08757                      /* Release the PRI lock while we create the channel */
08758                      ast_mutex_unlock(&pri->lock);
08759                      if (crv) {
08760                         /* Set bearer and such */
08761                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
08762                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08763                         pri->pvts[chanpos]->owner = &inuse;
08764                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
08765                      } else {
08766                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08767                      }
08768                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
08769                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
08770                      }
08771                      if (e->ring.ani2 >= 0) {
08772                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
08773                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08774                      }
08775 
08776 #ifdef SUPPORT_USERUSER
08777                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
08778                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08779                      }
08780 #endif
08781 
08782                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08783                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08784                      if (e->ring.redirectingreason >= 0)
08785                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08786                      
08787                      ast_mutex_lock(&pri->lock);
08788                      pthread_attr_init(&attr);
08789                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08790                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
08791                         if (option_verbose > 2)
08792                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
08793                               plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
08794                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08795                      } else {
08796                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08797                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08798                         if (c)
08799                            ast_hangup(c);
08800                         else {
08801                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08802                            pri->pvts[chanpos]->call = NULL;
08803                         }
08804                      }
08805                      pthread_attr_destroy(&attr);
08806                   } else  {
08807                      ast_mutex_unlock(&pri->lock);
08808                      /* Release PRI lock while we create the channel */
08809                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
08810                      ast_mutex_lock(&pri->lock);
08811                      if (c) {
08812                         char calledtonstr[10];
08813                         if (e->ring.ani2 >= 0) {
08814                            snprintf(ani2str, 5, "%d", e->ring.ani2);
08815                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08816                         }
08817 
08818 #ifdef SUPPORT_USERUSER
08819                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
08820                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08821                         }
08822 #endif
08823 
08824                         if (e->ring.redirectingreason >= 0)
08825                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08826                      
08827                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08828                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08829                         if (option_verbose > 2)
08830                            ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
08831                               plancallingnum, pri->pvts[chanpos]->exten, 
08832                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08833                         zt_enable_ec(pri->pvts[chanpos]);
08834                      } else {
08835                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08836                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08837                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08838                         pri->pvts[chanpos]->call = NULL;
08839                      }
08840                   }
08841                } else {
08842                   if (option_verbose > 2)
08843                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
08844                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
08845                            pri->pvts[chanpos]->prioffset, pri->span);
08846                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
08847                   pri->pvts[chanpos]->call = NULL;
08848                   pri->pvts[chanpos]->exten[0] = '\0';
08849                }
08850                if (crv)
08851                   ast_mutex_unlock(&crv->lock);
08852                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08853             } else {
08854                if (e->ring.flexible)
08855                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
08856                else
08857                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
08858             }
08859             break;
08860          case PRI_EVENT_RINGING:
08861             chanpos = pri_find_principle(pri, e->ringing.channel);
08862             if (chanpos < 0) {
08863                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
08864                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08865             } else {
08866                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
08867                if (chanpos < 0) {
08868                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
08869                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08870                } else {
08871                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08872                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
08873                      zt_enable_ec(pri->pvts[chanpos]);
08874                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
08875                      pri->pvts[chanpos]->alerting = 1;
08876                   } else
08877                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
08878 #ifdef PRI_PROGRESS_MASK
08879                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08880 #else
08881                   if (e->ringing.progress == 8) {
08882 #endif
08883                      /* Now we can do call progress detection */
08884                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08885                         /* RINGING detection isn't required because we got ALERTING signal */
08886                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
08887                         pri->pvts[chanpos]->dsp_features = 0;
08888                      }
08889                   }
08890 
08891 #ifdef SUPPORT_USERUSER
08892                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
08893                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->ringing.useruserinfo);
08894                   }
08895 #endif
08896 
08897                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08898                }
08899             }
08900             break;
08901          case PRI_EVENT_PROGRESS:
08902             /* Get chan value if e->e is not PRI_EVNT_RINGING */
08903             chanpos = pri_find_principle(pri, e->proceeding.channel);
08904             if (chanpos > -1) {
08905 #ifdef PRI_PROGRESS_MASK
08906                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
08907 #else
08908                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
08909 #endif
08910                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
08911 
08912                   if (e->proceeding.cause > -1) {
08913                      if (option_verbose > 2)
08914                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
08915 
08916                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
08917                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
08918                         if (pri->pvts[chanpos]->owner) {
08919                            if (option_verbose > 2)
08920                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
08921 
08922                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
08923                            f.subclass = AST_CONTROL_BUSY;
08924                         }
08925                      }
08926                   }
08927                   
08928                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08929                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
08930                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08931                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08932 #ifdef PRI_PROGRESS_MASK
08933                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08934 #else
08935                   if (e->proceeding.progress == 8) {
08936 #endif
08937                      /* Now we can do call progress detection */
08938                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08939                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08940                         pri->pvts[chanpos]->dsp_features = 0;
08941                      }
08942                   }
08943                   pri->pvts[chanpos]->progress = 1;
08944                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08945                }
08946             }
08947             break;
08948          case PRI_EVENT_PROCEEDING:
08949             chanpos = pri_find_principle(pri, e->proceeding.channel);
08950             if (chanpos > -1) {
08951                if (!pri->pvts[chanpos]->proceeding) {
08952                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
08953                   
08954                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08955                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
08956                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
08957                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
08958 #ifdef PRI_PROGRESS_MASK
08959                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08960 #else
08961                   if (e->proceeding.progress == 8) {
08962 #endif
08963                      /* Now we can do call progress detection */
08964                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
08965                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
08966                         pri->pvts[chanpos]->dsp_features = 0;
08967                      }
08968                      /* Bring voice path up */
08969                      f.subclass = AST_CONTROL_PROGRESS;
08970                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
08971                   }
08972                   pri->pvts[chanpos]->proceeding = 1;
08973                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08974                }
08975             }
08976             break;
08977          case PRI_EVENT_FACNAME:
08978             chanpos = pri_find_principle(pri, e->facname.channel);
08979             if (chanpos < 0) {
08980                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
08981                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
08982             } else {
08983                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
08984                if (chanpos < 0) {
08985                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
08986                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
08987                } else {
08988                   /* Re-use *69 field for PRI */
08989                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08990                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
08991                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
08992                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
08993                   zt_enable_ec(pri->pvts[chanpos]);
08994                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08995                }
08996             }
08997             break;            
08998          case PRI_EVENT_ANSWER:
08999             chanpos = pri_find_principle(pri, e->answer.channel);
09000             if (chanpos < 0) {
09001                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09002                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09003             } else {
09004                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09005                if (chanpos < 0) {
09006                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09007                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09008                } else {
09009                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09010                   /* Now we can do call progress detection */
09011 
09012                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09013                    * By this time, we need DTMF detection and other features that were previously disabled
09014                    * -- Matt F */
09015                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09016                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09017                      pri->pvts[chanpos]->dsp_features = 0;
09018                   }
09019                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09020                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09021                      x = ZT_START;
09022                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09023                      if (res < 0) {
09024                         if (errno != EINPROGRESS) {
09025                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09026                         }
09027                      }
09028                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09029                      pri->pvts[chanpos]->dialing = 1;
09030                      /* Send any "w" waited stuff */
09031                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09032                      if (res < 0) {
09033                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09034                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09035                      } else 
09036                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
09037                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09038                   } else if (pri->pvts[chanpos]->confirmanswer) {
09039                      ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
09040                   } else {
09041                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
09042                      /* Enable echo cancellation if it's not on already */
09043                      zt_enable_ec(pri->pvts[chanpos]);
09044                   }
09045 
09046 #ifdef SUPPORT_USERUSER
09047                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
09048                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->answer.useruserinfo);
09049                   }
09050 #endif
09051 
09052                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09053                }
09054             }
09055             break;            
09056          case PRI_EVENT_HANGUP:
09057             chanpos = pri_find_principle(pri, e->hangup.channel);
09058             if (chanpos < 0) {
09059                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
09060                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09061             } else {
09062                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09063                if (chanpos > -1) {
09064                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09065                   if (!pri->pvts[chanpos]->alreadyhungup) {
09066                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
09067                      pri->pvts[chanpos]->alreadyhungup = 1;
09068                      if (pri->pvts[chanpos]->realcall) 
09069                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09070                      else if (pri->pvts[chanpos]->owner) {
09071                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
09072                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09073                         switch (e->hangup.cause) {
09074                         case PRI_CAUSE_USER_BUSY:
09075                            pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09076                            break;
09077                         case PRI_CAUSE_CALL_REJECTED:
09078                         case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09079                         case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09080                         case PRI_CAUSE_SWITCH_CONGESTION:
09081                         case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09082                         case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09083                            pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09084                            break;
09085                         default:
09086                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09087                         }
09088                      }
09089                      if (option_verbose > 2) 
09090                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup\n", 
09091                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09092                   } else {
09093                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09094                      pri->pvts[chanpos]->call = NULL;
09095                   }
09096                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09097                      if (option_verbose > 2)
09098                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
09099                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09100                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09101                      pri->pvts[chanpos]->resetting = 1;
09102                   }
09103                   if (e->hangup.aoc_units > -1)
09104                      if (option_verbose > 2)
09105                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09106                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09107 
09108 #ifdef SUPPORT_USERUSER
09109                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09110                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09111                   }
09112 #endif
09113 
09114                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09115                } else {
09116                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
09117                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09118                }
09119             } 
09120             break;
09121 #ifndef PRI_EVENT_HANGUP_REQ
09122 #error please update libpri
09123 #endif
09124          case PRI_EVENT_HANGUP_REQ:
09125             chanpos = pri_find_principle(pri, e->hangup.channel);
09126             if (chanpos < 0) {
09127                ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
09128                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09129             } else {
09130                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09131                if (chanpos > -1) {
09132                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09133                   if (pri->pvts[chanpos]->realcall) 
09134                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09135                   else if (pri->pvts[chanpos]->owner) {
09136                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09137                      switch (e->hangup.cause) {
09138                      case PRI_CAUSE_USER_BUSY:
09139                         pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09140                         break;
09141                      case PRI_CAUSE_CALL_REJECTED:
09142                      case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09143                      case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09144                      case PRI_CAUSE_SWITCH_CONGESTION:
09145                      case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09146                      case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09147                         pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09148                         break;
09149                      default:
09150                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09151                      }
09152                      if (option_verbose > 2) 
09153                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09154                      if (e->hangup.aoc_units > -1)
09155                         if (option_verbose > 2)
09156                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09157                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09158                   } else {
09159                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09160                      pri->pvts[chanpos]->call = NULL;
09161                   }
09162                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09163                      if (option_verbose > 2)
09164                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
09165                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09166                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09167                      pri->pvts[chanpos]->resetting = 1;
09168                   }
09169 
09170 #ifdef SUPPORT_USERUSER
09171                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09172                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09173                   }
09174 #endif
09175 
09176                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09177                } else {
09178                   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);
09179                }
09180             } 
09181             break;
09182          case PRI_EVENT_HANGUP_ACK:
09183             chanpos = pri_find_principle(pri, e->hangup.channel);
09184             if (chanpos < 0) {
09185                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
09186                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09187             } else {
09188                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09189                if (chanpos > -1) {
09190                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09191                   pri->pvts[chanpos]->call = NULL;
09192                   pri->pvts[chanpos]->resetting = 0;
09193                   if (pri->pvts[chanpos]->owner) {
09194                      if (option_verbose > 2) 
09195                         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);
09196                   }
09197 
09198 #ifdef SUPPORT_USERUSER
09199                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09200                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
09201                   }
09202 #endif
09203 
09204                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09205                }
09206             }
09207             break;
09208          case PRI_EVENT_CONFIG_ERR:
09209             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
09210             break;
09211          case PRI_EVENT_RESTART_ACK:
09212             chanpos = pri_find_principle(pri, e->restartack.channel);
09213             if (chanpos < 0) {
09214                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
09215                   channel number, so we have to figure it out...  This must be why
09216                   everybody resets exactly a channel at a time. */
09217                for (x = 0; x < pri->numchans; x++) {
09218                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
09219                      chanpos = x;
09220                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09221                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
09222                            pri->pvts[chanpos]->prioffset, pri->span);
09223                      if (pri->pvts[chanpos]->realcall) 
09224                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09225                      else if (pri->pvts[chanpos]->owner) {
09226                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
09227                            pri->pvts[chanpos]->prioffset, pri->span);
09228                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09229                      }
09230                      pri->pvts[chanpos]->resetting = 0;
09231                      if (option_verbose > 2)
09232                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09233                            pri->pvts[chanpos]->prioffset, pri->span);
09234                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09235                      if (pri->resetting)
09236                         pri_check_restart(pri);
09237                      break;
09238                   }
09239                }
09240                if (chanpos < 0) {
09241                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
09242                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09243                }
09244             } else {
09245                if (pri->pvts[chanpos]) {
09246                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09247                   if (pri->pvts[chanpos]->realcall) 
09248                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09249                   else if (pri->pvts[chanpos]->owner) {
09250                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
09251                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09252                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09253                   }
09254                   pri->pvts[chanpos]->resetting = 0;
09255                   if (option_verbose > 2)
09256                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09257                            pri->pvts[chanpos]->prioffset, pri->span);
09258                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09259                   if (pri->resetting)
09260                      pri_check_restart(pri);
09261                }
09262             }
09263             break;
09264          case PRI_EVENT_SETUP_ACK:
09265             chanpos = pri_find_principle(pri, e->setup_ack.channel);
09266             if (chanpos < 0) {
09267                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
09268                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
09269             } else {
09270                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
09271                if (chanpos > -1) {
09272                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09273                   pri->pvts[chanpos]->setup_ack = 1;
09274                   /* Send any queued digits */
09275                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
09276                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
09277                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
09278                         pri->pvts[chanpos]->dialdest[x]);
09279                   }
09280                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09281                } else
09282                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
09283             }
09284             break;
09285          case PRI_EVENT_NOTIFY:
09286             chanpos = pri_find_principle(pri, e->notify.channel);
09287             if (chanpos < 0) {
09288                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
09289                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
09290             } else {
09291                struct ast_frame f = { AST_FRAME_CONTROL, };
09292                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09293                switch (e->notify.info) {
09294                case PRI_NOTIFY_REMOTE_HOLD:
09295                   f.subclass = AST_CONTROL_HOLD;
09296                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09297                   break;
09298                case PRI_NOTIFY_REMOTE_RETRIEVAL:
09299                   f.subclass = AST_CONTROL_UNHOLD;
09300                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09301                   break;
09302                }
09303                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09304             }
09305             break;
09306          default:
09307             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
09308          }
09309       }  
09310       ast_mutex_unlock(&pri->lock);
09311    }
09312    /* Never reached */
09313    return NULL;
09314 }
09315 
09316 static int start_pri(struct zt_pri *pri)
09317 {
09318    int res, x;
09319    ZT_PARAMS p;
09320    ZT_BUFFERINFO bi;
09321    struct zt_spaninfo si;
09322    int i;
09323    
09324    for (i = 0; i < NUM_DCHANS; i++) {
09325       if (!pri->dchannels[i])
09326          break;
09327       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
09328       x = pri->dchannels[i];
09329       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
09330          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
09331          return -1;
09332       }
09333       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
09334       if (res) {
09335          zt_close(pri->fds[i]);
09336          pri->fds[i] = -1;
09337          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
09338          return -1;
09339       }
09340       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
09341          zt_close(pri->fds[i]);
09342          pri->fds[i] = -1;
09343          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
09344          return -1;
09345       }
09346       memset(&si, 0, sizeof(si));
09347       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
09348       if (res) {
09349          zt_close(pri->fds[i]);
09350          pri->fds[i] = -1;
09351          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
09352       }
09353       if (!si.alarms)
09354          pri->dchanavail[i] |= DCHAN_NOTINALARM;
09355       else
09356          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
09357       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
09358       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
09359       bi.numbufs = 32;
09360       bi.bufsize = 1024;
09361       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
09362          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
09363          zt_close(pri->fds[i]);
09364          pri->fds[i] = -1;
09365          return -1;
09366       }
09367       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
09368       /* Force overlap dial if we're doing GR-303! */
09369       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
09370          pri->overlapdial = 1;
09371       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
09372       /* Enslave to master if appropriate */
09373       if (i)
09374          pri_enslave(pri->dchans[0], pri->dchans[i]);
09375       if (!pri->dchans[i]) {
09376          zt_close(pri->fds[i]);
09377          pri->fds[i] = -1;
09378          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
09379          return -1;
09380       }
09381       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
09382       pri_set_nsf(pri->dchans[i], pri->nsf);
09383 #ifdef PRI_GETSET_TIMERS
09384       for (x = 0; x < PRI_MAX_TIMERS; x++) {
09385          if (pritimers[x] != 0)
09386             pri_set_timer(pri->dchans[i], x, pritimers[x]);
09387       }
09388 #endif
09389    }
09390    /* Assume primary is the one we use */
09391    pri->pri = pri->dchans[0];
09392    pri->resetpos = -1;
09393    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
09394       for (i = 0; i < NUM_DCHANS; i++) {
09395          if (!pri->dchannels[i])
09396             break;
09397          zt_close(pri->fds[i]);
09398          pri->fds[i] = -1;
09399       }
09400       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
09401       return -1;
09402    }
09403    return 0;
09404 }
09405 
09406 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
09407 {
09408    int which, span;
09409    char *ret = NULL;
09410 
09411    if (pos != rpos)
09412       return ret;
09413 
09414    for (which = span = 0; span < NUM_SPANS; span++) {
09415       if (pris[span].pri && ++which > state) {
09416          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
09417          break;
09418       }
09419    }
09420    return ret;
09421 }
09422 
09423 static char *complete_span_4(const char *line, const char *word, int pos, int state)
09424 {
09425    return complete_span_helper(line,word,pos,state,3);
09426 }
09427 
09428 static char *complete_span_5(const char *line, const char *word, int pos, int state)
09429 {
09430    return complete_span_helper(line,word,pos,state,4);
09431 }
09432 
09433 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
09434 {
09435    int myfd;
09436 
09437    if (!strncasecmp(argv[1], "set", 3)) {
09438       if (argc < 5) 
09439          return RESULT_SHOWUSAGE;
09440 
09441       if (ast_strlen_zero(argv[4]))
09442          return RESULT_SHOWUSAGE;
09443 
09444       myfd = open(argv[4], O_CREAT|O_WRONLY);
09445       if (myfd < 0) {
09446          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
09447          return RESULT_SUCCESS;
09448       }
09449 
09450       ast_mutex_lock(&pridebugfdlock);
09451 
09452       if (pridebugfd >= 0)
09453          close(pridebugfd);
09454 
09455       pridebugfd = myfd;
09456       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
09457       
09458       ast_mutex_unlock(&pridebugfdlock);
09459 
09460       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
09461    } else {
09462       /* Assume it is unset */
09463       ast_mutex_lock(&pridebugfdlock);
09464       close(pridebugfd);
09465       pridebugfd = -1;
09466       ast_cli(fd, "PRI debug output to file disabled\n");
09467       ast_mutex_unlock(&pridebugfdlock);
09468    }
09469 
09470    return RESULT_SUCCESS;
09471 }
09472 
09473 static int handle_pri_debug(int fd, int argc, char *argv[])
09474 {
09475    int span;
09476    int x;
09477    if (argc < 4) {
09478       return RESULT_SHOWUSAGE;
09479    }
09480    span = atoi(argv[3]);
09481    if ((span < 1) || (span > NUM_SPANS)) {
09482       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
09483       return RESULT_SUCCESS;
09484    }
09485    if (!pris[span-1].pri) {
09486       ast_cli(fd, "No PRI running on span %d\n", span);
09487       return RESULT_SUCCESS;
09488    }
09489    for (x = 0; x < NUM_DCHANS; x++) {
09490       if (pris[span-1].dchans[x])
09491          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09492                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09493                                                PRI_DEBUG_Q921_STATE);
09494    }
09495    ast_cli(fd, "Enabled debugging on span %d\n", span);
09496    return RESULT_SUCCESS;
09497 }
09498 
09499 
09500 
09501 static int handle_pri_no_debug(int fd, int argc, char *argv[])
09502 {
09503    int span;
09504    int x;
09505    if (argc < 5)
09506       return RESULT_SHOWUSAGE;
09507    span = atoi(argv[4]);
09508    if ((span < 1) || (span > NUM_SPANS)) {
09509       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 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], 0);
09519    }
09520    ast_cli(fd, "Disabled debugging on span %d\n", span);
09521    return RESULT_SUCCESS;
09522 }
09523 
09524 static int handle_pri_really_debug(int fd, int argc, char *argv[])
09525 {
09526    int span;
09527    int x;
09528    if (argc < 5)
09529       return RESULT_SHOWUSAGE;
09530    span = atoi(argv[4]);
09531    if ((span < 1) || (span > NUM_SPANS)) {
09532       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09533       return RESULT_SUCCESS;
09534    }
09535    if (!pris[span-1].pri) {
09536       ast_cli(fd, "No PRI running on span %d\n", span);
09537       return RESULT_SUCCESS;
09538    }
09539    for (x = 0; x < NUM_DCHANS; x++) {
09540       if (pris[span-1].dchans[x])
09541          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09542                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09543                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
09544    }
09545    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
09546    return RESULT_SUCCESS;
09547 }
09548 
09549 static void build_status(char *s, size_t len, int status, int active)
09550 {
09551    if (!s || len < 1) {
09552       return;
09553    }
09554    s[0] = '\0';
09555    if (status & DCHAN_PROVISIONED)
09556       strncat(s, "Provisioned, ", len - strlen(s) - 1);
09557    if (!(status & DCHAN_NOTINALARM))
09558       strncat(s, "In Alarm, ", len - strlen(s) - 1);
09559    if (status & DCHAN_UP)
09560       strncat(s, "Up", len - strlen(s) - 1);
09561    else
09562       strncat(s, "Down", len - strlen(s) - 1);
09563    if (active)
09564       strncat(s, ", Active", len - strlen(s) - 1);
09565    else
09566       strncat(s, ", Standby", len - strlen(s) - 1);
09567    s[len - 1] = '\0';
09568 }
09569 
09570 static int handle_pri_show_spans(int fd, int argc, char *argv[])
09571 {
09572    int span;
09573    int x;
09574    char status[256];
09575    if (argc != 3)
09576       return RESULT_SHOWUSAGE;
09577 
09578    for (span = 0; span < NUM_SPANS; span++) {
09579       if (pris[span].pri) {
09580          for (x = 0; x < NUM_DCHANS; x++) {
09581             if (pris[span].dchannels[x]) {
09582                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
09583                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
09584             }
09585          }
09586       }
09587    }
09588    return RESULT_SUCCESS;
09589 }
09590 
09591 static int handle_pri_show_span(int fd, int argc, char *argv[])
09592 {
09593    int span;
09594    int x;
09595    char status[256];
09596    if (argc < 4)
09597       return RESULT_SHOWUSAGE;
09598    span = atoi(argv[3]);
09599    if ((span < 1) || (span > NUM_SPANS)) {
09600       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
09601       return RESULT_SUCCESS;
09602    }
09603    if (!pris[span-1].pri) {
09604       ast_cli(fd, "No PRI running on span %d\n", span);
09605       return RESULT_SUCCESS;
09606    }
09607    for (x = 0; x < NUM_DCHANS; x++) {
09608       if (pris[span-1].dchannels[x]) {
09609 #ifdef PRI_DUMP_INFO_STR
09610          char *info_str = NULL;
09611 #endif
09612          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
09613          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
09614          ast_cli(fd, "Status: %s\n", status);
09615 #ifdef PRI_DUMP_INFO_STR
09616          info_str = pri_dump_info_str(pris[span-1].pri);
09617          if (info_str) {
09618             ast_cli(fd, "%s", info_str);
09619             free(info_str);
09620          }
09621 #else
09622          pri_dump_info(pris[span-1].pri);
09623 #endif
09624          ast_cli(fd, "\n");
09625       }
09626    }
09627    return RESULT_SUCCESS;
09628 }
09629 
09630 static int handle_pri_show_debug(int fd, int argc, char *argv[])
09631 {
09632    int x;
09633    int span;
09634    int count=0;
09635    int debug=0;
09636 
09637    for (span = 0; span < NUM_SPANS; span++) {
09638            if (pris[span].pri) {
09639          for (x = 0; x < NUM_DCHANS; x++) {
09640             debug = 0;
09641                if (pris[span].dchans[x]) {
09642                   debug = pri_get_debug(pris[span].dchans[x]);
09643                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" );
09644                count++;
09645             }
09646          }
09647       }
09648 
09649    }
09650    ast_mutex_lock(&pridebugfdlock);
09651    if (pridebugfd >= 0) 
09652       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
09653    ast_mutex_unlock(&pridebugfdlock);
09654        
09655    if (!count) 
09656       ast_cli(fd, "No debug set or no PRI running\n");
09657    return RESULT_SUCCESS;
09658 }
09659 
09660 static const char pri_debug_help[] = 
09661    "Usage: pri debug span <span>\n"
09662    "       Enables debugging on a given PRI span\n";
09663    
09664 static const char pri_no_debug_help[] = 
09665    "Usage: pri no debug span <span>\n"
09666    "       Disables debugging on a given PRI span\n";
09667 
09668 static const char pri_really_debug_help[] = 
09669    "Usage: pri intensive debug span <span>\n"
09670    "       Enables debugging down to the Q.921 level\n";
09671 
09672 static const char pri_show_span_help[] = 
09673    "Usage: pri show span <span>\n"
09674    "       Displays PRI Information on a given PRI span\n";
09675 
09676 static const char pri_show_spans_help[] = 
09677    "Usage: pri show spans\n"
09678    "       Displays PRI Information\n";
09679 
09680 static struct ast_cli_entry zap_pri_cli[] = {
09681    { { "pri", "debug", "span", NULL },
09682    handle_pri_debug, "Enables PRI debugging on a span",
09683    pri_debug_help, complete_span_4 },
09684 
09685    { { "pri", "no", "debug", "span", NULL },
09686    handle_pri_no_debug, "Disables PRI debugging on a span",
09687    pri_no_debug_help, complete_span_5 },
09688 
09689    { { "pri", "intense", "debug", "span", NULL },
09690    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
09691    pri_really_debug_help, complete_span_5 },
09692 
09693    { { "pri", "show", "spans", NULL },
09694    handle_pri_show_spans, "Displays PRI Information",
09695    pri_show_spans_help },
09696 
09697    { { "pri", "show", "span", NULL },
09698    handle_pri_show_span, "Displays PRI Information",
09699    pri_show_span_help, complete_span_4 },
09700 
09701    { { "pri", "show", "debug", NULL },
09702    handle_pri_show_debug, "Displays current PRI debug settings" },
09703 
09704    { { "pri", "set", "debug", "file", NULL },
09705    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
09706 
09707    { { "pri", "unset", "debug", "file", NULL },
09708    handle_pri_set_debug_file, "Ends PRI debug output to file" },
09709 };
09710 
09711 #endif /* HAVE_PRI */
09712 
09713 static int zap_destroy_channel(int fd, int argc, char **argv)
09714 {
09715    int channel;
09716    
09717    if (argc != 4)
09718       return RESULT_SHOWUSAGE;
09719    
09720    channel = atoi(argv[3]);
09721 
09722    return zap_destroy_channel_bynum(channel);
09723 }
09724 
09725 static int setup_zap(int reload);
09726 static int zap_restart(void)
09727 {
09728    if (option_verbose > 0)
09729       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09730    while (iflist) {
09731       if (option_debug)
09732          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09733       /* Also updates iflist: */
09734       destroy_channel(NULL, iflist, 1);
09735    }
09736    if (option_debug)
09737       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09738    if (setup_zap(0) != 0) {
09739       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09740       return 1;
09741    }
09742    return 0;
09743 }
09744 
09745 static int zap_restart_cmd(int fd, int argc, char **argv)
09746 {
09747    if (argc != 2) {
09748       return RESULT_SHOWUSAGE;
09749    }
09750 
09751    if (zap_restart() != 0)
09752       return RESULT_FAILURE;
09753    return RESULT_SUCCESS;
09754 }
09755 
09756 static int action_zaprestart(struct mansession *s, const struct message *m)
09757 {
09758    if (zap_restart() != 0) {
09759       astman_send_error(s, m, "Failed rereading zaptel configuration");
09760       return 1;
09761    }
09762    astman_send_ack(s, m, "ZapRestart: Success");
09763    return 0;
09764 }
09765 
09766 static int zap_show_channels(int fd, int argc, char **argv)
09767 {
09768 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09769 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09770    struct zt_pvt *tmp = NULL;
09771    char tmps[20] = "";
09772    ast_mutex_t *lock;
09773    struct zt_pvt *start;
09774 #ifdef HAVE_PRI
09775    int trunkgroup;
09776    struct zt_pri *pri = NULL;
09777    int x;
09778 #endif
09779 
09780    lock = &iflock;
09781    start = iflist;
09782 
09783 #ifdef HAVE_PRI
09784    if (argc == 4) {
09785       if ((trunkgroup = atoi(argv[3])) < 1)
09786          return RESULT_SHOWUSAGE;
09787       for (x = 0; x < NUM_SPANS; x++) {
09788          if (pris[x].trunkgroup == trunkgroup) {
09789             pri = pris + x;
09790             break;
09791          }
09792       }
09793       if (pri) {
09794          start = pri->crvs;
09795          lock = &pri->lock;
09796       } else {
09797          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09798          return RESULT_FAILURE;
09799       }
09800    } else
09801 #endif
09802    if (argc != 3)
09803       return RESULT_SHOWUSAGE;
09804 
09805    ast_mutex_lock(lock);
09806 #ifdef HAVE_PRI
09807    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
09808 #else
09809    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
09810 #endif   
09811    
09812    tmp = start;
09813    while (tmp) {
09814       if (tmp->channel > 0) {
09815          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09816       } else
09817          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09818       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
09819       tmp = tmp->next;
09820    }
09821    ast_mutex_unlock(lock);
09822    return RESULT_SUCCESS;
09823 #undef FORMAT
09824 #undef FORMAT2
09825 }
09826 
09827 static int zap_show_channel(int fd, int argc, char **argv)
09828 {
09829    int channel;
09830    struct zt_pvt *tmp = NULL;
09831    ZT_CONFINFO ci;
09832    ZT_PARAMS ps;
09833    int x;
09834    ast_mutex_t *lock;
09835    struct zt_pvt *start;
09836 #ifdef HAVE_PRI
09837    char *c;
09838    int trunkgroup;
09839    struct zt_pri *pri=NULL;
09840 #endif
09841 
09842    lock = &iflock;
09843    start = iflist;
09844 
09845    if (argc != 4)
09846       return RESULT_SHOWUSAGE;
09847 #ifdef HAVE_PRI
09848    if ((c = strchr(argv[3], ':'))) {
09849       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09850          return RESULT_SHOWUSAGE;
09851       if ((trunkgroup < 1) || (channel < 1))
09852          return RESULT_SHOWUSAGE;
09853       for (x = 0; x < NUM_SPANS; x++) {
09854          if (pris[x].trunkgroup == trunkgroup) {
09855             pri = pris + x;
09856             break;
09857          }
09858       }
09859       if (pri) {
09860          start = pri->crvs;
09861          lock = &pri->lock;
09862       } else {
09863          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09864          return RESULT_FAILURE;
09865       }
09866    } else
09867 #endif
09868       channel = atoi(argv[3]);
09869 
09870    ast_mutex_lock(lock);
09871    tmp = start;
09872    while (tmp) {
09873       if (tmp->channel == channel) {
09874 #ifdef HAVE_PRI
09875          if (pri) 
09876             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
09877          else
09878 #endif         
09879          ast_cli(fd, "Channel: %d\n", tmp->channel);
09880          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
09881          ast_cli(fd, "Span: %d\n", tmp->span);
09882          ast_cli(fd, "Extension: %s\n", tmp->exten);
09883          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
09884          ast_cli(fd, "Context: %s\n", tmp->context);
09885          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
09886          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
09887          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
09888          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
09889          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
09890          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
09891          ast_cli(fd, "Radio: %d\n", tmp->radio);
09892          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
09893          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)" : "");
09894          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)" : "");
09895          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)" : "");
09896          ast_cli(fd, "Confno: %d\n", tmp->confno);
09897          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
09898          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
09899          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
09900          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
09901          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
09902          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
09903          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
09904          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
09905          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
09906          if (tmp->master)
09907             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
09908          for (x = 0; x < MAX_SLAVES; x++) {
09909             if (tmp->slaves[x])
09910                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
09911          }
09912 #ifdef HAVE_PRI
09913          if (tmp->pri) {
09914             ast_cli(fd, "PRI Flags: ");
09915             if (tmp->resetting)
09916                ast_cli(fd, "Resetting ");
09917             if (tmp->call)
09918                ast_cli(fd, "Call ");
09919             if (tmp->bearer)
09920                ast_cli(fd, "Bearer ");
09921             ast_cli(fd, "\n");
09922             if (tmp->logicalspan) 
09923                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
09924             else
09925                ast_cli(fd, "PRI Logical Span: Implicit\n");
09926          }
09927             
09928 #endif
09929          memset(&ci, 0, sizeof(ci));
09930          ps.channo = tmp->channel;
09931          if (tmp->subs[SUB_REAL].zfd > -1) {
09932             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
09933                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
09934             }
09935 #ifdef ZT_GETCONFMUTE
09936             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
09937                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
09938             }
09939 #endif
09940             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
09941                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
09942             } else {
09943                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
09944             }
09945          }
09946          ast_mutex_unlock(lock);
09947          return RESULT_SUCCESS;
09948       }
09949       tmp = tmp->next;
09950    }
09951    
09952    ast_cli(fd, "Unable to find given channel %d\n", channel);
09953    ast_mutex_unlock(lock);
09954    return RESULT_FAILURE;
09955 }
09956 
09957 static char zap_show_cadences_help[] =
09958 "Usage: zap show cadences\n"
09959 "       Shows all cadences currently defined\n";
09960 
09961 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
09962 {
09963    int i, j;
09964    for (i = 0; i < num_cadence; i++) {
09965       char output[1024];
09966       char tmp[16], tmp2[64];
09967       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
09968       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
09969 
09970       for (j = 0; j < 16; j++) {
09971          if (cadences[i].ringcadence[j] == 0)
09972             break;
09973          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
09974          if (cidrings[i] * 2 - 1 == j)
09975             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
09976          else
09977             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
09978          if (j != 0)
09979             strncat(output, ",", sizeof(output) - strlen(output) - 1);
09980          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
09981       }
09982       ast_cli(fd,"%s\n",output);
09983    }
09984    return 0;
09985 }
09986 
09987 /* Based on irqmiss.c */
09988 static int zap_show_status(int fd, int argc, char *argv[]) {
09989    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
09990    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
09991 
09992    int span;
09993    int res;
09994    char alarms[50];
09995 
09996    int ctl;
09997    ZT_SPANINFO s;
09998 
09999    ctl = open("/dev/zap/ctl", O_RDWR);
10000    if (ctl < 0) {
10001       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
10002       ast_cli(fd, "No Zaptel interface found.\n");
10003       return RESULT_FAILURE;
10004    }
10005    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10006 
10007    for (span = 1; span < ZT_MAX_SPANS; ++span) {
10008       s.spanno = span;
10009       res = ioctl(ctl, ZT_SPANSTAT, &s);
10010       if (res) {
10011          continue;
10012       }
10013       alarms[0] = '\0';
10014       if (s.alarms > 0) {
10015          if (s.alarms & ZT_ALARM_BLUE)
10016             strcat(alarms, "BLU/");
10017          if (s.alarms & ZT_ALARM_YELLOW)
10018             strcat(alarms, "YEL/");
10019          if (s.alarms & ZT_ALARM_RED)
10020             strcat(alarms, "RED/");
10021          if (s.alarms & ZT_ALARM_LOOPBACK)
10022             strcat(alarms, "LB/");
10023          if (s.alarms & ZT_ALARM_RECOVER)
10024             strcat(alarms, "REC/");
10025          if (s.alarms & ZT_ALARM_NOTOPEN)
10026             strcat(alarms, "NOP/");
10027          if (!strlen(alarms))
10028             strcat(alarms, "UUU/");
10029          if (strlen(alarms)) {
10030             /* Strip trailing / */
10031             alarms[strlen(alarms) - 1] = '\0';
10032          }
10033       } else {
10034          if (s.numchans)
10035             strcpy(alarms, "OK");
10036          else
10037             strcpy(alarms, "UNCONFIGURED");
10038       }
10039 
10040       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
10041    }
10042    close(ctl);
10043 
10044    return RESULT_SUCCESS;
10045 #undef FORMAT
10046 #undef FORMAT2
10047 }
10048 
10049 static char show_channels_usage[] =
10050    "Usage: zap show channels\n"
10051    "  Shows a list of available channels\n";
10052 
10053 static char show_channel_usage[] =
10054    "Usage: zap show channel <chan num>\n"
10055    "  Detailed information about a given channel\n";
10056 
10057 static char zap_show_status_usage[] =
10058    "Usage: zap show status\n"
10059    "       Shows a list of Zaptel cards with status\n";
10060 
10061 static char destroy_channel_usage[] =
10062    "Usage: zap destroy channel <chan num>\n"
10063    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
10064 
10065 static char zap_restart_usage[] =
10066    "Usage: zap restart\n"
10067    "  Restarts the zaptel channels: destroys them all and then\n"
10068    "  re-reads them from zapata.conf.\n"
10069    "  Note that this will STOP any running CALL on zaptel channels.\n"
10070    "";
10071 
10072 static struct ast_cli_entry zap_cli[] = {
10073    { { "zap", "show", "cadences", NULL },
10074    handle_zap_show_cadences, "List cadences",
10075    zap_show_cadences_help },
10076 
10077    { { "zap", "show", "channels", NULL},
10078    zap_show_channels, "Show active zapata channels",
10079    show_channels_usage },
10080 
10081    { { "zap", "show", "channel", NULL},
10082    zap_show_channel, "Show information on a channel",
10083    show_channel_usage },
10084 
10085    { { "zap", "destroy", "channel", NULL},
10086    zap_destroy_channel, "Destroy a channel",
10087    destroy_channel_usage },
10088 
10089    { { "zap", "restart", NULL},
10090    zap_restart_cmd, "Fully restart zaptel channels",
10091    zap_restart_usage },
10092 
10093    { { "zap", "show", "status", NULL},
10094    zap_show_status, "Show all Zaptel cards status",
10095    zap_show_status_usage },
10096 };
10097 
10098 #define TRANSFER  0
10099 #define HANGUP    1
10100 
10101 static int zap_fake_event(struct zt_pvt *p, int mode)
10102 {
10103    if (p) {
10104       switch (mode) {
10105          case TRANSFER:
10106             p->fake_event = ZT_EVENT_WINKFLASH;
10107             break;
10108          case HANGUP:
10109             p->fake_event = ZT_EVENT_ONHOOK;
10110             break;
10111          default:
10112             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10113       }
10114    }
10115    return 0;
10116 }
10117 static struct zt_pvt *find_channel(int channel)
10118 {
10119    struct zt_pvt *p = iflist;
10120    while (p) {
10121       if (p->channel == channel) {
10122          break;
10123       }
10124       p = p->next;
10125    }
10126    return p;
10127 }
10128 
10129 static int action_zapdndon(struct mansession *s, const struct message *m)
10130 {
10131    struct zt_pvt *p = NULL;
10132    const char *channel = astman_get_header(m, "ZapChannel");
10133 
10134    if (ast_strlen_zero(channel)) {
10135       astman_send_error(s, m, "No channel specified");
10136       return 0;
10137    }
10138    p = find_channel(atoi(channel));
10139    if (!p) {
10140       astman_send_error(s, m, "No such channel");
10141       return 0;
10142    }
10143    p->dnd = 1;
10144    astman_send_ack(s, m, "DND Enabled");
10145    return 0;
10146 }
10147 
10148 static int action_zapdndoff(struct mansession *s, const struct message *m)
10149 {
10150    struct zt_pvt *p = NULL;
10151    const char *channel = astman_get_header(m, "ZapChannel");
10152 
10153    if (ast_strlen_zero(channel)) {
10154       astman_send_error(s, m, "No channel specified");
10155       return 0;
10156    }
10157    p = find_channel(atoi(channel));
10158    if (!p) {
10159       astman_send_error(s, m, "No such channel");
10160       return 0;
10161    }
10162    p->dnd = 0;
10163    astman_send_ack(s, m, "DND Disabled");
10164    return 0;
10165 }
10166 
10167 static int action_transfer(struct mansession *s, const struct message *m)
10168 {
10169    struct zt_pvt *p = NULL;
10170    const char *channel = astman_get_header(m, "ZapChannel");
10171 
10172    if (ast_strlen_zero(channel)) {
10173       astman_send_error(s, m, "No channel specified");
10174       return 0;
10175    }
10176    p = find_channel(atoi(channel));
10177    if (!p) {
10178       astman_send_error(s, m, "No such channel");
10179       return 0;
10180    }
10181    zap_fake_event(p,TRANSFER);
10182    astman_send_ack(s, m, "ZapTransfer");
10183    return 0;
10184 }
10185 
10186 static int action_transferhangup(struct mansession *s, const struct message *m)
10187 {
10188    struct zt_pvt *p = NULL;
10189    const char *channel = astman_get_header(m, "ZapChannel");
10190 
10191    if (ast_strlen_zero(channel)) {
10192       astman_send_error(s, m, "No channel specified");
10193       return 0;
10194    }
10195    p = find_channel(atoi(channel));
10196    if (!p) {
10197       astman_send_error(s, m, "No such channel");
10198       return 0;
10199    }
10200    zap_fake_event(p,HANGUP);
10201    astman_send_ack(s, m, "ZapHangup");
10202    return 0;
10203 }
10204 
10205 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
10206 {
10207    struct zt_pvt *p = NULL;
10208    const char *channel = astman_get_header(m, "ZapChannel");
10209    const char *number = astman_get_header(m, "Number");
10210    int i;
10211 
10212    if (ast_strlen_zero(channel)) {
10213       astman_send_error(s, m, "No channel specified");
10214       return 0;
10215    }
10216    if (ast_strlen_zero(number)) {
10217       astman_send_error(s, m, "No number specified");
10218       return 0;
10219    }
10220    p = find_channel(atoi(channel));
10221    if (!p) {
10222       astman_send_error(s, m, "No such channel");
10223       return 0;
10224    }
10225    if (!p->owner) {
10226       astman_send_error(s, m, "Channel does not have it's owner");
10227       return 0;
10228    }
10229    for (i = 0; i < strlen(number); i++) {
10230       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10231       zap_queue_frame(p, &f, NULL); 
10232    }
10233    astman_send_ack(s, m, "ZapDialOffhook");
10234    return 0;
10235 }
10236 
10237 static int action_zapshowchannels(struct mansession *s, const struct message *m)
10238 {
10239    struct zt_pvt *tmp = NULL;
10240    const char *id = astman_get_header(m, "ActionID");
10241    char idText[256] = "";
10242 
10243    astman_send_ack(s, m, "Zapata channel status will follow");
10244    if (!ast_strlen_zero(id))
10245       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10246 
10247    ast_mutex_lock(&iflock);
10248    
10249    tmp = iflist;
10250    while (tmp) {
10251       if (tmp->channel > 0) {
10252          int alarm = get_alarms(tmp);
10253          astman_append(s,
10254             "Event: ZapShowChannels\r\n"
10255             "Channel: %d\r\n"
10256             "Signalling: %s\r\n"
10257             "Context: %s\r\n"
10258             "DND: %s\r\n"
10259             "Alarm: %s\r\n"
10260             "%s"
10261             "\r\n",
10262             tmp->channel, sig2str(tmp->sig), tmp->context, 
10263             tmp->dnd ? "Enabled" : "Disabled",
10264             alarm2str(alarm), idText);
10265       } 
10266 
10267       tmp = tmp->next;
10268    }
10269 
10270    ast_mutex_unlock(&iflock);
10271    
10272    astman_append(s, 
10273       "Event: ZapShowChannelsComplete\r\n"
10274       "%s"
10275       "\r\n", 
10276       idText);
10277    return 0;
10278 }
10279 
10280 static int __unload_module(void)
10281 {
10282    int x = 0;
10283    struct zt_pvt *p, *pl;
10284 #ifdef HAVE_PRI
10285    int i;
10286    for (i = 0; i < NUM_SPANS; i++) {
10287       if (pris[i].master != AST_PTHREADT_NULL) 
10288          pthread_cancel(pris[i].master);
10289    }
10290    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
10291    ast_unregister_application(zap_send_keypad_facility_app);
10292 #endif
10293    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
10294    ast_manager_unregister( "ZapDialOffhook" );
10295    ast_manager_unregister( "ZapHangup" );
10296    ast_manager_unregister( "ZapTransfer" );
10297    ast_manager_unregister( "ZapDNDoff" );
10298    ast_manager_unregister( "ZapDNDon" );
10299    ast_manager_unregister("ZapShowChannels");
10300    ast_manager_unregister("ZapRestart");
10301    ast_channel_unregister(&zap_tech);
10302    ast_mutex_lock(&iflock);
10303    /* Hangup all interfaces if they have an owner */
10304    p = iflist;
10305    while (p) {
10306       if (p->owner)
10307          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10308       p = p->next;
10309    }
10310    ast_mutex_unlock(&iflock);
10311    ast_mutex_lock(&monlock);
10312    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10313       pthread_cancel(monitor_thread);
10314       pthread_kill(monitor_thread, SIGURG);
10315       pthread_join(monitor_thread, NULL);
10316    }
10317    monitor_thread = AST_PTHREADT_STOP;
10318    ast_mutex_unlock(&monlock);
10319 
10320    ast_mutex_lock(&iflock);
10321    /* Destroy all the interfaces and free their memory */
10322    p = iflist;
10323    while (p) {
10324       /* Free any callerid */
10325       if (p->cidspill)
10326          free(p->cidspill);
10327       /* Close the zapata thingy */
10328       if (p->subs[SUB_REAL].zfd > -1)
10329          zt_close(p->subs[SUB_REAL].zfd);
10330       pl = p;
10331       p = p->next;
10332       x++;
10333       /* Free associated memory */
10334       if (pl)
10335          destroy_zt_pvt(&pl);
10336       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10337    }
10338    iflist = NULL;
10339    ifcount = 0;
10340    ast_mutex_unlock(&iflock);
10341 #ifdef HAVE_PRI      
10342    for (i = 0; i < NUM_SPANS; i++) {
10343       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10344          pthread_join(pris[i].master, NULL);
10345       zt_close(pris[i].fds[i]);
10346    }
10347 #endif
10348    return 0;
10349 }
10350 
10351 static int unload_module(void)
10352 {
10353 #ifdef HAVE_PRI      
10354    int y;
10355    for (y = 0; y < NUM_SPANS; y++)
10356       ast_mutex_destroy(&pris[y].lock);
10357 #endif
10358    return __unload_module();
10359 }
10360 
10361 static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
10362 {
10363    char *c, *chan;
10364    int x, start, finish;
10365    struct zt_pvt *tmp;
10366 #ifdef HAVE_PRI
10367    struct zt_pri *pri;
10368    int trunkgroup, y;
10369 #endif
10370    
10371    if ((reload == 0) && (conf.chan.sig < 0)) {
10372       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10373       return -1;
10374    }
10375 
10376    c = ast_strdupa(value);
10377 
10378 #ifdef HAVE_PRI
10379    pri = NULL;
10380    if (iscrv) {
10381       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10382          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
10383          return -1;
10384       }
10385       if (trunkgroup < 1) {
10386          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
10387          return -1;
10388       }
10389       c += y;
10390       for (y = 0; y < NUM_SPANS; y++) {
10391          if (pris[y].trunkgroup == trunkgroup) {
10392             pri = pris + y;
10393             break;
10394          }
10395       }
10396       if (!pri) {
10397          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
10398          return -1;
10399       }
10400    }
10401 #endif         
10402 
10403    while ((chan = strsep(&c, ","))) {
10404       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10405          /* Range */
10406       } else if (sscanf(chan, "%d", &start)) {
10407          /* Just one */
10408          finish = start;
10409       } else if (!strcasecmp(chan, "pseudo")) {
10410          finish = start = CHAN_PSEUDO;
10411          if (found_pseudo)
10412             *found_pseudo = 1;
10413       } else {
10414          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
10415          return -1;
10416       }
10417       if (finish < start) {
10418          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10419          x = finish;
10420          finish = start;
10421          start = x;
10422       }
10423 
10424       for (x = start; x <= finish; x++) {
10425 #ifdef HAVE_PRI
10426          tmp = mkintf(x, conf, pri, reload);
10427 #else       
10428          tmp = mkintf(x, conf, NULL, reload);
10429 #endif         
10430 
10431          if (tmp) {
10432             if (option_verbose > 2) {
10433 #ifdef HAVE_PRI
10434                if (pri)
10435                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
10436                else
10437 #endif
10438                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10439             }
10440          } else {
10441             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
10442                (reload == 1) ? "reconfigure" : "register", value);
10443             return -1;
10444          }
10445       }
10446    }
10447 
10448    return 0;
10449 }
10450 
10451 /** The length of the parameters list of 'zapchan'. 
10452  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10453 #define MAX_CHANLIST_LEN 80
10454 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
10455 {
10456    struct zt_pvt *tmp;
10457    char *ringc; /* temporary string for parsing the dring number. */
10458    int y;
10459    int found_pseudo = 0;
10460         char zapchan[MAX_CHANLIST_LEN] = {};
10461 
10462    for (; v; v = v->next) {
10463       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
10464          continue;
10465 
10466       /* Create the interface list */
10467       if (!strcasecmp(v->name, "channel")
10468 #ifdef HAVE_PRI
10469           || !strcasecmp(v->name, "crv")
10470 #endif         
10471          ) {
10472          if (skipchannels)
10473             continue;
10474          int iscrv = !strcasecmp(v->name, "crv");
10475          if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
10476                return -1;
10477       } else if (!strcasecmp(v->name, "zapchan")) {
10478          ast_copy_string(zapchan, v->value, sizeof(zapchan));
10479       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10480          if (ast_true(v->value))
10481             confp->chan.usedistinctiveringdetection = 1;
10482       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
10483          if (ast_true(v->value))
10484             distinctiveringaftercid = 1;
10485       } else if (!strcasecmp(v->name, "dring1context")) {
10486          ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData));
10487       } else if (!strcasecmp(v->name, "dring2context")) {
10488          ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData));
10489       } else if (!strcasecmp(v->name, "dring3context")) {
10490          ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData));
10491       } else if (!strcasecmp(v->name, "dring1")) {
10492          ringc = v->value;
10493          sscanf(ringc, "%d,%d,%d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10494       } else if (!strcasecmp(v->name, "dring2")) {
10495          ringc = v->value;
10496          sscanf(ringc,"%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10497       } else if (!strcasecmp(v->name, "dring3")) {
10498          ringc = v->value;
10499          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10500       } else if (!strcasecmp(v->name, "usecallerid")) {
10501          confp->chan.use_callerid = ast_true(v->value);
10502       } else if (!strcasecmp(v->name, "cidsignalling")) {
10503          if (!strcasecmp(v->value, "bell"))
10504             confp->chan.cid_signalling = CID_SIG_BELL;
10505          else if (!strcasecmp(v->value, "v23"))
10506             confp->chan.cid_signalling = CID_SIG_V23;
10507          else if (!strcasecmp(v->value, "dtmf"))
10508             confp->chan.cid_signalling = CID_SIG_DTMF;
10509          else if (!strcasecmp(v->value, "smdi"))
10510             confp->chan.cid_signalling = CID_SIG_SMDI;
10511          else if (!strcasecmp(v->value, "v23_jp"))
10512             confp->chan.cid_signalling = CID_SIG_V23_JP;
10513          else if (ast_true(v->value))
10514             confp->chan.cid_signalling = CID_SIG_BELL;
10515       } else if (!strcasecmp(v->name, "cidstart")) {
10516          if (!strcasecmp(v->value, "ring"))
10517             confp->chan.cid_start = CID_START_RING;
10518          else if (!strcasecmp(v->value, "polarity"))
10519             confp->chan.cid_start = CID_START_POLARITY;
10520          else if (ast_true(v->value))
10521             confp->chan.cid_start = CID_START_RING;
10522       } else if (!strcasecmp(v->name, "threewaycalling")) {
10523          confp->chan.threewaycalling = ast_true(v->value);
10524       } else if (!strcasecmp(v->name, "cancallforward")) {
10525          confp->chan.cancallforward = ast_true(v->value);
10526       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10527          if (ast_true(v->value)) 
10528             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
10529          else
10530             confp->chan.dtmfrelax = 0;
10531       } else if (!strcasecmp(v->name, "mailbox")) {
10532          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
10533       } else if (!strcasecmp(v->name, "adsi")) {
10534          confp->chan.adsi = ast_true(v->value);
10535       } else if (!strcasecmp(v->name, "usesmdi")) {
10536          confp->chan.use_smdi = ast_true(v->value);
10537       } else if (!strcasecmp(v->name, "smdiport")) {
10538          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
10539       } else if (!strcasecmp(v->name, "transfer")) {
10540          confp->chan.transfer = ast_true(v->value);
10541       } else if (!strcasecmp(v->name, "canpark")) {
10542          confp->chan.canpark = ast_true(v->value);
10543       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10544          confp->chan.echocanbridged = ast_true(v->value);
10545       } else if (!strcasecmp(v->name, "busydetect")) {
10546          confp->chan.busydetect = ast_true(v->value);
10547       } else if (!strcasecmp(v->name, "busycount")) {
10548          confp->chan.busycount = atoi(v->value);
10549       } else if (!strcasecmp(v->name, "busypattern")) {
10550          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
10551             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
10552          }
10553       } else if (!strcasecmp(v->name, "callprogress")) {
10554          if (ast_true(v->value))
10555             confp->chan.callprogress |= 1;
10556          else
10557             confp->chan.callprogress &= ~1;
10558       } else if (!strcasecmp(v->name, "faxdetect")) {
10559          if (!strcasecmp(v->value, "incoming")) {
10560             confp->chan.callprogress |= 4;
10561             confp->chan.callprogress &= ~2;
10562          } else if (!strcasecmp(v->value, "outgoing")) {
10563             confp->chan.callprogress &= ~4;
10564             confp->chan.callprogress |= 2;
10565          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10566             confp->chan.callprogress |= 6;
10567          else
10568             confp->chan.callprogress &= ~6;
10569       } else if (!strcasecmp(v->name, "echocancel")) {
10570          if (!ast_strlen_zero(v->value)) {
10571             y = atoi(v->value);
10572          } else
10573             y = 0;
10574          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
10575             confp->chan.echocancel = y;
10576          else {
10577             confp->chan.echocancel = ast_true(v->value);
10578             if (confp->chan.echocancel)
10579                confp->chan.echocancel=128;
10580          }
10581       } else if (!strcasecmp(v->name, "echotraining")) {
10582          if (sscanf(v->value, "%d", &y) == 1) {
10583             if ((y < 10) || (y > 4000)) {
10584                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
10585             } else {
10586                confp->chan.echotraining = y;
10587             }
10588          } else if (ast_true(v->value)) {
10589             confp->chan.echotraining = 400;
10590          } else
10591             confp->chan.echotraining = 0;
10592       } else if (!strcasecmp(v->name, "hidecallerid")) {
10593          confp->chan.hidecallerid = ast_true(v->value);
10594       } else if (!strcasecmp(v->name, "hidecalleridname")) {
10595          confp->chan.hidecalleridname = ast_true(v->value);
10596       } else if (!strcasecmp(v->name, "pulsedial")) {
10597          confp->chan.pulse = ast_true(v->value);
10598       } else if (!strcasecmp(v->name, "callreturn")) {
10599          confp->chan.callreturn = ast_true(v->value);
10600       } else if (!strcasecmp(v->name, "callwaiting")) {
10601          confp->chan.callwaiting = ast_true(v->value);
10602       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10603          confp->chan.callwaitingcallerid = ast_true(v->value);
10604       } else if (!strcasecmp(v->name, "context")) {
10605          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
10606       } else if (!strcasecmp(v->name, "language")) {
10607          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
10608       } else if (!strcasecmp(v->name, "progzone")) {
10609          ast_copy_string(progzone, v->value, sizeof(progzone));
10610       } else if (!strcasecmp(v->name, "mohinterpret") 
10611          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
10612          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
10613       } else if (!strcasecmp(v->name, "mohsuggest")) {
10614          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
10615       } else if (!strcasecmp(v->name, "stripmsd")) {
10616          confp->chan.stripmsd = atoi(v->value);
10617       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10618          numbufs = atoi(v->value);
10619       } else if (!strcasecmp(v->name, "group")) {
10620          confp->chan.group = ast_get_group(v->value);
10621       } else if (!strcasecmp(v->name, "callgroup")) {
10622          confp->chan.callgroup = ast_get_group(v->value);
10623       } else if (!strcasecmp(v->name, "pickupgroup")) {
10624          confp->chan.pickupgroup = ast_get_group(v->value);
10625       } else if (!strcasecmp(v->name, "immediate")) {
10626          confp->chan.immediate = ast_true(v->value);
10627       } else if (!strcasecmp(v->name, "transfertobusy")) {
10628          confp->chan.transfertobusy = ast_true(v->value);
10629       } else if (!strcasecmp(v->name, "rxgain")) {
10630          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
10631             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10632          }
10633       } else if (!strcasecmp(v->name, "txgain")) {
10634          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
10635             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10636          }
10637       } else if (!strcasecmp(v->name, "tonezone")) {
10638          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
10639             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10640          }
10641       } else if (!strcasecmp(v->name, "callerid")) {
10642          if (!strcasecmp(v->value, "asreceived")) {
10643             confp->chan.cid_num[0] = '\0';
10644             confp->chan.cid_name[0] = '\0';
10645          } else {
10646             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
10647          } 
10648       } else if (!strcasecmp(v->name, "fullname")) {
10649          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
10650       } else if (!strcasecmp(v->name, "cid_number")) {
10651          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
10652       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10653          confp->chan.zaptrcallerid = ast_true(v->value);
10654       } else if (!strcasecmp(v->name, "restrictcid")) {
10655          confp->chan.restrictcid = ast_true(v->value);
10656       } else if (!strcasecmp(v->name, "usecallingpres")) {
10657          confp->chan.use_callingpres = ast_true(v->value);
10658       } else if (!strcasecmp(v->name, "accountcode")) {
10659          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
10660       } else if (!strcasecmp(v->name, "amaflags")) {
10661          y = ast_cdr_amaflags2int(v->value);
10662          if (y < 0) 
10663             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10664          else
10665             confp->chan.amaflags = y;
10666       } else if (!reload){ 
10667           if (!strcasecmp(v->name, "signalling")) {
10668             confp->chan.outsigmod = -1;
10669             if (!strcasecmp(v->value, "em")) {
10670                confp->chan.sig = SIG_EM;
10671             } else if (!strcasecmp(v->value, "em_e1")) {
10672                confp->chan.sig = SIG_EM_E1;
10673             } else if (!strcasecmp(v->value, "em_w")) {
10674                confp->chan.sig = SIG_EMWINK;
10675                confp->chan.radio = 0;
10676             } else if (!strcasecmp(v->value, "fxs_ls")) {
10677                confp->chan.sig = SIG_FXSLS;
10678                confp->chan.radio = 0;
10679             } else if (!strcasecmp(v->value, "fxs_gs")) {
10680                confp->chan.sig = SIG_FXSGS;
10681                confp->chan.radio = 0;
10682             } else if (!strcasecmp(v->value, "fxs_ks")) {
10683                confp->chan.sig = SIG_FXSKS;
10684                confp->chan.radio = 0;
10685             } else if (!strcasecmp(v->value, "fxo_ls")) {
10686                confp->chan.sig = SIG_FXOLS;
10687                confp->chan.radio = 0;
10688             } else if (!strcasecmp(v->value, "fxo_gs")) {
10689                confp->chan.sig = SIG_FXOGS;
10690                confp->chan.radio = 0;
10691             } else if (!strcasecmp(v->value, "fxo_ks")) {
10692                confp->chan.sig = SIG_FXOKS;
10693                confp->chan.radio = 0;
10694             } else if (!strcasecmp(v->value, "fxs_rx")) {
10695                confp->chan.sig = SIG_FXSKS;
10696                confp->chan.radio = 1;
10697             } else if (!strcasecmp(v->value, "fxo_rx")) {
10698                confp->chan.sig = SIG_FXOLS;
10699                confp->chan.radio = 1;
10700             } else if (!strcasecmp(v->value, "fxs_tx")) {
10701                confp->chan.sig = SIG_FXSLS;
10702                confp->chan.radio = 1;
10703             } else if (!strcasecmp(v->value, "fxo_tx")) {
10704                confp->chan.sig = SIG_FXOGS;
10705                confp->chan.radio = 1;
10706             } else if (!strcasecmp(v->value, "em_rx")) {
10707                confp->chan.sig = SIG_EM;
10708                confp->chan.radio = 1;
10709             } else if (!strcasecmp(v->value, "em_tx")) {
10710                confp->chan.sig = SIG_EM;
10711                confp->chan.radio = 1;
10712             } else if (!strcasecmp(v->value, "em_rxtx")) {
10713                confp->chan.sig = SIG_EM;
10714                confp->chan.radio = 2;
10715             } else if (!strcasecmp(v->value, "em_txrx")) {
10716                confp->chan.sig = SIG_EM;
10717                confp->chan.radio = 2;
10718             } else if (!strcasecmp(v->value, "sf")) {
10719                confp->chan.sig = SIG_SF;
10720                confp->chan.radio = 0;
10721             } else if (!strcasecmp(v->value, "sf_w")) {
10722                confp->chan.sig = SIG_SFWINK;
10723                confp->chan.radio = 0;
10724             } else if (!strcasecmp(v->value, "sf_featd")) {
10725                confp->chan.sig = SIG_FEATD;
10726                confp->chan.radio = 0;
10727             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10728                confp->chan.sig = SIG_FEATDMF;
10729                confp->chan.radio = 0;
10730             } else if (!strcasecmp(v->value, "sf_featb")) {
10731                confp->chan.sig = SIG_SF_FEATB;
10732                confp->chan.radio = 0;
10733             } else if (!strcasecmp(v->value, "sf")) {
10734                confp->chan.sig = SIG_SF;
10735                confp->chan.radio = 0;
10736             } else if (!strcasecmp(v->value, "sf_rx")) {
10737                confp->chan.sig = SIG_SF;
10738                confp->chan.radio = 1;
10739             } else if (!strcasecmp(v->value, "sf_tx")) {
10740                confp->chan.sig = SIG_SF;
10741                confp->chan.radio = 1;
10742             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10743                confp->chan.sig = SIG_SF;
10744                confp->chan.radio = 2;
10745             } else if (!strcasecmp(v->value, "sf_txrx")) {
10746                confp->chan.sig = SIG_SF;
10747                confp->chan.radio = 2;
10748             } else if (!strcasecmp(v->value, "featd")) {
10749                confp->chan.sig = SIG_FEATD;
10750                confp->chan.radio = 0;
10751             } else if (!strcasecmp(v->value, "featdmf")) {
10752                confp->chan.sig = SIG_FEATDMF;
10753                confp->chan.radio = 0;
10754             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10755                confp->chan.sig = SIG_FEATDMF_TA;
10756                confp->chan.radio = 0;
10757             } else if (!strcasecmp(v->value, "e911")) {
10758                confp->chan.sig = SIG_E911;
10759                confp->chan.radio = 0;
10760             } else if (!strcasecmp(v->value, "fgccama")) {
10761                confp->chan.sig = SIG_FGC_CAMA;
10762                confp->chan.radio = 0;
10763             } else if (!strcasecmp(v->value, "fgccamamf")) {
10764                confp->chan.sig = SIG_FGC_CAMAMF;
10765                confp->chan.radio = 0;
10766             } else if (!strcasecmp(v->value, "featb")) {
10767                confp->chan.sig = SIG_FEATB;
10768                confp->chan.radio = 0;
10769 #ifdef HAVE_PRI
10770             } else if (!strcasecmp(v->value, "pri_net")) {
10771                confp->chan.radio = 0;
10772                confp->chan.sig = SIG_PRI;
10773                confp->pri.nodetype = PRI_NETWORK;
10774             } else if (!strcasecmp(v->value, "pri_cpe")) {
10775                confp->chan.sig = SIG_PRI;
10776                confp->chan.radio = 0;
10777                confp->pri.nodetype = PRI_CPE;
10778             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10779                confp->chan.sig = SIG_GR303FXOKS;
10780                confp->chan.radio = 0;
10781                confp->pri.nodetype = PRI_NETWORK;
10782             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
10783                confp->chan.sig = SIG_GR303FXSKS;
10784                confp->chan.radio = 0;
10785                confp->pri.nodetype = PRI_CPE;
10786 #endif
10787             } else {
10788                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10789             }
10790           } else if (!strcasecmp(v->name, "outsignalling")) {
10791             if (!strcasecmp(v->value, "em")) {
10792                confp->chan.outsigmod = SIG_EM;
10793             } else if (!strcasecmp(v->value, "em_e1")) {
10794                confp->chan.outsigmod = SIG_EM_E1;
10795             } else if (!strcasecmp(v->value, "em_w")) {
10796                confp->chan.outsigmod = SIG_EMWINK;
10797             } else if (!strcasecmp(v->value, "sf")) {
10798                confp->chan.outsigmod = SIG_SF;
10799             } else if (!strcasecmp(v->value, "sf_w")) {
10800                confp->chan.outsigmod = SIG_SFWINK;
10801             } else if (!strcasecmp(v->value, "sf_featd")) {
10802                confp->chan.outsigmod = SIG_FEATD;
10803             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10804                confp->chan.outsigmod = SIG_FEATDMF;
10805             } else if (!strcasecmp(v->value, "sf_featb")) {
10806                confp->chan.outsigmod = SIG_SF_FEATB;
10807             } else if (!strcasecmp(v->value, "sf")) {
10808                confp->chan.outsigmod = SIG_SF;
10809             } else if (!strcasecmp(v->value, "featd")) {
10810                confp->chan.outsigmod = SIG_FEATD;
10811             } else if (!strcasecmp(v->value, "featdmf")) {
10812                confp->chan.outsigmod = SIG_FEATDMF;
10813             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10814                confp->chan.outsigmod = SIG_FEATDMF_TA;
10815             } else if (!strcasecmp(v->value, "e911")) {
10816                confp->chan.outsigmod = SIG_E911;
10817             } else if (!strcasecmp(v->value, "fgccama")) {
10818                confp->chan.outsigmod = SIG_FGC_CAMA;
10819             } else if (!strcasecmp(v->value, "fgccamamf")) {
10820                confp->chan.outsigmod = SIG_FGC_CAMAMF;
10821             } else if (!strcasecmp(v->value, "featb")) {
10822                confp->chan.outsigmod = SIG_FEATB;
10823             } else {
10824                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10825             }
10826 #ifdef HAVE_PRI
10827          } else if (!strcasecmp(v->name, "pridialplan")) {
10828             if (!strcasecmp(v->value, "national")) {
10829                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
10830             } else if (!strcasecmp(v->value, "unknown")) {
10831                confp->pri.dialplan = PRI_UNKNOWN + 1;
10832             } else if (!strcasecmp(v->value, "private")) {
10833                confp->pri.dialplan = PRI_PRIVATE + 1;
10834             } else if (!strcasecmp(v->value, "international")) {
10835                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
10836             } else if (!strcasecmp(v->value, "local")) {
10837                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
10838             } else if (!strcasecmp(v->value, "dynamic")) {
10839                confp->pri.dialplan = -1;
10840             } else {
10841                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10842             }
10843          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
10844             if (!strcasecmp(v->value, "national")) {
10845                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
10846             } else if (!strcasecmp(v->value, "unknown")) {
10847                confp->pri.localdialplan = PRI_UNKNOWN + 1;
10848             } else if (!strcasecmp(v->value, "private")) {
10849                confp->pri.localdialplan = PRI_PRIVATE + 1;
10850             } else if (!strcasecmp(v->value, "international")) {
10851                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
10852             } else if (!strcasecmp(v->value, "local")) {
10853                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
10854             } else if (!strcasecmp(v->value, "dynamic")) {
10855                confp->pri.localdialplan = -1;
10856             } else {
10857                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10858             }
10859          } else if (!strcasecmp(v->name, "switchtype")) {
10860             if (!strcasecmp(v->value, "national")) 
10861                confp->pri.switchtype = PRI_SWITCH_NI2;
10862             else if (!strcasecmp(v->value, "ni1"))
10863                confp->pri.switchtype = PRI_SWITCH_NI1;
10864             else if (!strcasecmp(v->value, "dms100"))
10865                confp->pri.switchtype = PRI_SWITCH_DMS100;
10866             else if (!strcasecmp(v->value, "4ess"))
10867                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
10868             else if (!strcasecmp(v->value, "5ess"))
10869                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
10870             else if (!strcasecmp(v->value, "euroisdn"))
10871                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
10872             else if (!strcasecmp(v->value, "qsig"))
10873                confp->pri.switchtype = PRI_SWITCH_QSIG;
10874             else {
10875                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
10876                return -1;
10877             }
10878          } else if (!strcasecmp(v->name, "nsf")) {
10879             if (!strcasecmp(v->value, "sdn"))
10880                confp->pri.nsf = PRI_NSF_SDN;
10881             else if (!strcasecmp(v->value, "megacom"))
10882                confp->pri.nsf = PRI_NSF_MEGACOM;
10883             else if (!strcasecmp(v->value, "tollfreemegacom"))
10884                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
10885             else if (!strcasecmp(v->value, "accunet"))
10886                confp->pri.nsf = PRI_NSF_ACCUNET;
10887             else if (!strcasecmp(v->value, "none"))
10888                confp->pri.nsf = PRI_NSF_NONE;
10889             else {
10890                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
10891                confp->pri.nsf = PRI_NSF_NONE;
10892             }
10893          } else if (!strcasecmp(v->name, "priindication")) {
10894             if (!strcasecmp(v->value, "outofband"))
10895                confp->chan.priindication_oob = 1;
10896             else if (!strcasecmp(v->value, "inband"))
10897                confp->chan.priindication_oob = 0;
10898             else
10899                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
10900                   v->value, v->lineno);
10901          } else if (!strcasecmp(v->name, "priexclusive")) {
10902             confp->chan.priexclusive = ast_true(v->value);
10903          } else if (!strcasecmp(v->name, "internationalprefix")) {
10904             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
10905          } else if (!strcasecmp(v->name, "nationalprefix")) {
10906             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
10907          } else if (!strcasecmp(v->name, "localprefix")) {
10908             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
10909          } else if (!strcasecmp(v->name, "privateprefix")) {
10910             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
10911          } else if (!strcasecmp(v->name, "unknownprefix")) {
10912             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
10913          } else if (!strcasecmp(v->name, "resetinterval")) {
10914             if (!strcasecmp(v->value, "never"))
10915                confp->pri.resetinterval = -1;
10916             else if (atoi(v->value) >= 60)
10917                confp->pri.resetinterval = atoi(v->value);
10918             else
10919                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
10920                   v->value, v->lineno);
10921          } else if (!strcasecmp(v->name, "minunused")) {
10922             confp->pri.minunused = atoi(v->value);
10923          } else if (!strcasecmp(v->name, "minidle")) {
10924             confp->pri.minidle = atoi(v->value); 
10925          } else if (!strcasecmp(v->name, "idleext")) {
10926             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
10927          } else if (!strcasecmp(v->name, "idledial")) {
10928             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
10929          } else if (!strcasecmp(v->name, "overlapdial")) {
10930             confp->pri.overlapdial = ast_true(v->value);
10931          } else if (!strcasecmp(v->name, "pritimer")) {
10932 #ifdef PRI_GETSET_TIMERS
10933             char *timerc, *c;
10934             int timer, timeridx;
10935             c = v->value;
10936             timerc = strsep(&c, ",");
10937             if (timerc) {
10938                timer = atoi(c);
10939                if (!timer)
10940                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
10941                else {
10942                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
10943                      pritimers[timeridx] = timer;
10944                   else
10945                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
10946                }
10947             } else
10948                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
10949 
10950          } else if (!strcasecmp(v->name, "facilityenable")) {
10951             confp->pri.facilityenable = ast_true(v->value);
10952 #endif /* PRI_GETSET_TIMERS */
10953 #endif /* HAVE_PRI */
10954          } else if (!strcasecmp(v->name, "cadence")) {
10955             /* setup to scan our argument */
10956             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
10957             int i;
10958             struct zt_ring_cadence new_cadence;
10959             int cid_location = -1;
10960             int firstcadencepos = 0;
10961             char original_args[80];
10962             int cadence_is_ok = 1;
10963 
10964             ast_copy_string(original_args, v->value, sizeof(original_args));
10965             /* 16 cadences allowed (8 pairs) */
10966             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]);
10967    
10968             /* Cadence must be even (on/off) */
10969             if (element_count % 2 == 1) {
10970                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
10971                cadence_is_ok = 0;
10972             }
10973    
10974             /* Ring cadences cannot be negative */
10975             for (i = 0; i < element_count; i++) {
10976                if (c[i] == 0) {
10977                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
10978                   cadence_is_ok = 0;
10979                   break;
10980                } else if (c[i] < 0) {
10981                   if (i % 2 == 1) {
10982                      /* Silence duration, negative possibly okay */
10983                      if (cid_location == -1) {
10984                         cid_location = i;
10985                         c[i] *= -1;
10986                      } else {
10987                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
10988                         cadence_is_ok = 0;
10989                         break;
10990                      }
10991                   } else {
10992                      if (firstcadencepos == 0) {
10993                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
10994                                  /* duration will be passed negative to the zaptel driver */
10995                      } else {
10996                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
10997                         cadence_is_ok = 0;
10998                         break;
10999                      }
11000                   }
11001                }
11002             }
11003    
11004             /* Substitute our scanned cadence */
11005             for (i = 0; i < 16; i++) {
11006                new_cadence.ringcadence[i] = c[i];
11007             }
11008    
11009             if (cadence_is_ok) {
11010                /* ---we scanned it without getting annoyed; now some sanity checks--- */
11011                if (element_count < 2) {
11012                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
11013                } else {
11014                   if (cid_location == -1) {
11015                      /* user didn't say; default to first pause */
11016                      cid_location = 1;
11017                   } else {
11018                      /* convert element_index to cidrings value */
11019                      cid_location = (cid_location + 1) / 2;
11020                   }
11021                   /* ---we like their cadence; try to install it--- */
11022                   if (!user_has_defined_cadences++)
11023                      /* this is the first user-defined cadence; clear the default user cadences */
11024                      num_cadence = 0;
11025                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
11026                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
11027                   else {
11028                      cadences[num_cadence] = new_cadence;
11029                      cidrings[num_cadence++] = cid_location;
11030                      if (option_verbose > 2)
11031                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
11032                   }
11033                }
11034             }
11035          } else if (!strcasecmp(v->name, "ringtimeout")) {
11036             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
11037          } else if (!strcasecmp(v->name, "prewink")) {
11038             confp->timing.prewinktime = atoi(v->value);
11039          } else if (!strcasecmp(v->name, "preflash")) {
11040             confp->timing.preflashtime = atoi(v->value);
11041          } else if (!strcasecmp(v->name, "wink")) {
11042             confp->timing.winktime = atoi(v->value);
11043          } else if (!strcasecmp(v->name, "flash")) {
11044             confp->timing.flashtime = atoi(v->value);
11045          } else if (!strcasecmp(v->name, "start")) {
11046             confp->timing.starttime = atoi(v->value);
11047          } else if (!strcasecmp(v->name, "rxwink")) {
11048             confp->timing.rxwinktime = atoi(v->value);
11049          } else if (!strcasecmp(v->name, "rxflash")) {
11050             confp->timing.rxflashtime = atoi(v->value);
11051          } else if (!strcasecmp(v->name, "debounce")) {
11052             confp->timing.debouncetime = atoi(v->value);
11053          } else if (!strcasecmp(v->name, "toneduration")) {
11054             int toneduration;
11055             int ctlfd;
11056             int res;
11057             struct zt_dialparams dps;
11058 
11059             ctlfd = open("/dev/zap/ctl", O_RDWR);
11060             if (ctlfd == -1) {
11061                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11062                return -1;
11063             }
11064 
11065             toneduration = atoi(v->value);
11066             if (toneduration > -1) {
11067                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11068                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11069                if (res < 0) {
11070                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11071                   return -1;
11072                }
11073             }
11074             close(ctlfd);
11075          } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
11076             confp->chan.polarityonanswerdelay = atoi(v->value);
11077          } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
11078             confp->chan.answeronpolarityswitch = ast_true(v->value);
11079          } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
11080             confp->chan.hanguponpolarityswitch = ast_true(v->value);
11081          } else if (!strcasecmp(v->name, "sendcalleridafter")) {
11082             confp->chan.sendcalleridafter = atoi(v->value);
11083          } else if (!strcasecmp(v->name, "defaultcic")) {
11084             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11085          } else if (!strcasecmp(v->name, "defaultozz")) {
11086             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11087          } 
11088       } else if (!skipchannels)
11089          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11090    }
11091    if (zapchan[0]) { 
11092       /* The user has set 'zapchan' */
11093       /*< \todo pass proper line number instead of 0 */
11094       if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
11095          return -1;
11096       }
11097    }
11098    /*< \todo why check for the pseudo in the per-channel section.
11099     * Any actual use for manual setup of the pseudo channel? */
11100    if (!found_pseudo && reload == 0) {
11101       /* Make sure pseudo isn't a member of any groups if
11102          we're automatically making it. */   
11103       
11104       confp->chan.group = 0;
11105       confp->chan.callgroup = 0;
11106       confp->chan.pickupgroup = 0;
11107 
11108       tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
11109 
11110       if (tmp) {
11111          if (option_verbose > 2)
11112             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11113       } else {
11114          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11115       }
11116    }
11117    return 0;
11118 }
11119       
11120 static int setup_zap(int reload)
11121 {
11122    struct ast_config *cfg;
11123    struct ast_variable *v;
11124    struct zt_chan_conf conf = zt_chan_conf_default();
11125    int res;
11126 
11127 #ifdef HAVE_PRI
11128    char *c;
11129    int spanno;
11130    int i, x;
11131    int logicalspan;
11132    int trunkgroup;
11133    int dchannels[NUM_DCHANS];
11134 #endif
11135 
11136    cfg = ast_config_load(config);
11137 
11138    /* Error if we have no config file */
11139    if (!cfg) {
11140       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
11141       return 0;
11142    }
11143 
11144    /* It's a little silly to lock it, but we mind as well just to be sure */
11145    ast_mutex_lock(&iflock);
11146 #ifdef HAVE_PRI
11147    if (!reload) {
11148       /* Process trunkgroups first */
11149       v = ast_variable_browse(cfg, "trunkgroups");
11150       while (v) {
11151          if (!strcasecmp(v->name, "trunkgroup")) {
11152             trunkgroup = atoi(v->value);
11153             if (trunkgroup > 0) {
11154                if ((c = strchr(v->value, ','))) {
11155                   i = 0;
11156                   memset(dchannels, 0, sizeof(dchannels));
11157                   while (c && (i < NUM_DCHANS)) {
11158                      dchannels[i] = atoi(c + 1);
11159                      if (dchannels[i] < 0) {
11160                         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);
11161                      } else
11162                         i++;
11163                      c = strchr(c + 1, ',');
11164                   }
11165                   if (i) {
11166                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
11167                         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);
11168                      } else if (option_verbose > 1)
11169                         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");
11170                   } else
11171                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
11172                } else
11173                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
11174             } else
11175                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
11176          } else if (!strcasecmp(v->name, "spanmap")) {
11177             spanno = atoi(v->value);
11178             if (spanno > 0) {
11179                if ((c = strchr(v->value, ','))) {
11180                   trunkgroup = atoi(c + 1);
11181                   if (trunkgroup > 0) {
11182                      if ((c = strchr(c + 1, ','))) 
11183                         logicalspan = atoi(c + 1);
11184                      else
11185                         logicalspan = 0;
11186                      if (logicalspan >= 0) {
11187                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
11188                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11189                         } else if (option_verbose > 1) 
11190                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11191                      } else
11192                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
11193                   } else
11194                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
11195                } else
11196                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
11197             } else
11198                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
11199          } else {
11200             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
11201          }
11202          v = v->next;
11203       }
11204    }
11205 #endif
11206    
11207    /* Copy the default jb config over global_jbconf */
11208    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
11209 
11210    v = ast_variable_browse(cfg, "channels");
11211    res = process_zap(&conf, v, reload, 0);
11212    ast_mutex_unlock(&iflock);
11213    ast_config_destroy(cfg);
11214    if (res)
11215       return res;
11216    cfg = ast_config_load("users.conf");
11217    if (cfg) {
11218       char *cat;
11219       const char *chans;
11220       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
11221       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
11222          if (!strcasecmp(cat, "general"))
11223             continue;
11224          chans = ast_variable_retrieve(cfg, cat, "zapchan");
11225          if (!ast_strlen_zero(chans)) {
11226             /** \todo At this point we should probably 
11227              * duplicate conf, and pass a copy, to prevent 
11228              * one section from affecting another
11229              */
11230             process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
11231          }
11232       }
11233       ast_config_destroy(cfg);
11234    }
11235 #ifdef HAVE_PRI
11236    if (!reload) {
11237       for (x = 0; x < NUM_SPANS; x++) {
11238          if (pris[x].pvts[0]) {
11239             if (start_pri(pris + x)) {
11240                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11241                return -1;
11242             } else if (option_verbose > 1)
11243                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11244          }
11245       }
11246    }
11247 #endif
11248    /* And start the monitor for the first time */
11249    restart_monitor();
11250    return 0;
11251 }
11252 
11253 static int load_module(void)
11254 {
11255    int res;
11256 
11257 #ifdef HAVE_PRI
11258    int y,i;
11259    memset(pris, 0, sizeof(pris));
11260    for (y = 0; y < NUM_SPANS; y++) {
11261       ast_mutex_init(&pris[y].lock);
11262       pris[y].offset = -1;
11263       pris[y].master = AST_PTHREADT_NULL;
11264       for (i = 0; i < NUM_DCHANS; i++)
11265          pris[y].fds[i] = -1;
11266    }
11267    pri_set_error(zt_pri_error);
11268    pri_set_message(zt_pri_message);
11269    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
11270          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
11271 #endif
11272    res = setup_zap(0);
11273    /* Make sure we can register our Zap channel type */
11274    if (res)
11275       return AST_MODULE_LOAD_DECLINE;
11276    if (ast_channel_register(&zap_tech)) {
11277       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
11278       __unload_module();
11279       return -1;
11280    }
11281 #ifdef HAVE_PRI
11282    ast_string_field_init(&inuse, 16);
11283    ast_string_field_set(&inuse, name, "GR-303InUse");
11284    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11285 #endif   
11286    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11287    
11288    memset(round_robin, 0, sizeof(round_robin));
11289    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11290    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11291    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11292    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11293    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11294    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11295    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
11296 
11297    return res;
11298 }
11299 
11300 static int zt_sendtext(struct ast_channel *c, const char *text)
11301 {
11302 #define  END_SILENCE_LEN 400
11303 #define  HEADER_MS 50
11304 #define  TRAILER_MS 5
11305 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11306 #define  ASCII_BYTES_PER_CHAR 80
11307 
11308    unsigned char *buf,*mybuf;
11309    struct zt_pvt *p = c->tech_pvt;
11310    struct pollfd fds[1];
11311    int size,res,fd,len,x;
11312    int bytes=0;
11313    /* Initial carrier (imaginary) */
11314    float cr = 1.0;
11315    float ci = 0.0;
11316    float scont = 0.0;
11317    int index;
11318 
11319    index = zt_get_index(c, p, 0);
11320    if (index < 0) {
11321       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11322       return -1;
11323    }
11324    if (!text[0]) return(0); /* if nothing to send, dont */
11325    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11326    if (p->mate) 
11327       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11328    else
11329       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11330    if (!buf)
11331       return -1;
11332    mybuf = buf;
11333    if (p->mate) {
11334       int codec = AST_LAW(p);
11335       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
11336          PUT_CLID_MARKMS;
11337       }
11338       /* Put actual message */
11339       for (x = 0; text[x]; x++) {
11340          PUT_CLID(text[x]);
11341       }
11342       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
11343          PUT_CLID_MARKMS;
11344       }
11345       len = bytes;
11346       buf = mybuf;
11347    } else {
11348       len = tdd_generate(p->tdd, buf, text);
11349       if (len < 1) {
11350          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
11351          free(mybuf);
11352          return -1;
11353       }
11354    }
11355    memset(buf + len, 0x7f, END_SILENCE_LEN);
11356    len += END_SILENCE_LEN;
11357    fd = p->subs[index].zfd;
11358    while (len) {
11359       if (ast_check_hangup(c)) {
11360          free(mybuf);
11361          return -1;
11362       }
11363       size = len;
11364       if (size > READ_SIZE)
11365          size = READ_SIZE;
11366       fds[0].fd = fd;
11367       fds[0].events = POLLOUT | POLLPRI;
11368       fds[0].revents = 0;
11369       res = poll(fds, 1, -1);
11370       if (!res) {
11371          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11372          continue;
11373       }
11374         /* if got exception */
11375       if (fds[0].revents & POLLPRI)
11376          return -1;
11377       if (!(fds[0].revents & POLLOUT)) {
11378          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11379          continue;
11380       }
11381       res = write(fd, buf, size);
11382       if (res != size) {
11383          if (res == -1) {
11384             free(mybuf);
11385             return -1;
11386          }
11387          if (option_debug)
11388             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11389          break;
11390       }
11391       len -= size;
11392       buf += size;
11393    }
11394    free(mybuf);
11395    return(0);
11396 }
11397 
11398 
11399 static int reload(void)
11400 {
11401    int res = 0;
11402 
11403    res = setup_zap(1);
11404    if (res) {
11405       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11406       return -1;
11407    }
11408    return 0;
11409 }
11410 
11411 /* This is a workaround so that menuselect displays a proper description
11412  * AST_MODULE_INFO(, , "Zapata Telephony"
11413  */
11414 
11415 #ifdef ZAPATA_PRI
11416 #define tdesc "Zapata Telephony w/PRI"
11417 #else
11418 #define tdesc "Zapata Telephony"
11419 #endif
11420 
11421 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
11422       .load = load_module,
11423       .unload = unload_module,
11424       .reload = reload,
11425           );
11426 
11427 

Generated on Mon Apr 30 07:36:33 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1