Tue Nov 4 13:20:17 2008

Asterisk developer's documentation


chan_zap.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Zaptel Pseudo TDM interface 
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Connects to the zaptel telephony library as well as 
00026  * libpri. Libpri is optional and needed only if you are
00027  * going to use ISDN connections.
00028  *
00029  * You need to install libraries before you attempt to compile
00030  * and install the zaptel channel.
00031  *
00032  * \par See also
00033  * \arg \ref Config_zap
00034  *
00035  * \ingroup channel_drivers
00036  *
00037  * \todo Deprecate the "musiconhold" configuration option post 1.4
00038  */
00039 
00040 /*** MODULEINFO
00041    <depend>res_smdi</depend>
00042    <depend>zaptel_vldtmf</depend>
00043    <depend>zaptel</depend>
00044    <depend>tonezone</depend>
00045    <depend>res_features</depend>
00046    <use>pri</use>
00047  ***/
00048 
00049 #include "asterisk.h"
00050 
00051 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 120425 $")
00052 
00053 #include <stdio.h>
00054 #include <string.h>
00055 #ifdef __NetBSD__
00056 #include <pthread.h>
00057 #include <signal.h>
00058 #else
00059 #include <sys/signal.h>
00060 #endif
00061 #include <errno.h>
00062 #include <stdlib.h>
00063 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00064 #include <stdint.h>
00065 #endif
00066 #include <unistd.h>
00067 #include <sys/ioctl.h>
00068 #include <math.h>
00069 #include <ctype.h>
00070 #include <zaptel/zaptel.h>
00071 #include <zaptel/tonezone.h>
00072 
00073 #ifdef HAVE_PRI
00074 #include <libpri.h>
00075 #endif
00076 
00077 #include "asterisk/lock.h"
00078 #include "asterisk/channel.h"
00079 #include "asterisk/config.h"
00080 #include "asterisk/logger.h"
00081 #include "asterisk/module.h"
00082 #include "asterisk/pbx.h"
00083 #include "asterisk/options.h"
00084 #include "asterisk/file.h"
00085 #include "asterisk/ulaw.h"
00086 #include "asterisk/alaw.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/adsi.h"
00089 #include "asterisk/cli.h"
00090 #include "asterisk/cdr.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/musiconhold.h"
00093 #include "asterisk/say.h"
00094 #include "asterisk/tdd.h"
00095 #include "asterisk/app.h"
00096 #include "asterisk/dsp.h"
00097 #include "asterisk/astdb.h"
00098 #include "asterisk/manager.h"
00099 #include "asterisk/causes.h"
00100 #include "asterisk/term.h"
00101 #include "asterisk/utils.h"
00102 #include "asterisk/transcap.h"
00103 #include "asterisk/stringfields.h"
00104 #include "asterisk/abstract_jb.h"
00105 #include "asterisk/smdi.h"
00106 #include "asterisk/astobj.h"
00107 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00108 
00109 /*! Global jitterbuffer configuration - by default, jb is disabled */
00110 static struct ast_jb_conf default_jbconf =
00111 {
00112    .flags = 0,
00113    .max_size = -1,
00114    .resync_threshold = -1,
00115    .impl = ""
00116 };
00117 static struct ast_jb_conf global_jbconf;
00118 
00119 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00120 #error "Your zaptel is too old.  Please update"
00121 #endif
00122 
00123 #ifndef ZT_TONEDETECT
00124 /* Work around older code with no tone detect */
00125 #define ZT_EVENT_DTMFDOWN 0
00126 #define ZT_EVENT_DTMFUP 0
00127 #endif
00128 
00129 /* define this to send PRI user-user information elements */
00130 #undef SUPPORT_USERUSER
00131 
00132 /*! 
00133  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00134  * the user hangs up to reset the state machine so ring works properly.
00135  * This is used to be able to support kewlstart by putting the zhone in
00136  * groundstart mode since their forward disconnect supervision is entirely
00137  * broken even though their documentation says it isn't and their support
00138  * is entirely unwilling to provide any assistance with their channel banks
00139  * even though their web site says they support their products for life.
00140  */
00141 /* #define ZHONE_HACK */
00142 
00143 /*! \note
00144  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00145  * before dialing on it.  Certain FXO interfaces always think they're out of
00146  * service with this method however.
00147  */
00148 /* #define ZAP_CHECK_HOOKSTATE */
00149 
00150 /*! \brief Typically, how many rings before we should send Caller*ID */
00151 #define DEFAULT_CIDRINGS 1
00152 
00153 #define CHANNEL_PSEUDO -12
00154 
00155 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00156 
00157 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00158 #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)) 
00159 
00160 static const char tdesc[] = "Zapata Telephony Driver"
00161 #ifdef HAVE_PRI
00162                " w/PRI"
00163 #endif
00164 ;
00165 
00166 static const char config[] = "zapata.conf";
00167 
00168 #define SIG_EM    ZT_SIG_EM
00169 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00170 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00171 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00172 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00173 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00174 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00175 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00176 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00177 #define SIG_FXSLS ZT_SIG_FXSLS
00178 #define SIG_FXSGS ZT_SIG_FXSGS
00179 #define SIG_FXSKS ZT_SIG_FXSKS
00180 #define SIG_FXOLS ZT_SIG_FXOLS
00181 #define SIG_FXOGS ZT_SIG_FXOGS
00182 #define SIG_FXOKS ZT_SIG_FXOKS
00183 #define SIG_PRI      ZT_SIG_CLEAR
00184 #define  SIG_SF      ZT_SIG_SF
00185 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00186 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00187 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00188 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00189 #define SIG_EM_E1 ZT_SIG_EM_E1
00190 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00191 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00192 
00193 #define NUM_SPANS       32
00194 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00195 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00196 
00197 #define CHAN_PSEUDO  -2
00198 
00199 #define DCHAN_PROVISIONED (1 << 0)
00200 #define DCHAN_NOTINALARM  (1 << 1)
00201 #define DCHAN_UP          (1 << 2)
00202 
00203 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00204 
00205 static char defaultcic[64] = "";
00206 static char defaultozz[64] = "";
00207 
00208 static char progzone[10] = "";
00209 
00210 static int distinctiveringaftercid = 0;
00211 
00212 static int numbufs = 4;
00213 
00214 #ifdef HAVE_PRI
00215 static struct ast_channel inuse;
00216 #ifdef PRI_GETSET_TIMERS
00217 static int pritimers[PRI_MAX_TIMERS];
00218 #endif
00219 static int pridebugfd = -1;
00220 static char pridebugfilename[1024] = "";
00221 #endif
00222 
00223 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00224 static int firstdigittimeout = 16000;
00225 
00226 /*! \brief How long to wait for following digits (FXO logic) */
00227 static int gendigittimeout = 8000;
00228 
00229 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00230 static int matchdigittimeout = 3000;
00231 
00232 /*! \brief Protect the interface list (of zt_pvt's) */
00233 AST_MUTEX_DEFINE_STATIC(iflock);
00234 
00235 
00236 static int ifcount = 0;
00237 
00238 #ifdef HAVE_PRI
00239 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00240 #endif
00241 
00242 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00243    when it's doing something critical. */
00244 AST_MUTEX_DEFINE_STATIC(monlock);
00245 
00246 /*! \brief This is the thread for the monitor which checks for input on the channels
00247    which are not currently in use. */
00248 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00249 
00250 static int restart_monitor(void);
00251 
00252 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);
00253 
00254 static int zt_sendtext(struct ast_channel *c, const char *text);
00255 
00256 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00257 static inline int zt_get_event(int fd)
00258 {
00259    int j;
00260    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00261       return -1;
00262    return j;
00263 }
00264 
00265 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00266 static inline int zt_wait_event(int fd)
00267 {
00268    int i, j = 0;
00269    i = ZT_IOMUX_SIGEVENT;
00270    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00271       return -1;
00272    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00273       return -1;
00274    return j;
00275 }
00276 
00277 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00278 #define READ_SIZE 160
00279 
00280 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00281 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00282 
00283 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00284 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
00285 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00286 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00287 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
00288 
00289 struct zt_pvt;
00290 
00291 static int ringt_base = DEFAULT_RINGT;
00292 
00293 #ifdef HAVE_PRI
00294 
00295 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00296 #define PRI_CHANNEL(p) ((p) & 0xff)
00297 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00298 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00299 
00300 struct zt_pri {
00301    pthread_t master;                /*!< Thread of master */
00302    ast_mutex_t lock;                /*!< Mutex */
00303    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00304    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00305    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00306    int minunused;                   /*!< Min # of channels to keep empty */
00307    int minidle;                     /*!< Min # of "idling" calls to keep active */
00308    int nodetype;                    /*!< Node type */
00309    int switchtype;                     /*!< Type of switch to emulate */
00310    int nsf;                   /*!< Network-Specific Facilities */
00311    int dialplan;                    /*!< Dialing plan */
00312    int localdialplan;                  /*!< Local dialing plan */
00313    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00314    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00315    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00316    char privateprefix[20];                /*!< for private dialplans */
00317    char unknownprefix[20];                /*!< for unknown dialplans */
00318    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00319    int trunkgroup;                     /*!< What our trunkgroup is */
00320    int mastertrunkgroup;                  /*!< What trunk group is our master */
00321    int prilogicalspan;                 /*!< Logical span number within trunk group */
00322    int numchans;                    /*!< Num of channels we represent */
00323    int overlapdial;                 /*!< In overlap dialing mode */
00324    int facilityenable;                 /*!< Enable facility IEs */
00325    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00326    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00327    struct pri *pri;                 /*!< Currently active D-channel */
00328    int debug;
00329    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00330    int offset;
00331    int span;
00332    int resetting;
00333    int resetpos;
00334    time_t lastreset;                /*!< time when unused channels were last reset */
00335    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00336    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00337    struct zt_pvt *crvs;                /*!< Member CRV structs */
00338    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00339 };
00340 
00341 
00342 static struct zt_pri pris[NUM_SPANS];
00343 
00344 #if 0
00345 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00346 #else
00347 #define DEFAULT_PRI_DEBUG 0
00348 #endif
00349 
00350 static inline void pri_rel(struct zt_pri *pri)
00351 {
00352    ast_mutex_unlock(&pri->lock);
00353 }
00354 
00355 #else
00356 /*! Shut up the compiler */
00357 struct zt_pri;
00358 #endif
00359 
00360 #define SUB_REAL  0        /*!< Active call */
00361 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00362 #define SUB_THREEWAY 2        /*!< Three-way call */
00363 
00364 /* Polarity states */
00365 #define POLARITY_IDLE   0
00366 #define POLARITY_REV    1
00367 
00368 
00369 static struct zt_distRings drings;
00370 
00371 struct distRingData {
00372    int ring[3];
00373 };
00374 struct ringContextData {
00375    char contextData[AST_MAX_CONTEXT];
00376 };
00377 struct zt_distRings {
00378    struct distRingData ringnum[3];
00379    struct ringContextData ringContext[3];
00380 };
00381 
00382 static char *subnames[] = {
00383    "Real",
00384    "Callwait",
00385    "Threeway"
00386 };
00387 
00388 struct zt_subchannel {
00389    int zfd;
00390    struct ast_channel *owner;
00391    int chan;
00392    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00393    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00394    unsigned int needringing:1;
00395    unsigned int needbusy:1;
00396    unsigned int needcongestion:1;
00397    unsigned int needcallerid:1;
00398    unsigned int needanswer:1;
00399    unsigned int needflash:1;
00400    unsigned int needhold:1;
00401    unsigned int needunhold:1;
00402    unsigned int linear:1;
00403    unsigned int inthreeway:1;
00404    ZT_CONFINFO curconf;
00405 };
00406 
00407 #define CONF_USER_REAL     (1 << 0)
00408 #define CONF_USER_THIRDCALL   (1 << 1)
00409 
00410 #define MAX_SLAVES   4
00411 
00412 static struct zt_pvt {
00413    ast_mutex_t lock;
00414    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00415                      /*!< Up to three channels can be associated with this call */
00416       
00417    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00418    struct zt_subchannel subs[3];       /*!< Sub-channels */
00419    struct zt_confinfo saveconf;        /*!< Saved conference info */
00420 
00421    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00422    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00423    int inconference;          /*!< If our real should be in the conference */
00424    
00425    int sig;             /*!< Signalling style */
00426    int radio;              /*!< radio type */
00427    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00428    int oprmode;               /*!< "Operator Services" mode */
00429    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00430    float rxgain;
00431    float txgain;
00432    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00433    struct zt_pvt *next;          /*!< Next channel in list */
00434    struct zt_pvt *prev;          /*!< Prev channel in list */
00435 
00436    /* flags */
00437    unsigned int adsi:1;
00438    unsigned int answeronpolarityswitch:1;
00439    unsigned int busydetect:1;
00440    unsigned int callreturn:1;
00441    unsigned int callwaiting:1;
00442    unsigned int callwaitingcallerid:1;
00443    unsigned int cancallforward:1;
00444    unsigned int canpark:1;
00445    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00446    unsigned int destroy:1;
00447    unsigned int didtdd:1;           /*!< flag to say its done it once */
00448    unsigned int dialednone:1;
00449    unsigned int dialing:1;
00450    unsigned int digital:1;
00451    unsigned int dnd:1;
00452    unsigned int echobreak:1;
00453    unsigned int echocanbridged:1;
00454    unsigned int echocanon:1;
00455    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00456    unsigned int firstradio:1;
00457    unsigned int hanguponpolarityswitch:1;
00458    unsigned int hardwaredtmf:1;
00459    unsigned int hidecallerid:1;
00460    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00461    unsigned int ignoredtmf:1;
00462    unsigned int immediate:1;        /*!< Answer before getting digits? */
00463    unsigned int inalarm:1;
00464    unsigned int unknown_alarm:1;
00465    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00466    unsigned int outgoing:1;
00467    unsigned int overlapdial:1;
00468    unsigned int permcallwaiting:1;
00469    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00470    unsigned int priindication_oob:1;
00471    unsigned int priexclusive:1;
00472    unsigned int pulse:1;
00473    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00474    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00475    unsigned int threewaycalling:1;
00476    unsigned int transfer:1;
00477    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00478    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00479    unsigned int usedistinctiveringdetection:1;
00480    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00481    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00482 #if defined(HAVE_PRI)
00483    unsigned int alerting:1;
00484    unsigned int alreadyhungup:1;
00485    unsigned int isidlecall:1;
00486    unsigned int proceeding:1;
00487    unsigned int progress:1;
00488    unsigned int resetting:1;
00489    unsigned int setup_ack:1;
00490 #endif
00491    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00492    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00493 
00494    struct zt_distRings drings;
00495 
00496    char context[AST_MAX_CONTEXT];
00497    char defcontext[AST_MAX_CONTEXT];
00498    char exten[AST_MAX_EXTENSION];
00499    char language[MAX_LANGUAGE];
00500    char mohinterpret[MAX_MUSICCLASS];
00501    char mohsuggest[MAX_MUSICCLASS];
00502 #ifdef PRI_ANI
00503    char cid_ani[AST_MAX_EXTENSION];
00504 #endif
00505    char cid_num[AST_MAX_EXTENSION];
00506    int cid_ton;               /*!< Type Of Number (TON) */
00507    char cid_name[AST_MAX_EXTENSION];
00508    char lastcid_num[AST_MAX_EXTENSION];
00509    char lastcid_name[AST_MAX_EXTENSION];
00510    char *origcid_num;            /*!< malloced original callerid */
00511    char *origcid_name;           /*!< malloced original callerid */
00512    char callwait_num[AST_MAX_EXTENSION];
00513    char callwait_name[AST_MAX_EXTENSION];
00514    char rdnis[AST_MAX_EXTENSION];
00515    char dnid[AST_MAX_EXTENSION];
00516    ast_group_t group;
00517    int law;
00518    int confno;             /*!< Our conference */
00519    int confusers;             /*!< Who is using our conference */
00520    int propconfno;               /*!< Propagated conference number */
00521    ast_group_t callgroup;
00522    ast_group_t pickupgroup;
00523    int channel;               /*!< Channel Number or CRV */
00524    int span;               /*!< Span number */
00525    time_t guardtime;          /*!< Must wait this much time before using for new call */
00526    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00527    int cid_start;             /*!< CID start indicator, polarity or ring */
00528    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00529    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00530    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00531    unsigned char *cidspill;
00532    int cidpos;
00533    int cidlen;
00534    int ringt;
00535    int ringt_base;
00536    int stripmsd;
00537    int callwaitcas;
00538    int callwaitrings;
00539    int echocancel;
00540    int echotraining;
00541    char echorest[20];
00542    int busycount;
00543    int busycompare;
00544    int busytonelength;
00545    int busyquietlength;
00546    int busyfuzziness;
00547    int silencethreshold;
00548    int callprogress;
00549    struct timeval flashtime;        /*!< Last flash-hook time */
00550    struct ast_dsp *dsp;
00551    int cref;               /*!< Call reference number */
00552    ZT_DIAL_OPERATION dop;
00553    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00554    char finaldial[64];
00555    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00556    int amaflags;              /*!< AMA Flags */
00557    struct tdd_state *tdd;           /*!< TDD flag */
00558    char call_forward[AST_MAX_EXTENSION];
00559    char mailbox[AST_MAX_EXTENSION];
00560    char dialdest[256];
00561    int onhooktime;
00562    int msgstate;
00563    int distinctivering;          /*!< Which distinctivering to use */
00564    int cidrings;              /*!< Which ring to deliver CID on */
00565    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00566    int fake_event;
00567    int polarityonanswerdelay;
00568    struct timeval polaritydelaytv;
00569    int sendcalleridafter;
00570 #ifdef HAVE_PRI
00571    struct zt_pri *pri;
00572    struct zt_pvt *bearer;
00573    struct zt_pvt *realcall;
00574    q931_call *call;
00575    int prioffset;
00576    int logicalspan;
00577 #endif   
00578    int polarity;
00579    int dsp_features;
00580    char begindigit;
00581 } *iflist = NULL, *ifend = NULL;
00582 
00583 /*! \brief Channel configuration from zapata.conf .
00584  * This struct is used for parsing the [channels] section of zapata.conf.
00585  * Generally there is a field here for every possible configuration item.
00586  *
00587  * The state of fields is saved along the parsing and whenever a 'channel'
00588  * statement is reached, the current zt_chan_conf is used to configure the 
00589  * channel (struct zt_pvt)
00590  *
00591  * @seealso zt_chan_init for the default values.
00592  */
00593 struct zt_chan_conf {
00594    struct zt_pvt chan;
00595 #ifdef HAVE_PRI
00596    struct zt_pri pri;
00597 #endif
00598    ZT_PARAMS timing;
00599 
00600    char smdi_port[SMDI_MAX_FILENAME_LEN];
00601 };
00602 
00603 /** returns a new zt_chan_conf with default values (by-value) */
00604 static struct zt_chan_conf zt_chan_conf_default(void) {
00605    /* recall that if a field is not included here it is initialized
00606     * to 0 or equivalent
00607     */
00608    struct zt_chan_conf conf = {
00609 #ifdef HAVE_PRI
00610       .pri = {
00611          .nsf = PRI_NSF_NONE,
00612          .switchtype = PRI_SWITCH_NI2,
00613          .dialplan = PRI_NATIONAL_ISDN + 1,
00614          .localdialplan = PRI_NATIONAL_ISDN + 1,
00615          .nodetype = PRI_CPE,
00616 
00617          .minunused = 2,
00618          .idleext = "",
00619          .idledial = "",
00620          .internationalprefix = "",
00621          .nationalprefix = "",
00622          .localprefix = "",
00623          .privateprefix = "",
00624          .unknownprefix = "",
00625 
00626          .resetinterval = 3600
00627       },
00628 #endif
00629       .chan = {
00630          .context = "default",
00631          .cid_num = "",
00632          .cid_name = "",
00633          .mohinterpret = "default",
00634          .mohsuggest = "",
00635          .transfertobusy = 1,
00636 
00637          .cid_signalling = CID_SIG_BELL,
00638          .cid_start = CID_START_RING,
00639          .zaptrcallerid = 0,
00640          .use_callerid = 1,
00641          .sig = -1,
00642          .outsigmod = -1,
00643 
00644          .tonezone = -1,
00645 
00646          .echocancel = 1,
00647 
00648          .busycount = 3,
00649          .busycompare = 0,
00650          .busytonelength = 0,
00651          .busyquietlength = 0,
00652          .busyfuzziness = 0,
00653          .silencethreshold = 0,
00654 
00655          .accountcode = "",
00656 
00657          .mailbox = "",
00658 
00659 
00660          .polarityonanswerdelay = 600,
00661 
00662          .sendcalleridafter = DEFAULT_CIDRINGS
00663       },
00664       .timing = {
00665          .prewinktime = -1,
00666          .preflashtime = -1,
00667          .winktime = -1,
00668          .flashtime = -1,
00669          .starttime = -1,
00670          .rxwinktime = -1,
00671          .rxflashtime = -1,
00672          .debouncetime = -1
00673       },
00674       .smdi_port = "/dev/ttyS0",
00675    };
00676 
00677    return conf;
00678 }
00679 
00680 
00681 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00682 static int zt_digit_begin(struct ast_channel *ast, char digit);
00683 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00684 static int zt_sendtext(struct ast_channel *c, const char *text);
00685 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00686 static int zt_hangup(struct ast_channel *ast);
00687 static int zt_answer(struct ast_channel *ast);
00688 static struct ast_frame *zt_read(struct ast_channel *ast);
00689 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00690 static struct ast_frame *zt_exception(struct ast_channel *ast);
00691 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00692 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00693 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00694 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00695 static int zt_setlinear(int zfd, int linear);
00696 static int zt_setlaw(int zfd, int law);
00697 
00698 static int set_actual_txgain(int fd, int chan, float gain, int law);
00699 static int set_actual_rxgain(int fd, int chan, float gain, int law);
00700 inline static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law);
00701 
00702 inline static int pri_is_up(struct zt_pri *pri);
00703 inline static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer);
00704 inline static int pri_active_dchan_fd(struct zt_pri *pri);
00705 static int pri_find_dchan(struct zt_pri *pri);
00706 
00707 static char * redirectingreason2str(int redirectingreason);
00708 static int send_callerid(struct zt_pvt *p);
00709 static int send_cwcidspill(struct zt_pvt *p);
00710 
00711 
00712 static const struct ast_channel_tech zap_tech = {
00713    .type = "Zap",
00714    .description = tdesc,
00715    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00716    .requester = zt_request,
00717    .send_digit_begin = zt_digit_begin,
00718    .send_digit_end = zt_digit_end,
00719    .send_text = zt_sendtext,
00720    .call = zt_call,
00721    .hangup = zt_hangup,
00722    .answer = zt_answer,
00723    .read = zt_read,
00724    .write = zt_write,
00725    .bridge = zt_bridge,
00726    .exception = zt_exception,
00727    .indicate = zt_indicate,
00728    .fixup = zt_fixup,
00729    .setoption = zt_setoption,
00730    .func_channel_read = zt_func_read,
00731 };
00732 
00733 #ifdef HAVE_PRI
00734 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00735 #else
00736 #define GET_CHANNEL(p) ((p)->channel)
00737 #endif
00738 
00739 struct zt_pvt *round_robin[32];
00740 
00741 #ifdef HAVE_PRI
00742 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00743 {
00744    int res;
00745    /* Grab the lock first */
00746    do {
00747       res = ast_mutex_trylock(&pri->lock);
00748       if (res) {
00749          DEADLOCK_AVOIDANCE(&pvt->lock);
00750       }
00751    } while (res);
00752    /* Then break the poll */
00753    pthread_kill(pri->master, SIGURG);
00754    return 0;
00755 }
00756 #endif
00757 
00758 #define NUM_CADENCE_MAX 25
00759 static int num_cadence = 4;
00760 static int user_has_defined_cadences = 0;
00761 
00762 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00763    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00764    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00765    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00766    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00767 };
00768 
00769 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00770  * is 1, the second pause is 2 and so on.
00771  */
00772 
00773 static int cidrings[NUM_CADENCE_MAX] = {
00774    2,                            /*!< Right after first long ring */
00775    4,                            /*!< Right after long part */
00776    3,                            /*!< After third chirp */
00777    2,                            /*!< Second spell */
00778 };
00779 
00780 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00781          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00782 
00783 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00784 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00785 
00786 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00787 {
00788    int res;
00789    if (p->subs[0].owner == ast)
00790       res = 0;
00791    else if (p->subs[1].owner == ast)
00792       res = 1;
00793    else if (p->subs[2].owner == ast)
00794       res = 2;
00795    else {
00796       res = -1;
00797       if (!nullok)
00798          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00799    }
00800    return res;
00801 }
00802 
00803 #ifdef HAVE_PRI
00804 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00805 #else
00806 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00807 #endif
00808 {
00809 #ifdef HAVE_PRI
00810    if (pri)
00811       ast_mutex_unlock(&pri->lock);
00812 #endif         
00813    for (;;) {
00814       if (p->subs[a].owner) {
00815          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00816             DEADLOCK_AVOIDANCE(&p->lock);
00817          } else {
00818             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00819             ast_mutex_unlock(&p->subs[a].owner->lock);
00820             break;
00821          }
00822       } else
00823          break;
00824    }
00825 #ifdef HAVE_PRI
00826    if (pri)
00827       ast_mutex_lock(&pri->lock);
00828 #endif         
00829 }
00830 
00831 #ifdef HAVE_PRI
00832 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00833 #else
00834 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00835 #endif
00836 {
00837    /* We must unlock the PRI to avoid the possibility of a deadlock */
00838 #ifdef HAVE_PRI
00839    if (pri)
00840       ast_mutex_unlock(&pri->lock);
00841 #endif      
00842    for (;;) {
00843       if (p->owner) {
00844          if (ast_mutex_trylock(&p->owner->lock)) {
00845             DEADLOCK_AVOIDANCE(&p->lock);
00846          } else {
00847             ast_queue_frame(p->owner, f);
00848             ast_mutex_unlock(&p->owner->lock);
00849             break;
00850          }
00851       } else
00852          break;
00853    }
00854 #ifdef HAVE_PRI
00855    if (pri)
00856       ast_mutex_lock(&pri->lock);
00857 #endif      
00858 }
00859 
00860 static int restore_gains(struct zt_pvt *p);
00861 
00862 static void swap_subs(struct zt_pvt *p, int a, int b)
00863 {
00864    int tchan;
00865    int tinthreeway;
00866    struct ast_channel *towner;
00867 
00868    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00869 
00870    tchan = p->subs[a].chan;
00871    towner = p->subs[a].owner;
00872    tinthreeway = p->subs[a].inthreeway;
00873 
00874    p->subs[a].chan = p->subs[b].chan;
00875    p->subs[a].owner = p->subs[b].owner;
00876    p->subs[a].inthreeway = p->subs[b].inthreeway;
00877 
00878    p->subs[b].chan = tchan;
00879    p->subs[b].owner = towner;
00880    p->subs[b].inthreeway = tinthreeway;
00881 
00882    if (p->subs[a].owner) 
00883       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00884    if (p->subs[b].owner) 
00885       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00886    wakeup_sub(p, a, NULL);
00887    wakeup_sub(p, b, NULL);
00888 }
00889 
00890 static int zt_open(char *fn)
00891 {
00892    int fd;
00893    int isnum;
00894    int chan = 0;
00895    int bs;
00896    int x;
00897    isnum = 1;
00898    for (x = 0; x < strlen(fn); x++) {
00899       if (!isdigit(fn[x])) {
00900          isnum = 0;
00901          break;
00902       }
00903    }
00904    if (isnum) {
00905       chan = atoi(fn);
00906       if (chan < 1) {
00907          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00908          return -1;
00909       }
00910       fn = "/dev/zap/channel";
00911    }
00912    fd = open(fn, O_RDWR | O_NONBLOCK);
00913    if (fd < 0) {
00914       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00915       return -1;
00916    }
00917    if (chan) {
00918       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00919          x = errno;
00920          close(fd);
00921          errno = x;
00922          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00923          return -1;
00924       }
00925    }
00926    bs = READ_SIZE;
00927    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
00928       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
00929       x = errno;
00930       close(fd);
00931       errno = x;
00932       return -1;
00933    }
00934    return fd;
00935 }
00936 
00937 static void zt_close(int fd)
00938 {
00939    if (fd > 0)
00940       close(fd);
00941 }
00942 
00943 static int zt_setlinear(int zfd, int linear)
00944 {
00945    int res;
00946    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00947    if (res)
00948       return res;
00949    return 0;
00950 }
00951 
00952 
00953 static int alloc_sub(struct zt_pvt *p, int x)
00954 {
00955    ZT_BUFFERINFO bi;
00956    int res;
00957    if (p->subs[x].zfd < 0) {
00958       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00959       if (p->subs[x].zfd > -1) {
00960          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00961          if (!res) {
00962             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00963             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00964             bi.numbufs = numbufs;
00965             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
00966             if (res < 0) {
00967                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
00968             }
00969          } else 
00970             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
00971          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
00972             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
00973             zt_close(p->subs[x].zfd);
00974             p->subs[x].zfd = -1;
00975             return -1;
00976          }
00977          if (option_debug)
00978             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
00979          return 0;
00980       } else
00981          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00982       return -1;
00983    }
00984    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
00985    return -1;
00986 }
00987 
00988 static int unalloc_sub(struct zt_pvt *p, int x)
00989 {
00990    if (!x) {
00991       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
00992       return -1;
00993    }
00994    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
00995    if (p->subs[x].zfd > -1) {
00996       zt_close(p->subs[x].zfd);
00997    }
00998    p->subs[x].zfd = -1;
00999    p->subs[x].linear = 0;
01000    p->subs[x].chan = 0;
01001    p->subs[x].owner = NULL;
01002    p->subs[x].inthreeway = 0;
01003    p->polarity = POLARITY_IDLE;
01004    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01005    return 0;
01006 }
01007 
01008 static int digit_to_dtmfindex(char digit)
01009 {
01010    if (isdigit(digit))
01011       return ZT_TONE_DTMF_BASE + (digit - '0');
01012    else if (digit >= 'A' && digit <= 'D')
01013       return ZT_TONE_DTMF_A + (digit - 'A');
01014    else if (digit >= 'a' && digit <= 'd')
01015       return ZT_TONE_DTMF_A + (digit - 'a');
01016    else if (digit == '*')
01017       return ZT_TONE_DTMF_s;
01018    else if (digit == '#')
01019       return ZT_TONE_DTMF_p;
01020    else
01021       return -1;
01022 }
01023 
01024 static int zt_digit_begin(struct ast_channel *chan, char digit)
01025 {
01026    struct zt_pvt *pvt;
01027    int index;
01028    int dtmf = -1;
01029    
01030    pvt = chan->tech_pvt;
01031 
01032    ast_mutex_lock(&pvt->lock);
01033 
01034    index = zt_get_index(chan, pvt, 0);
01035 
01036    if ((index != SUB_REAL) || !pvt->owner)
01037       goto out;
01038 
01039 #ifdef HAVE_PRI
01040    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01041       if (pvt->setup_ack) {
01042          if (!pri_grab(pvt, pvt->pri)) {
01043             pri_information(pvt->pri->pri, pvt->call, digit);
01044             pri_rel(pvt->pri);
01045          } else
01046             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01047       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01048          int res;
01049          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01050          res = strlen(pvt->dialdest);
01051          pvt->dialdest[res++] = digit;
01052          pvt->dialdest[res] = '\0';
01053       }
01054       goto out;
01055    }
01056 #endif
01057    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01058       goto out;
01059 
01060    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01061       int res;
01062       ZT_DIAL_OPERATION zo = {
01063          .op = ZT_DIAL_OP_APPEND,
01064          .dialstr[0] = 'T',
01065          .dialstr[1] = digit,
01066          .dialstr[2] = 0,
01067       };
01068       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01069          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01070       else
01071          pvt->dialing = 1;
01072    } else {
01073       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01074       pvt->dialing = 1;
01075       pvt->begindigit = digit;
01076    }
01077 
01078 out:
01079    ast_mutex_unlock(&pvt->lock);
01080 
01081    return 0;
01082 }
01083 
01084 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01085 {
01086    struct zt_pvt *pvt;
01087    int res = 0;
01088    int index;
01089    int x;
01090    
01091    pvt = chan->tech_pvt;
01092 
01093    ast_mutex_lock(&pvt->lock);
01094    
01095    index = zt_get_index(chan, pvt, 0);
01096 
01097    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01098       goto out;
01099 
01100 #ifdef HAVE_PRI
01101    /* This means that the digit was already sent via PRI signalling */
01102    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01103       goto out;
01104 #endif
01105 
01106    if (pvt->begindigit) {
01107       x = -1;
01108       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01109       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01110       pvt->dialing = 0;
01111       pvt->begindigit = 0;
01112    }
01113 
01114 out:
01115    ast_mutex_unlock(&pvt->lock);
01116 
01117    return res;
01118 }
01119 
01120 static char *events[] = {
01121    "No event",
01122    "On hook",
01123    "Ring/Answered",
01124    "Wink/Flash",
01125    "Alarm",
01126    "No more alarm",
01127    "HDLC Abort",
01128    "HDLC Overrun",
01129    "HDLC Bad FCS",
01130    "Dial Complete",
01131    "Ringer On",
01132    "Ringer Off",
01133    "Hook Transition Complete",
01134    "Bits Changed",
01135    "Pulse Start",
01136    "Timer Expired",
01137    "Timer Ping",
01138    "Polarity Reversal",
01139    "Ring Begin",
01140 };
01141 
01142 static struct {
01143    int alarm;
01144    char *name;
01145 } alarms[] = {
01146    { ZT_ALARM_RED, "Red Alarm" },
01147    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01148    { ZT_ALARM_BLUE, "Blue Alarm" },
01149    { ZT_ALARM_RECOVER, "Recovering" },
01150    { ZT_ALARM_LOOPBACK, "Loopback" },
01151    { ZT_ALARM_NOTOPEN, "Not Open" },
01152    { ZT_ALARM_NONE, "None" },
01153 };
01154 
01155 static char *alarm2str(int alarm)
01156 {
01157    int x;
01158    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01159       if (alarms[x].alarm & alarm)
01160          return alarms[x].name;
01161    }
01162    return alarm ? "Unknown Alarm" : "No Alarm";
01163 }
01164 
01165 static char *event2str(int event)
01166 {
01167    static char buf[256];
01168    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01169       return events[event];
01170    sprintf(buf, "Event %d", event); /* safe */
01171    return buf;
01172 }
01173 
01174 #ifdef HAVE_PRI
01175 static char *dialplan2str(int dialplan)
01176 {
01177    if (dialplan == -1) {
01178       return("Dynamically set dialplan in ISDN");
01179    }
01180    return (pri_plan2str(dialplan));
01181 }
01182 #endif
01183 
01184 static char *zap_sig2str(int sig)
01185 {
01186    static char buf[256];
01187    switch (sig) {
01188    case SIG_EM:
01189       return "E & M Immediate";
01190    case SIG_EMWINK:
01191       return "E & M Wink";
01192    case SIG_EM_E1:
01193       return "E & M E1";
01194    case SIG_FEATD:
01195       return "Feature Group D (DTMF)";
01196    case SIG_FEATDMF:
01197       return "Feature Group D (MF)";
01198    case SIG_FEATDMF_TA:
01199       return "Feature Groud D (MF) Tandem Access";
01200    case SIG_FEATB:
01201       return "Feature Group B (MF)";
01202    case SIG_E911:
01203       return "E911 (MF)";
01204    case SIG_FGC_CAMA:
01205       return "FGC/CAMA (Dialpulse)";
01206    case SIG_FGC_CAMAMF:
01207       return "FGC/CAMA (MF)";
01208    case SIG_FXSLS:
01209       return "FXS Loopstart";
01210    case SIG_FXSGS:
01211       return "FXS Groundstart";
01212    case SIG_FXSKS:
01213       return "FXS Kewlstart";
01214    case SIG_FXOLS:
01215       return "FXO Loopstart";
01216    case SIG_FXOGS:
01217       return "FXO Groundstart";
01218    case SIG_FXOKS:
01219       return "FXO Kewlstart";
01220    case SIG_PRI:
01221       return "ISDN PRI";
01222    case SIG_SF:
01223       return "SF (Tone) Immediate";
01224    case SIG_SFWINK:
01225       return "SF (Tone) Wink";
01226    case SIG_SF_FEATD:
01227       return "SF (Tone) with Feature Group D (DTMF)";
01228    case SIG_SF_FEATDMF:
01229       return "SF (Tone) with Feature Group D (MF)";
01230    case SIG_SF_FEATB:
01231       return "SF (Tone) with Feature Group B (MF)";
01232    case SIG_GR303FXOKS:
01233       return "GR-303 with FXOKS";
01234    case SIG_GR303FXSKS:
01235       return "GR-303 with FXSKS";
01236    case 0:
01237       return "Pseudo";
01238    default:
01239       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01240       return buf;
01241    }
01242 }
01243 
01244 #define sig2str zap_sig2str
01245 
01246 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01247 {
01248    /* If the conference already exists, and we're already in it
01249       don't bother doing anything */
01250    ZT_CONFINFO zi;
01251    
01252    memset(&zi, 0, sizeof(zi));
01253    zi.chan = 0;
01254 
01255    if (slavechannel > 0) {
01256       /* If we have only one slave, do a digital mon */
01257       zi.confmode = ZT_CONF_DIGITALMON;
01258       zi.confno = slavechannel;
01259    } else {
01260       if (!index) {
01261          /* Real-side and pseudo-side both participate in conference */
01262          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01263             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01264       } else
01265          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01266       zi.confno = p->confno;
01267    }
01268    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01269       return 0;
01270    if (c->zfd < 0)
01271       return 0;
01272    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01273       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01274       return -1;
01275    }
01276    if (slavechannel < 1) {
01277       p->confno = zi.confno;
01278    }
01279    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01280    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01281    return 0;
01282 }
01283 
01284 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01285 {
01286    /* If they're listening to our channel, they're ours */  
01287    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01288       return 1;
01289    /* If they're a talker on our (allocated) conference, they're ours */
01290    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01291       return 1;
01292    return 0;
01293 }
01294 
01295 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01296 {
01297    ZT_CONFINFO zi;
01298    if (/* Can't delete if there's no zfd */
01299       (c->zfd < 0) ||
01300       /* Don't delete from the conference if it's not our conference */
01301       !isourconf(p, c)
01302       /* Don't delete if we don't think it's conferenced at all (implied) */
01303       ) return 0;
01304    memset(&zi, 0, sizeof(zi));
01305    zi.chan = 0;
01306    zi.confno = 0;
01307    zi.confmode = 0;
01308    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01309       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01310       return -1;
01311    }
01312    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01313    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01314    return 0;
01315 }
01316 
01317 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01318 {
01319    int x;
01320    int useslavenative;
01321    struct zt_pvt *slave = NULL;
01322    /* Start out optimistic */
01323    useslavenative = 1;
01324    /* Update conference state in a stateless fashion */
01325    for (x = 0; x < 3; x++) {
01326       /* Any three-way calling makes slave native mode *definitely* out
01327          of the question */
01328       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01329          useslavenative = 0;
01330    }
01331    /* If we don't have any 3-way calls, check to see if we have
01332       precisely one slave */
01333    if (useslavenative) {
01334       for (x = 0; x < MAX_SLAVES; x++) {
01335          if (p->slaves[x]) {
01336             if (slave) {
01337                /* Whoops already have a slave!  No 
01338                   slave native and stop right away */
01339                slave = NULL;
01340                useslavenative = 0;
01341                break;
01342             } else {
01343                /* We have one slave so far */
01344                slave = p->slaves[x];
01345             }
01346          }
01347       }
01348    }
01349    /* If no slave, slave native definitely out */
01350    if (!slave)
01351       useslavenative = 0;
01352    else if (slave->law != p->law) {
01353       useslavenative = 0;
01354       slave = NULL;
01355    }
01356    if (out)
01357       *out = slave;
01358    return useslavenative;
01359 }
01360 
01361 static int reset_conf(struct zt_pvt *p)
01362 {
01363    ZT_CONFINFO zi;
01364    memset(&zi, 0, sizeof(zi));
01365    p->confno = -1;
01366    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01367    if (p->subs[SUB_REAL].zfd > -1) {
01368       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01369          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01370    }
01371    return 0;
01372 }
01373 
01374 static int update_conf(struct zt_pvt *p)
01375 {
01376    int needconf = 0;
01377    int x;
01378    int useslavenative;
01379    struct zt_pvt *slave = NULL;
01380 
01381    useslavenative = isslavenative(p, &slave);
01382    /* Start with the obvious, general stuff */
01383    for (x = 0; x < 3; x++) {
01384       /* Look for three way calls */
01385       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01386          conf_add(p, &p->subs[x], x, 0);
01387          needconf++;
01388       } else {
01389          conf_del(p, &p->subs[x], x);
01390       }
01391    }
01392    /* If we have a slave, add him to our conference now. or DAX
01393       if this is slave native */
01394    for (x = 0; x < MAX_SLAVES; x++) {
01395       if (p->slaves[x]) {
01396          if (useslavenative)
01397             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01398          else {
01399             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01400             needconf++;
01401          }
01402       }
01403    }
01404    /* If we're supposed to be in there, do so now */
01405    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01406       if (useslavenative)
01407          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01408       else {
01409          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01410          needconf++;
01411       }
01412    }
01413    /* If we have a master, add ourselves to his conference */
01414    if (p->master) {
01415       if (isslavenative(p->master, NULL)) {
01416          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01417       } else {
01418          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01419       }
01420    }
01421    if (!needconf) {
01422       /* Nobody is left (or should be left) in our conference.
01423          Kill it. */
01424       p->confno = -1;
01425    }
01426    if (option_debug)
01427       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01428    return 0;
01429 }
01430 
01431 static void zt_enable_ec(struct zt_pvt *p)
01432 {
01433    int x;
01434    int res;
01435    if (!p)
01436       return;
01437    if (p->echocanon) {
01438       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01439       return;
01440    }
01441    if (p->digital) {
01442       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01443       return;
01444    }
01445    if (p->echocancel) {
01446       if (p->sig == SIG_PRI) {
01447          x = 1;
01448          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01449          if (res)
01450             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
01451       }
01452       x = p->echocancel;
01453       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01454       if (res) 
01455          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
01456       else {
01457          p->echocanon = 1;
01458          if (option_debug)
01459             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01460       }
01461    } else if (option_debug)
01462       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01463 }
01464 
01465 static void zt_train_ec(struct zt_pvt *p)
01466 {
01467    int x;
01468    int res;
01469    if (p && p->echocancel && p->echotraining) {
01470       x = p->echotraining;
01471       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01472       if (res)
01473          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01474       else {
01475          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01476       }
01477    } else
01478       ast_log(LOG_DEBUG, "No echo training requested\n");
01479 }
01480 
01481 static void zt_disable_ec(struct zt_pvt *p)
01482 {
01483    int x;
01484    int res;
01485    if (p->echocancel) {
01486       x = 0;
01487       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01488       if (res)
01489          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01490       else if (option_debug)
01491          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01492    }
01493    p->echocanon = 0;
01494 }
01495 
01496 static void fill_txgain(struct zt_gains *g, float gain, int law)
01497 {
01498    int j;
01499    int k;
01500    float linear_gain = pow(10.0, gain / 20.0);
01501 
01502    switch (law) {
01503    case ZT_LAW_ALAW:
01504       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01505          if (gain) {
01506             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01507             if (k > 32767) k = 32767;
01508             if (k < -32767) k = -32767;
01509             g->txgain[j] = AST_LIN2A(k);
01510          } else {
01511             g->txgain[j] = j;
01512          }
01513       }
01514       break;
01515    case ZT_LAW_MULAW:
01516       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01517          if (gain) {
01518             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01519             if (k > 32767) k = 32767;
01520             if (k < -32767) k = -32767;
01521             g->txgain[j] = AST_LIN2MU(k);
01522          } else {
01523             g->txgain[j] = j;
01524          }
01525       }
01526       break;
01527    }
01528 }
01529 
01530 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01531 {
01532    int j;
01533    int k;
01534    float linear_gain = pow(10.0, gain / 20.0);
01535 
01536    switch (law) {
01537    case ZT_LAW_ALAW:
01538       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01539          if (gain) {
01540             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01541             if (k > 32767) k = 32767;
01542             if (k < -32767) k = -32767;
01543             g->rxgain[j] = AST_LIN2A(k);
01544          } else {
01545             g->rxgain[j] = j;
01546          }
01547       }
01548       break;
01549    case ZT_LAW_MULAW:
01550       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01551          if (gain) {
01552             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01553             if (k > 32767) k = 32767;
01554             if (k < -32767) k = -32767;
01555             g->rxgain[j] = AST_LIN2MU(k);
01556          } else {
01557             g->rxgain[j] = j;
01558          }
01559       }
01560       break;
01561    }
01562 }
01563 
01564 static int set_actual_txgain(int fd, int chan, float gain, int law)
01565 {
01566    struct zt_gains g;
01567    int res;
01568 
01569    memset(&g, 0, sizeof(g));
01570    g.chan = chan;
01571    res = ioctl(fd, ZT_GETGAINS, &g);
01572    if (res) {
01573       if (option_debug)
01574          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01575       return res;
01576    }
01577 
01578    fill_txgain(&g, gain, law);
01579 
01580    return ioctl(fd, ZT_SETGAINS, &g);
01581 }
01582 
01583 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01584 {
01585    struct zt_gains g;
01586    int res;
01587 
01588    memset(&g, 0, sizeof(g));
01589    g.chan = chan;
01590    res = ioctl(fd, ZT_GETGAINS, &g);
01591    if (res) {
01592       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01593       return res;
01594    }
01595 
01596    fill_rxgain(&g, gain, law);
01597 
01598    return ioctl(fd, ZT_SETGAINS, &g);
01599 }
01600 
01601 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01602 {
01603    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01604 }
01605 
01606 static int bump_gains(struct zt_pvt *p)
01607 {
01608    int res;
01609 
01610    /* Bump receive gain by 5.0db */
01611    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01612    if (res) {
01613       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01614       return -1;
01615    }
01616 
01617    return 0;
01618 }
01619 
01620 static int restore_gains(struct zt_pvt *p)
01621 {
01622    int res;
01623 
01624    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01625    if (res) {
01626       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01627       return -1;
01628    }
01629 
01630    return 0;
01631 }
01632 
01633 static inline int zt_set_hook(int fd, int hs)
01634 {
01635    int x, res;
01636 
01637    x = hs;
01638    res = ioctl(fd, ZT_HOOK, &x);
01639 
01640    if (res < 0) {
01641       if (errno == EINPROGRESS)
01642          return 0;
01643       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01644    }
01645 
01646    return res;
01647 }
01648 
01649 static inline int zt_confmute(struct zt_pvt *p, int muted)
01650 {
01651    int x, y, res;
01652    x = muted;
01653    if (p->sig == SIG_PRI) {
01654       y = 1;
01655       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01656       if (res)
01657          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01658    }
01659    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01660    if (res < 0)
01661       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01662    return res;
01663 }
01664 
01665 static int save_conference(struct zt_pvt *p)
01666 {
01667    struct zt_confinfo c;
01668    int res;
01669    if (p->saveconf.confmode) {
01670       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01671       return -1;
01672    }
01673    p->saveconf.chan = 0;
01674    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01675    if (res) {
01676       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01677       p->saveconf.confmode = 0;
01678       return -1;
01679    }
01680    c.chan = 0;
01681    c.confno = 0;
01682    c.confmode = ZT_CONF_NORMAL;
01683    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01684    if (res) {
01685       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01686       return -1;
01687    }
01688    if (option_debug)
01689       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01690    return 0;
01691 }
01692 
01693 static int restore_conference(struct zt_pvt *p)
01694 {
01695    int res;
01696    if (p->saveconf.confmode) {
01697       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01698       p->saveconf.confmode = 0;
01699       if (res) {
01700          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01701          return -1;
01702       }
01703    }
01704    if (option_debug)
01705       ast_log(LOG_DEBUG, "Restored conferencing\n");
01706    return 0;
01707 }
01708 
01709 static int send_cwcidspill(struct zt_pvt *p)
01710 {
01711    p->callwaitcas = 0;
01712    p->cidcwexpire = 0;
01713    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01714       return -1;
01715    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01716    /* Make sure we account for the end */
01717    p->cidlen += READ_SIZE * 4;
01718    p->cidpos = 0;
01719    send_callerid(p);
01720    if (option_verbose > 2)
01721       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01722    return 0;
01723 }
01724 
01725 static int has_voicemail(struct zt_pvt *p)
01726 {
01727 
01728    return ast_app_has_voicemail(p->mailbox, NULL);
01729 }
01730 
01731 static int send_callerid(struct zt_pvt *p)
01732 {
01733    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01734    int res;
01735    /* Take out of linear mode if necessary */
01736    if (p->subs[SUB_REAL].linear) {
01737       p->subs[SUB_REAL].linear = 0;
01738       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01739    }
01740    while (p->cidpos < p->cidlen) {
01741       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01742       if (res < 0) {
01743          if (errno == EAGAIN)
01744             return 0;
01745          else {
01746             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01747             return -1;
01748          }
01749       }
01750       if (!res)
01751          return 0;
01752       p->cidpos += res;
01753    }
01754    free(p->cidspill);
01755    p->cidspill = NULL;
01756    if (p->callwaitcas) {
01757       /* Wait for CID/CW to expire */
01758       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01759    } else
01760       restore_conference(p);
01761    return 0;
01762 }
01763 
01764 static int zt_callwait(struct ast_channel *ast)
01765 {
01766    struct zt_pvt *p = ast->tech_pvt;
01767    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01768    if (p->cidspill) {
01769       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01770       free(p->cidspill);
01771    }
01772    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01773       return -1;
01774    save_conference(p);
01775    /* Silence */
01776    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01777    if (!p->callwaitrings && p->callwaitingcallerid) {
01778       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01779       p->callwaitcas = 1;
01780       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01781    } else {
01782       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01783       p->callwaitcas = 0;
01784       p->cidlen = 2400 + READ_SIZE * 4;
01785    }
01786    p->cidpos = 0;
01787    send_callerid(p);
01788    
01789    return 0;
01790 }
01791 
01792 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01793 {
01794    struct zt_pvt *p = ast->tech_pvt;
01795    int x, res, index,mysig;
01796    char *c, *n, *l;
01797 #ifdef HAVE_PRI
01798    char *s = NULL;
01799 #endif
01800    char dest[256]; /* must be same length as p->dialdest */
01801    ast_mutex_lock(&p->lock);
01802    ast_copy_string(dest, rdest, sizeof(dest));
01803    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01804    if ((ast->_state == AST_STATE_BUSY)) {
01805       p->subs[SUB_REAL].needbusy = 1;
01806       ast_mutex_unlock(&p->lock);
01807       return 0;
01808    }
01809    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01810       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01811       ast_mutex_unlock(&p->lock);
01812       return -1;
01813    }
01814    p->dialednone = 0;
01815    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01816    {
01817       /* Special pseudo -- automatically up */
01818       ast_setstate(ast, AST_STATE_UP); 
01819       ast_mutex_unlock(&p->lock);
01820       return 0;
01821    }
01822    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01823    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01824    if (res)
01825       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01826    p->outgoing = 1;
01827 
01828    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01829 
01830    mysig = p->sig;
01831    if (p->outsigmod > -1)
01832       mysig = p->outsigmod;
01833 
01834    switch (mysig) {
01835    case SIG_FXOLS:
01836    case SIG_FXOGS:
01837    case SIG_FXOKS:
01838       if (p->owner == ast) {
01839          /* Normal ring, on hook */
01840          
01841          /* Don't send audio while on hook, until the call is answered */
01842          p->dialing = 1;
01843          if (p->use_callerid) {
01844             /* Generate the Caller-ID spill if desired */
01845             if (p->cidspill) {
01846                ast_log(LOG_WARNING, "cidspill already exists??\n");
01847                free(p->cidspill);
01848             }
01849             p->callwaitcas = 0;
01850             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01851                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01852                p->cidpos = 0;
01853                send_callerid(p);
01854             }
01855          }
01856          /* Choose proper cadence */
01857          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01858             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01859                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01860             p->cidrings = cidrings[p->distinctivering - 1];
01861          } else {
01862             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01863                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01864             p->cidrings = p->sendcalleridafter;
01865          }
01866 
01867          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01868          c = strchr(dest, '/');
01869          if (c)
01870             c++;
01871          if (c && (strlen(c) < p->stripmsd)) {
01872             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01873             c = NULL;
01874          }
01875          if (c) {
01876             p->dop.op = ZT_DIAL_OP_REPLACE;
01877             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01878             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01879          } else {
01880             p->dop.dialstr[0] = '\0';
01881          }
01882          x = ZT_RING;
01883          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01884             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01885             ast_mutex_unlock(&p->lock);
01886             return -1;
01887          }
01888          p->dialing = 1;
01889       } else {
01890          /* Call waiting call */
01891          p->callwaitrings = 0;
01892          if (ast->cid.cid_num)
01893             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01894          else
01895             p->callwait_num[0] = '\0';
01896          if (ast->cid.cid_name)
01897             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01898          else
01899             p->callwait_name[0] = '\0';
01900          /* Call waiting tone instead */
01901          if (zt_callwait(ast)) {
01902             ast_mutex_unlock(&p->lock);
01903             return -1;
01904          }
01905          /* Make ring-back */
01906          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01907             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01908             
01909       }
01910       n = ast->cid.cid_name;
01911       l = ast->cid.cid_num;
01912       if (l)
01913          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01914       else
01915          p->lastcid_num[0] = '\0';
01916       if (n)
01917          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01918       else
01919          p->lastcid_name[0] = '\0';
01920       ast_setstate(ast, AST_STATE_RINGING);
01921       index = zt_get_index(ast, p, 0);
01922       if (index > -1) {
01923          p->subs[index].needringing = 1;
01924       }
01925       break;
01926    case SIG_FXSLS:
01927    case SIG_FXSGS:
01928    case SIG_FXSKS:
01929    case SIG_EMWINK:
01930    case SIG_EM:
01931    case SIG_EM_E1:
01932    case SIG_FEATD:
01933    case SIG_FEATDMF:
01934    case SIG_E911:
01935    case SIG_FGC_CAMA:
01936    case SIG_FGC_CAMAMF:
01937    case SIG_FEATB:
01938    case SIG_SFWINK:
01939    case SIG_SF:
01940    case SIG_SF_FEATD:
01941    case SIG_SF_FEATDMF:
01942    case SIG_FEATDMF_TA:
01943    case SIG_SF_FEATB:
01944       c = strchr(dest, '/');
01945       if (c)
01946          c++;
01947       else
01948          c = "";
01949       if (strlen(c) < p->stripmsd) {
01950          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01951          ast_mutex_unlock(&p->lock);
01952          return -1;
01953       }
01954 #ifdef HAVE_PRI
01955       /* Start the trunk, if not GR-303 */
01956       if (!p->pri) {
01957 #endif
01958          x = ZT_START;
01959          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01960          if (res < 0) {
01961             if (errno != EINPROGRESS) {
01962                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01963                ast_mutex_unlock(&p->lock);
01964                return -1;
01965             }
01966          }
01967 #ifdef HAVE_PRI
01968       }
01969 #endif
01970       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01971       p->dop.op = ZT_DIAL_OP_REPLACE;
01972 
01973       c += p->stripmsd;
01974 
01975       switch (mysig) {
01976       case SIG_FEATD:
01977          l = ast->cid.cid_num;
01978          if (l) 
01979             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01980          else
01981             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01982          break;
01983       case SIG_FEATDMF:
01984          l = ast->cid.cid_num;
01985          if (l) 
01986             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01987          else
01988             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01989          break;
01990       case SIG_FEATDMF_TA:
01991       {
01992          const char *cic, *ozz;
01993 
01994          /* If you have to go through a Tandem Access point you need to use this */
01995          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01996          if (!ozz)
01997             ozz = defaultozz;
01998          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01999          if (!cic)
02000             cic = defaultcic;
02001          if (!ozz || !cic) {
02002             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
02003             ast_mutex_unlock(&p->lock);
02004             return -1;
02005          }
02006          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
02007          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
02008          p->whichwink = 0;
02009       }
02010          break;
02011       case SIG_E911:
02012          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
02013          break;
02014       case SIG_FGC_CAMA:
02015          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02016          break;
02017       case SIG_FGC_CAMAMF:
02018       case SIG_FEATB:
02019          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02020          break;
02021       default:
02022          if (p->pulse)
02023             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02024          else
02025             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02026          break;
02027       }
02028 
02029       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02030          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02031          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02032          p->echorest[sizeof(p->echorest) - 1] = '\0';
02033          p->echobreak = 1;
02034          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02035       } else
02036          p->echobreak = 0;
02037       if (!res) {
02038          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02039             x = ZT_ONHOOK;
02040             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02041             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02042             ast_mutex_unlock(&p->lock);
02043             return -1;
02044          }
02045       } else
02046          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02047       p->dialing = 1;
02048       if (ast_strlen_zero(c))
02049          p->dialednone = 1;
02050       ast_setstate(ast, AST_STATE_DIALING);
02051       break;
02052    case 0:
02053       /* Special pseudo -- automatically up*/
02054       ast_setstate(ast, AST_STATE_UP);
02055       break;      
02056    case SIG_PRI:
02057       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02058       p->dialdest[0] = '\0';
02059       break;
02060    default:
02061       ast_log(LOG_DEBUG, "not yet implemented\n");
02062       ast_mutex_unlock(&p->lock);
02063       return -1;
02064    }
02065 #ifdef HAVE_PRI
02066    if (p->pri) {
02067       struct pri_sr *sr;
02068 #ifdef SUPPORT_USERUSER
02069       const char *useruser;
02070 #endif
02071       int pridialplan;
02072       int dp_strip;
02073       int prilocaldialplan;
02074       int ldp_strip;
02075       int exclusive;
02076       const char *rr_str;
02077       int redirect_reason;
02078 
02079       c = strchr(dest, '/');
02080       if (c)
02081          c++;
02082       else
02083          c = dest;
02084 
02085       l = NULL;
02086       n = NULL;
02087 
02088       if (!p->hidecallerid) {
02089          l = ast->cid.cid_num;
02090          if (!p->hidecalleridname) {
02091             n = ast->cid.cid_name;
02092          }
02093       }
02094 
02095 
02096       if (strlen(c) < p->stripmsd) {
02097          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02098          ast_mutex_unlock(&p->lock);
02099          return -1;
02100       }
02101       if (mysig != SIG_FXSKS) {
02102          p->dop.op = ZT_DIAL_OP_REPLACE;
02103          s = strchr(c + p->stripmsd, 'w');
02104          if (s) {
02105             if (strlen(s) > 1)
02106                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02107             else
02108                p->dop.dialstr[0] = '\0';
02109             *s = '\0';
02110          } else {
02111             p->dop.dialstr[0] = '\0';
02112          }
02113       }
02114       if (pri_grab(p, p->pri)) {
02115          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02116          ast_mutex_unlock(&p->lock);
02117          return -1;
02118       }
02119       if (!(p->call = pri_new_call(p->pri->pri))) {
02120          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02121          pri_rel(p->pri);
02122          ast_mutex_unlock(&p->lock);
02123          return -1;
02124       }
02125       if (!(sr = pri_sr_new())) {
02126          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02127          pri_destroycall(p->pri->pri, p->call);
02128          p->call = NULL;
02129          pri_rel(p->pri);
02130          ast_mutex_unlock(&p->lock);
02131          return -1;
02132       }
02133       if (p->bearer || (mysig == SIG_FXSKS)) {
02134          if (p->bearer) {
02135             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);
02136             p->bearer->call = p->call;
02137          } else
02138             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02139          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02140       }
02141       p->digital = IS_DIGITAL(ast->transfercapability);
02142       /* Add support for exclusive override */
02143       if (p->priexclusive)
02144          exclusive = 1;
02145       else {
02146       /* otherwise, traditional behavior */
02147          if (p->pri->nodetype == PRI_NETWORK)
02148             exclusive = 0;
02149          else
02150             exclusive = 1;
02151       }
02152       
02153       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02154       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02155                (p->digital ? -1 : 
02156                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02157       if (p->pri->facilityenable)
02158          pri_facility_enable(p->pri->pri);
02159 
02160       if (option_verbose > 2)
02161          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02162       dp_strip = 0;
02163       pridialplan = p->pri->dialplan - 1;
02164       if (pridialplan == -2) { /* compute dynamically */
02165          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02166             dp_strip = strlen(p->pri->internationalprefix);
02167             pridialplan = PRI_INTERNATIONAL_ISDN;
02168          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02169             dp_strip = strlen(p->pri->nationalprefix);
02170             pridialplan = PRI_NATIONAL_ISDN;
02171          } else {
02172             pridialplan = PRI_LOCAL_ISDN;
02173          }
02174       }
02175       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02176 
02177       ldp_strip = 0;
02178       prilocaldialplan = p->pri->localdialplan - 1;
02179       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02180          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02181             ldp_strip = strlen(p->pri->internationalprefix);
02182             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02183          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02184             ldp_strip = strlen(p->pri->nationalprefix);
02185             prilocaldialplan = PRI_NATIONAL_ISDN;
02186          } else {
02187             prilocaldialplan = PRI_LOCAL_ISDN;
02188          }
02189       }
02190       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02191          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02192       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02193          if (!strcasecmp(rr_str, "UNKNOWN"))
02194             redirect_reason = 0;
02195          else if (!strcasecmp(rr_str, "BUSY"))
02196             redirect_reason = 1;
02197          else if (!strcasecmp(rr_str, "NO_REPLY"))
02198             redirect_reason = 2;
02199          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02200             redirect_reason = 15;
02201          else
02202             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02203       } else
02204          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02205       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02206 
02207 #ifdef SUPPORT_USERUSER
02208       /* User-user info */
02209       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02210 
02211       if (useruser)
02212          pri_sr_set_useruser(sr, useruser);
02213 #endif
02214 
02215       if (pri_setup(p->pri->pri, p->call, sr)) {
02216          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02217             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02218          pri_rel(p->pri);
02219          ast_mutex_unlock(&p->lock);
02220          pri_sr_free(sr);
02221          return -1;
02222       }
02223       pri_sr_free(sr);
02224       ast_setstate(ast, AST_STATE_DIALING);
02225       pri_rel(p->pri);
02226    }
02227 #endif      
02228    ast_mutex_unlock(&p->lock);
02229    return 0;
02230 }
02231 
02232 static void destroy_zt_pvt(struct zt_pvt **pvt)
02233 {
02234    struct zt_pvt *p = *pvt;
02235    /* Remove channel from the list */
02236    if (p->prev)
02237       p->prev->next = p->next;
02238    if (p->next)
02239       p->next->prev = p->prev;
02240    if (p->use_smdi)
02241       ast_smdi_interface_unref(p->smdi_iface);
02242    ast_mutex_destroy(&p->lock);
02243    free(p);
02244    *pvt = NULL;
02245 }
02246 
02247 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02248 {
02249    int owned = 0;
02250    int i = 0;
02251 
02252    if (!now) {
02253       if (cur->owner) {
02254          owned = 1;
02255       }
02256 
02257       for (i = 0; i < 3; i++) {
02258          if (cur->subs[i].owner) {
02259             owned = 1;
02260          }
02261       }
02262       if (!owned) {
02263          if (prev) {
02264             prev->next = cur->next;
02265             if (prev->next)
02266                prev->next->prev = prev;
02267             else
02268                ifend = prev;
02269          } else {
02270             iflist = cur->next;
02271             if (iflist)
02272                iflist->prev = NULL;
02273             else
02274                ifend = NULL;
02275          }
02276          if (cur->subs[SUB_REAL].zfd > -1) {
02277             zt_close(cur->subs[SUB_REAL].zfd);
02278          }
02279          destroy_zt_pvt(&cur);
02280       }
02281    } else {
02282       if (prev) {
02283          prev->next = cur->next;
02284          if (prev->next)
02285             prev->next->prev = prev;
02286          else
02287             ifend = prev;
02288       } else {
02289          iflist = cur->next;
02290          if (iflist)
02291             iflist->prev = NULL;
02292          else
02293             ifend = NULL;
02294       }
02295       if (cur->subs[SUB_REAL].zfd > -1) {
02296          zt_close(cur->subs[SUB_REAL].zfd);
02297       }
02298       destroy_zt_pvt(&cur);
02299    }
02300    return 0;
02301 }
02302 
02303 #ifdef HAVE_PRI
02304 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02305 
02306 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02307 
02308 static char *zap_send_keypad_facility_descrip = 
02309 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02310 "  IE over the current channel.\n";
02311 
02312 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02313 {
02314    /* Data will be our digit string */
02315    struct zt_pvt *p;
02316    char *digits = (char *) data;
02317 
02318    if (ast_strlen_zero(digits)) {
02319       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02320       return -1;
02321    }
02322 
02323    p = (struct zt_pvt *)chan->tech_pvt;
02324 
02325    if (!p) {
02326       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02327       return -1;
02328    }
02329 
02330    ast_mutex_lock(&p->lock);
02331 
02332    if (!p->pri || !p->call) {
02333       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02334       ast_mutex_unlock(&p->lock);
02335       return -1;
02336    }
02337 
02338    if (!pri_grab(p, p->pri)) {
02339       pri_keypad_facility(p->pri->pri, p->call, digits);
02340       pri_rel(p->pri);
02341    } else {
02342       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02343       ast_mutex_unlock(&p->lock);
02344       return -1;
02345    }
02346 
02347    ast_mutex_unlock(&p->lock);
02348 
02349    return 0;
02350 }
02351 
02352 static int pri_is_up(struct zt_pri *pri)
02353 {
02354    int x;
02355    for (x = 0; x < NUM_DCHANS; x++) {
02356       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02357          return 1;
02358    }
02359    return 0;
02360 }
02361 
02362 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02363 {
02364    bearer->owner = &inuse;
02365    bearer->realcall = crv;
02366    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02367    if (crv->subs[SUB_REAL].owner)
02368       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02369    crv->bearer = bearer;
02370    crv->call = bearer->call;
02371    crv->pri = pri;
02372    return 0;
02373 }
02374 
02375 static char *pri_order(int level)
02376 {
02377    switch (level) {
02378    case 0:
02379       return "Primary";
02380    case 1:
02381       return "Secondary";
02382    case 2:
02383       return "Tertiary";
02384    case 3:
02385       return "Quaternary";
02386    default:
02387       return "<Unknown>";
02388    }     
02389 }
02390 
02391 /* Returns fd of the active dchan */
02392 static int pri_active_dchan_fd(struct zt_pri *pri)
02393 {
02394    int x = -1;
02395 
02396    for (x = 0; x < NUM_DCHANS; x++) {
02397       if ((pri->dchans[x] == pri->pri))
02398          break;
02399    }
02400 
02401    return pri->fds[x];
02402 }
02403 
02404 static int pri_find_dchan(struct zt_pri *pri)
02405 {
02406    int oldslot = -1;
02407    struct pri *old;
02408    int newslot = -1;
02409    int x;
02410    old = pri->pri;
02411    for (x = 0; x < NUM_DCHANS; x++) {
02412       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02413          newslot = x;
02414       if (pri->dchans[x] == old) {
02415          oldslot = x;
02416       }
02417    }
02418    if (newslot < 0) {
02419       newslot = 0;
02420       ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02421          pri->dchannels[newslot]);
02422    }
02423    if (old && (oldslot != newslot))
02424       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02425          pri->dchannels[oldslot], pri->dchannels[newslot]);
02426    pri->pri = pri->dchans[newslot];
02427    return 0;
02428 }
02429 #endif
02430 
02431 static int zt_hangup(struct ast_channel *ast)
02432 {
02433    int res;
02434    int index,x, law;
02435    /*static int restore_gains(struct zt_pvt *p);*/
02436    struct zt_pvt *p = ast->tech_pvt;
02437    struct zt_pvt *tmp = NULL;
02438    struct zt_pvt *prev = NULL;
02439    ZT_PARAMS par;
02440 
02441    if (option_debug)
02442       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02443    if (!ast->tech_pvt) {
02444       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02445       return 0;
02446    }
02447    
02448    ast_mutex_lock(&p->lock);
02449    
02450    index = zt_get_index(ast, p, 1);
02451 
02452    if (p->sig == SIG_PRI) {
02453       x = 1;
02454       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02455    }
02456 
02457    x = 0;
02458    zt_confmute(p, 0);
02459    restore_gains(p);
02460    if (p->origcid_num) {
02461       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02462       free(p->origcid_num);
02463       p->origcid_num = NULL;
02464    }  
02465    if (p->origcid_name) {
02466       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02467       free(p->origcid_name);
02468       p->origcid_name = NULL;
02469    }  
02470    if (p->dsp)
02471       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02472    if (p->exten)
02473       p->exten[0] = '\0';
02474 
02475    if (option_debug)
02476       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02477       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02478    p->ignoredtmf = 0;
02479    
02480    if (index > -1) {
02481       /* Real channel, do some fixup */
02482       p->subs[index].owner = NULL;
02483       p->subs[index].needanswer = 0;
02484       p->subs[index].needflash = 0;
02485       p->subs[index].needringing = 0;
02486       p->subs[index].needbusy = 0;
02487       p->subs[index].needcongestion = 0;
02488       p->subs[index].linear = 0;
02489       p->subs[index].needcallerid = 0;
02490       p->polarity = POLARITY_IDLE;
02491       zt_setlinear(p->subs[index].zfd, 0);
02492       if (index == SUB_REAL) {
02493          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02494             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02495             if (p->subs[SUB_CALLWAIT].inthreeway) {
02496                /* We had flipped over to answer a callwait and now it's gone */
02497                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02498                /* Move to the call-wait, but un-own us until they flip back. */
02499                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02500                unalloc_sub(p, SUB_CALLWAIT);
02501                p->owner = NULL;
02502             } else {
02503                /* The three way hung up, but we still have a call wait */
02504                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02505                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02506                unalloc_sub(p, SUB_THREEWAY);
02507                if (p->subs[SUB_REAL].inthreeway) {
02508                   /* This was part of a three way call.  Immediately make way for
02509                      another call */
02510                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02511                   p->owner = p->subs[SUB_REAL].owner;
02512                } else {
02513                   /* This call hasn't been completed yet...  Set owner to NULL */
02514                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02515                   p->owner = NULL;
02516                }
02517                p->subs[SUB_REAL].inthreeway = 0;
02518             }
02519          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02520             /* Move to the call-wait and switch back to them. */
02521             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02522             unalloc_sub(p, SUB_CALLWAIT);
02523             p->owner = p->subs[SUB_REAL].owner;
02524             if (p->owner->_state != AST_STATE_UP)
02525                p->subs[SUB_REAL].needanswer = 1;
02526             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02527                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02528          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02529             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02530             unalloc_sub(p, SUB_THREEWAY);
02531             if (p->subs[SUB_REAL].inthreeway) {
02532                /* This was part of a three way call.  Immediately make way for
02533                   another call */
02534                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02535                p->owner = p->subs[SUB_REAL].owner;
02536             } else {
02537                /* This call hasn't been completed yet...  Set owner to NULL */
02538                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02539                p->owner = NULL;
02540             }
02541             p->subs[SUB_REAL].inthreeway = 0;
02542          }
02543       } else if (index == SUB_CALLWAIT) {
02544          /* Ditch the holding callwait call, and immediately make it availabe */
02545          if (p->subs[SUB_CALLWAIT].inthreeway) {
02546             /* This is actually part of a three way, placed on hold.  Place the third part
02547                on music on hold now */
02548             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02549                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02550                   S_OR(p->mohsuggest, NULL),
02551                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02552             }
02553             p->subs[SUB_THREEWAY].inthreeway = 0;
02554             /* Make it the call wait now */
02555             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02556             unalloc_sub(p, SUB_THREEWAY);
02557          } else
02558             unalloc_sub(p, SUB_CALLWAIT);
02559       } else if (index == SUB_THREEWAY) {
02560          if (p->subs[SUB_CALLWAIT].inthreeway) {
02561             /* The other party of the three way call is currently in a call-wait state.
02562                Start music on hold for them, and take the main guy out of the third call */
02563             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02564                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02565                   S_OR(p->mohsuggest, NULL),
02566                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02567             }
02568             p->subs[SUB_CALLWAIT].inthreeway = 0;
02569          }
02570          p->subs[SUB_REAL].inthreeway = 0;
02571          /* If this was part of a three way call index, let us make
02572             another three way call */
02573          unalloc_sub(p, SUB_THREEWAY);
02574       } else {
02575          /* This wasn't any sort of call, but how are we an index? */
02576          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02577       }
02578    }
02579 
02580    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02581       p->owner = NULL;
02582       p->ringt = 0;
02583       p->distinctivering = 0;
02584       p->confirmanswer = 0;
02585       p->cidrings = 1;
02586       p->outgoing = 0;
02587       p->digital = 0;
02588       p->faxhandled = 0;
02589       p->pulsedial = 0;
02590       p->onhooktime = time(NULL);
02591 #ifdef HAVE_PRI
02592       p->proceeding = 0;
02593       p->progress = 0;
02594       p->alerting = 0;
02595       p->setup_ack = 0;
02596 #endif      
02597       if (p->dsp) {
02598          ast_dsp_free(p->dsp);
02599          p->dsp = NULL;
02600       }
02601 
02602       law = ZT_LAW_DEFAULT;
02603       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02604       if (res < 0) 
02605          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02606       /* Perform low level hangup if no owner left */
02607 #ifdef HAVE_PRI
02608       if (p->pri) {
02609 #ifdef SUPPORT_USERUSER
02610          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02611 #endif
02612 
02613          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02614          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02615             if (!pri_grab(p, p->pri)) {
02616                if (p->alreadyhungup) {
02617                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02618 
02619 #ifdef SUPPORT_USERUSER
02620                   pri_call_set_useruser(p->call, useruser);
02621 #endif
02622 
02623                   pri_hangup(p->pri->pri, p->call, -1);
02624                   p->call = NULL;
02625                   if (p->bearer) 
02626                      p->bearer->call = NULL;
02627                } else {
02628                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02629                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02630                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02631 
02632 #ifdef SUPPORT_USERUSER
02633                   pri_call_set_useruser(p->call, useruser);
02634 #endif
02635 
02636                   p->alreadyhungup = 1;
02637                   if (p->bearer)
02638                      p->bearer->alreadyhungup = 1;
02639                   if (cause) {
02640                      if (atoi(cause))
02641                         icause = atoi(cause);
02642                   }
02643                   pri_hangup(p->pri->pri, p->call, icause);
02644                }
02645                if (res < 0) 
02646                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02647                pri_rel(p->pri);        
02648             } else {
02649                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02650                res = -1;
02651             }
02652          } else {
02653             if (p->bearer)
02654                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02655             p->call = NULL;
02656             res = 0;
02657          }
02658       }
02659 #endif
02660       if (p->sig && (p->sig != SIG_PRI))
02661          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02662       if (res < 0) {
02663          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02664       }
02665       switch (p->sig) {
02666       case SIG_FXOGS:
02667       case SIG_FXOLS:
02668       case SIG_FXOKS:
02669          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02670          if (!res) {
02671 #if 0
02672             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02673 #endif
02674             /* If they're off hook, try playing congestion */
02675             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02676                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02677             else
02678                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02679          }
02680          break;
02681       case SIG_FXSGS:
02682       case SIG_FXSLS:
02683       case SIG_FXSKS:
02684          /* Make sure we're not made available for at least two seconds assuming
02685             we were actually used for an inbound or outbound call. */
02686          if (ast->_state != AST_STATE_RESERVED) {
02687             time(&p->guardtime);
02688             p->guardtime += 2;
02689          }
02690          break;
02691       default:
02692          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02693       }
02694       if (p->cidspill)
02695          free(p->cidspill);
02696       if (p->sig)
02697          zt_disable_ec(p);
02698       x = 0;
02699       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02700       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02701       p->didtdd = 0;
02702       p->cidspill = NULL;
02703       p->callwaitcas = 0;
02704       p->callwaiting = p->permcallwaiting;
02705       p->hidecallerid = p->permhidecallerid;
02706       p->dialing = 0;
02707       p->rdnis[0] = '\0';
02708       update_conf(p);
02709       reset_conf(p);
02710       /* Restore data mode */
02711       if (p->sig == SIG_PRI) {
02712          x = 0;
02713          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02714       }
02715 #ifdef HAVE_PRI
02716       if (p->bearer) {
02717          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02718          /* Free up the bearer channel as well, and
02719             don't use its file descriptor anymore */
02720          update_conf(p->bearer);
02721          reset_conf(p->bearer);
02722          p->bearer->owner = NULL;
02723          p->bearer->realcall = NULL;
02724          p->bearer = NULL;
02725          p->subs[SUB_REAL].zfd = -1;
02726          p->pri = NULL;
02727       }
02728 #endif
02729       restart_monitor();
02730    }
02731 
02732    p->callwaitingrepeat = 0;
02733    p->cidcwexpire = 0;
02734    p->oprmode = 0;
02735    ast->tech_pvt = NULL;
02736    ast_mutex_unlock(&p->lock);
02737    ast_module_unref(ast_module_info->self);
02738    if (option_verbose > 2) 
02739       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02740 
02741    ast_mutex_lock(&iflock);
02742    tmp = iflist;
02743    prev = NULL;
02744    if (p->destroy) {
02745       while (tmp) {
02746          if (tmp == p) {
02747             destroy_channel(prev, tmp, 0);
02748             break;
02749          } else {
02750             prev = tmp;
02751             tmp = tmp->next;
02752          }
02753       }
02754    }
02755    ast_mutex_unlock(&iflock);
02756    return 0;
02757 }
02758 
02759 static int zt_answer(struct ast_channel *ast)
02760 {
02761    struct zt_pvt *p = ast->tech_pvt;
02762    int res = 0;
02763    int index;
02764    int oldstate = ast->_state;
02765    ast_setstate(ast, AST_STATE_UP);
02766    ast_mutex_lock(&p->lock);
02767    index = zt_get_index(ast, p, 0);
02768    if (index < 0)
02769       index = SUB_REAL;
02770    /* nothing to do if a radio channel */
02771    if ((p->radio || (p->oprmode < 0))) {
02772       ast_mutex_unlock(&p->lock);
02773       return 0;
02774    }
02775    switch (p->sig) {
02776    case SIG_FXSLS:
02777    case SIG_FXSGS:
02778    case SIG_FXSKS:
02779       p->ringt = 0;
02780       /* Fall through */
02781    case SIG_EM:
02782    case SIG_EM_E1:
02783    case SIG_EMWINK:
02784    case SIG_FEATD:
02785    case SIG_FEATDMF:
02786    case SIG_FEATDMF_TA:
02787    case SIG_E911:
02788    case SIG_FGC_CAMA:
02789    case SIG_FGC_CAMAMF:
02790    case SIG_FEATB:
02791    case SIG_SF:
02792    case SIG_SFWINK:
02793    case SIG_SF_FEATD:
02794    case SIG_SF_FEATDMF:
02795    case SIG_SF_FEATB:
02796    case SIG_FXOLS:
02797    case SIG_FXOGS:
02798    case SIG_FXOKS:
02799       /* Pick up the line */
02800       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02801       if (p->hanguponpolarityswitch) {
02802          gettimeofday(&p->polaritydelaytv, NULL);
02803       }
02804       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02805       tone_zone_play_tone(p->subs[index].zfd, -1);
02806       p->dialing = 0;
02807       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02808          if (oldstate == AST_STATE_RINGING) {
02809             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02810             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02811             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02812             p->owner = p->subs[SUB_REAL].owner;
02813          }
02814       }
02815       if (p->sig & __ZT_SIG_FXS) {
02816          zt_enable_ec(p);
02817          zt_train_ec(p);
02818       }
02819       break;
02820 #ifdef HAVE_PRI
02821    case SIG_PRI:
02822       /* Send a pri acknowledge */
02823       if (!pri_grab(p, p->pri)) {
02824          p->proceeding = 1;
02825          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02826          pri_rel(p->pri);
02827       } else {
02828          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02829          res = -1;
02830       }
02831       break;
02832 #endif
02833    case 0:
02834       ast_mutex_unlock(&p->lock);
02835       return 0;
02836    default:
02837       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02838       res = -1;
02839    }
02840    ast_mutex_unlock(&p->lock);
02841    return res;
02842 }
02843 
02844 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02845 {
02846    char *cp;
02847    signed char *scp;
02848    int x;
02849    int index;
02850    struct zt_pvt *p = chan->tech_pvt, *pp;
02851    struct oprmode *oprmode;
02852    
02853 
02854    /* all supported options require data */
02855    if (!data || (datalen < 1)) {
02856       errno = EINVAL;
02857       return -1;
02858    }
02859 
02860    switch (option) {
02861    case AST_OPTION_TXGAIN:
02862       scp = (signed char *) data;
02863       index = zt_get_index(chan, p, 0);
02864       if (index < 0) {
02865          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02866          return -1;
02867       }
02868       if (option_debug)
02869          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02870       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02871    case AST_OPTION_RXGAIN:
02872       scp = (signed char *) data;
02873       index = zt_get_index(chan, p, 0);
02874       if (index < 0) {
02875          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02876          return -1;
02877       }
02878       if (option_debug)
02879          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02880       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02881    case AST_OPTION_TONE_VERIFY:
02882       if (!p->dsp)
02883          break;
02884       cp = (char *) data;
02885       switch (*cp) {
02886       case 1:
02887          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02888          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02889          break;
02890       case 2:
02891          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02892          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02893          break;
02894       default:
02895          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02896          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02897          break;
02898       }
02899       break;
02900    case AST_OPTION_TDD:
02901       /* turn on or off TDD */
02902       cp = (char *) data;
02903       p->mate = 0;
02904       if (!*cp) { /* turn it off */
02905          if (option_debug)
02906             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02907          if (p->tdd)
02908             tdd_free(p->tdd);
02909          p->tdd = 0;
02910          break;
02911       }
02912       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02913          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02914       zt_disable_ec(p);
02915       /* otherwise, turn it on */
02916       if (!p->didtdd) { /* if havent done it yet */
02917          unsigned char mybuf[41000], *buf;
02918          int size, res, fd, len;
02919          struct pollfd fds[1];
02920 
02921          buf = mybuf;
02922          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02923          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02924          len = 40000;
02925          index = zt_get_index(chan, p, 0);
02926          if (index < 0) {
02927             ast_log(LOG_WARNING, "No index in TDD?\n");
02928             return -1;
02929          }
02930          fd = p->subs[index].zfd;
02931          while (len) {
02932             if (ast_check_hangup(chan))
02933                return -1;
02934             size = len;
02935             if (size > READ_SIZE)
02936                size = READ_SIZE;
02937             fds[0].fd = fd;
02938             fds[0].events = POLLPRI | POLLOUT;
02939             fds[0].revents = 0;
02940             res = poll(fds, 1, -1);
02941             if (!res) {
02942                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02943                continue;
02944             }
02945             /* if got exception */
02946             if (fds[0].revents & POLLPRI)
02947                return -1;
02948             if (!(fds[0].revents & POLLOUT)) {
02949                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02950                continue;
02951             }
02952             res = write(fd, buf, size);
02953             if (res != size) {
02954                if (res == -1) return -1;
02955                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02956                break;
02957             }
02958             len -= size;
02959             buf += size;
02960          }
02961          p->didtdd = 1; /* set to have done it now */    
02962       }
02963       if (*cp == 2) { /* Mate mode */
02964          if (p->tdd)
02965             tdd_free(p->tdd);
02966          p->tdd = 0;
02967          p->mate = 1;
02968          break;
02969       }     
02970       if (!p->tdd) { /* if we dont have one yet */
02971          p->tdd = tdd_new(); /* allocate one */
02972       }     
02973       break;
02974    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02975       if (!p->dsp)
02976          break;
02977       cp = (char *) data;
02978       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02979          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02980                 p->dtmfrelax = 0;
02981                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
02982                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
02983       break;
02984    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02985       cp = (char *) data;
02986       if (!*cp) {    
02987          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02988          x = 0;
02989          zt_disable_ec(p);
02990       } else {    
02991          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02992          x = 1;
02993       }
02994       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02995          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02996       break;
02997    case AST_OPTION_OPRMODE:  /* Operator services mode */
02998       oprmode = (struct oprmode *) data;
02999       pp = oprmode->peer->tech_pvt;
03000       p->oprmode = pp->oprmode = 0;
03001       /* setup peers */
03002       p->oprpeer = pp;
03003       pp->oprpeer = p;
03004       /* setup modes, if any */
03005       if (oprmode->mode) 
03006       {
03007          pp->oprmode = oprmode->mode;
03008          p->oprmode = -oprmode->mode;
03009       }
03010       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
03011          oprmode->mode, chan->name,oprmode->peer->name);;
03012       break;
03013    case AST_OPTION_ECHOCAN:
03014       cp = (char *) data;
03015       if (*cp) {
03016          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
03017          zt_enable_ec(p);
03018       } else {
03019          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
03020          zt_disable_ec(p);
03021       }
03022       break;
03023    }
03024    errno = 0;
03025 
03026    return 0;
03027 }
03028 
03029 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03030 {
03031    struct zt_pvt *p = chan->tech_pvt;
03032    
03033    if (!strcasecmp(data, "rxgain")) {
03034       ast_mutex_lock(&p->lock);
03035       snprintf(buf, len, "%f", p->rxgain);
03036       ast_mutex_unlock(&p->lock);   
03037    } else if (!strcasecmp(data, "txgain")) {
03038       ast_mutex_lock(&p->lock);
03039       snprintf(buf, len, "%f", p->txgain);
03040       ast_mutex_unlock(&p->lock);   
03041    } else {
03042       ast_copy_string(buf, "", len);
03043    }
03044    return 0;
03045 }
03046 
03047 
03048 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03049 {
03050    /* Unlink a specific slave or all slaves/masters from a given master */
03051    int x;
03052    int hasslaves;
03053    if (!master)
03054       return;
03055    if (needlock) {
03056       ast_mutex_lock(&master->lock);
03057       if (slave) {
03058          while (ast_mutex_trylock(&slave->lock)) {
03059             DEADLOCK_AVOIDANCE(&master->lock);
03060          }
03061       }
03062    }
03063    hasslaves = 0;
03064    for (x = 0; x < MAX_SLAVES; x++) {
03065       if (master->slaves[x]) {
03066          if (!slave || (master->slaves[x] == slave)) {
03067             /* Take slave out of the conference */
03068             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03069             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03070             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03071             master->slaves[x]->master = NULL;
03072             master->slaves[x] = NULL;
03073          } else
03074             hasslaves = 1;
03075       }
03076       if (!hasslaves)
03077          master->inconference = 0;
03078    }
03079    if (!slave) {
03080       if (master->master) {
03081          /* Take master out of the conference */
03082          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03083          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03084          hasslaves = 0;
03085          for (x = 0; x < MAX_SLAVES; x++) {
03086             if (master->master->slaves[x] == master)
03087                master->master->slaves[x] = NULL;
03088             else if (master->master->slaves[x])
03089                hasslaves = 1;
03090          }
03091          if (!hasslaves)
03092             master->master->inconference = 0;
03093       }
03094       master->master = NULL;
03095    }
03096    update_conf(master);
03097    if (needlock) {
03098       if (slave)
03099          ast_mutex_unlock(&slave->lock);
03100       ast_mutex_unlock(&master->lock);
03101    }
03102 }
03103 
03104 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03105    int x;
03106    if (!slave || !master) {
03107       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03108       return;
03109    }
03110    for (x = 0; x < MAX_SLAVES; x++) {
03111       if (!master->slaves[x]) {
03112          master->slaves[x] = slave;
03113          break;
03114       }
03115    }
03116    if (x >= MAX_SLAVES) {
03117       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03118       master->slaves[MAX_SLAVES - 1] = slave;
03119    }
03120    if (slave->master) 
03121       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03122    slave->master = master;
03123    
03124    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03125 }
03126 
03127 static void disable_dtmf_detect(struct zt_pvt *p)
03128 {
03129 #ifdef ZT_TONEDETECT
03130    int val;
03131 #endif
03132 
03133    p->ignoredtmf = 1;
03134 
03135 #ifdef ZT_TONEDETECT
03136    val = 0;
03137    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03138 #endif      
03139    if (!p->hardwaredtmf && p->dsp) {
03140       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03141       ast_dsp_set_features(p->dsp, p->dsp_features);
03142    }
03143 }
03144 
03145 static void enable_dtmf_detect(struct zt_pvt *p)
03146 {
03147 #ifdef ZT_TONEDETECT
03148    int val;
03149 #endif
03150 
03151    if (p->channel == CHAN_PSEUDO)
03152       return;
03153 
03154    p->ignoredtmf = 0;
03155 
03156 #ifdef ZT_TONEDETECT
03157    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03158    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03159 #endif      
03160    if (!p->hardwaredtmf && p->dsp) {
03161       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03162       ast_dsp_set_features(p->dsp, p->dsp_features);
03163    }
03164 }
03165 
03166 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)
03167 {
03168    struct ast_channel *who;
03169    struct zt_pvt *p0, *p1, *op0, *op1;
03170    struct zt_pvt *master = NULL, *slave = NULL;
03171    struct ast_frame *f;
03172    int inconf = 0;
03173    int nothingok = 1;
03174    int ofd0, ofd1;
03175    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03176    int os0 = -1, os1 = -1;
03177    int priority = 0;
03178    struct ast_channel *oc0, *oc1;
03179    enum ast_bridge_result res;
03180 
03181 #ifdef PRI_2BCT
03182    int triedtopribridge = 0;
03183    q931_call *q931c0 = NULL, *q931c1 = NULL;
03184 #endif
03185 
03186    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03187       There is code below to handle it properly until DTMF is actually seen,
03188       but due to currently unresolved issues it's ignored...
03189    */
03190 
03191    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03192       return AST_BRIDGE_FAILED_NOWARN;
03193 
03194    ast_mutex_lock(&c0->lock);
03195    while (ast_mutex_trylock(&c1->lock)) {
03196       DEADLOCK_AVOIDANCE(&c0->lock);
03197    }
03198 
03199    p0 = c0->tech_pvt;
03200    p1 = c1->tech_pvt;
03201    /* cant do pseudo-channels here */
03202    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03203       ast_mutex_unlock(&c0->lock);
03204       ast_mutex_unlock(&c1->lock);
03205       return AST_BRIDGE_FAILED_NOWARN;
03206    }
03207 
03208    oi0 = zt_get_index(c0, p0, 0);
03209    oi1 = zt_get_index(c1, p1, 0);
03210    if ((oi0 < 0) || (oi1 < 0)) {
03211       ast_mutex_unlock(&c0->lock);
03212       ast_mutex_unlock(&c1->lock);
03213       return AST_BRIDGE_FAILED;
03214    }
03215 
03216    op0 = p0 = c0->tech_pvt;
03217    op1 = p1 = c1->tech_pvt;
03218    ofd0 = c0->fds[0];
03219    ofd1 = c1->fds[0];
03220    oc0 = p0->owner;
03221    oc1 = p1->owner;
03222 
03223    if (ast_mutex_trylock(&p0->lock)) {
03224       /* Don't block, due to potential for deadlock */
03225       ast_mutex_unlock(&c0->lock);
03226       ast_mutex_unlock(&c1->lock);
03227       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03228       return AST_BRIDGE_RETRY;
03229    }
03230    if (ast_mutex_trylock(&p1->lock)) {
03231       /* Don't block, due to potential for deadlock */
03232       ast_mutex_unlock(&p0->lock);
03233       ast_mutex_unlock(&c0->lock);
03234       ast_mutex_unlock(&c1->lock);
03235       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03236       return AST_BRIDGE_RETRY;
03237    }
03238 
03239    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03240       if (p0->owner && p1->owner) {
03241          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03242          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03243             master = p0;
03244             slave = p1;
03245             inconf = 1;
03246          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03247             master = p1;
03248             slave = p0;
03249             inconf = 1;
03250          } else {
03251             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03252             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03253                p0->channel,
03254                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03255                p0->subs[SUB_REAL].inthreeway, p0->channel,
03256                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03257                p1->subs[SUB_REAL].inthreeway);
03258          }
03259          nothingok = 0;
03260       }
03261    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03262       if (p1->subs[SUB_THREEWAY].inthreeway) {
03263          master = p1;
03264          slave = p0;
03265          nothingok = 0;
03266       }
03267    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03268       if (p0->subs[SUB_THREEWAY].inthreeway) {
03269          master = p0;
03270          slave = p1;
03271          nothingok = 0;
03272       }
03273    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03274       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03275          don't put us in anything */
03276       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03277          master = p1;
03278          slave = p0;
03279          nothingok = 0;
03280       }
03281    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03282       /* Same as previous */
03283       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03284          master = p0;
03285          slave = p1;
03286          nothingok = 0;
03287       }
03288    }
03289    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03290       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03291    if (master && slave) {
03292       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03293          in an active threeway call with a channel that is ringing, we should
03294          indicate ringing. */
03295       if ((oi1 == SUB_THREEWAY) && 
03296           p1->subs[SUB_THREEWAY].inthreeway && 
03297           p1->subs[SUB_REAL].owner && 
03298           p1->subs[SUB_REAL].inthreeway && 
03299           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03300          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03301          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03302          os1 = p1->subs[SUB_REAL].owner->_state;
03303       } else {
03304          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03305          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03306       }
03307       if ((oi0 == SUB_THREEWAY) && 
03308           p0->subs[SUB_THREEWAY].inthreeway && 
03309           p0->subs[SUB_REAL].owner && 
03310           p0->subs[SUB_REAL].inthreeway && 
03311           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03312          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03313          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03314          os0 = p0->subs[SUB_REAL].owner->_state;
03315       } else {
03316          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03317          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03318       }
03319       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03320          if (!p0->echocanbridged || !p1->echocanbridged) {
03321             /* Disable echo cancellation if appropriate */
03322             zt_disable_ec(p0);
03323             zt_disable_ec(p1);
03324          }
03325       }
03326       zt_link(slave, master);
03327       master->inconference = inconf;
03328    } else if (!nothingok)
03329       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03330 
03331    update_conf(p0);
03332    update_conf(p1);
03333    t0 = p0->subs[SUB_REAL].inthreeway;
03334    t1 = p1->subs[SUB_REAL].inthreeway;
03335 
03336    ast_mutex_unlock(&p0->lock);
03337    ast_mutex_unlock(&p1->lock);
03338 
03339    ast_mutex_unlock(&c0->lock);
03340    ast_mutex_unlock(&c1->lock);
03341 
03342    /* Native bridge failed */
03343    if ((!master || !slave) && !nothingok) {
03344       zt_enable_ec(p0);
03345       zt_enable_ec(p1);
03346       return AST_BRIDGE_FAILED;
03347    }
03348    
03349    if (option_verbose > 2) 
03350       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03351 
03352    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03353       disable_dtmf_detect(op0);
03354 
03355    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03356       disable_dtmf_detect(op1);
03357 
03358    for (;;) {
03359       struct ast_channel *c0_priority[2] = {c0, c1};
03360       struct ast_channel *c1_priority[2] = {c1, c0};
03361 
03362       /* Here's our main loop...  Start by locking things, looking for private parts, 
03363          and then balking if anything is wrong */
03364       ast_mutex_lock(&c0->lock);
03365       while (ast_mutex_trylock(&c1->lock)) {
03366          DEADLOCK_AVOIDANCE(&c0->lock);
03367       }
03368 
03369       p0 = c0->tech_pvt;
03370       p1 = c1->tech_pvt;
03371 
03372       if (op0 == p0)
03373          i0 = zt_get_index(c0, p0, 1);
03374       if (op1 == p1)
03375          i1 = zt_get_index(c1, p1, 1);
03376       ast_mutex_unlock(&c0->lock);
03377       ast_mutex_unlock(&c1->lock);
03378 
03379       if (!timeoutms || 
03380           (op0 != p0) ||
03381           (op1 != p1) || 
03382           (ofd0 != c0->fds[0]) || 
03383           (ofd1 != c1->fds[0]) ||
03384           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03385           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03386           (oc0 != p0->owner) || 
03387           (oc1 != p1->owner) ||
03388           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03389           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03390           (oi0 != i0) ||
03391           (oi1 != i1)) {
03392          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03393             op0->channel, oi0, op1->channel, oi1);
03394          res = AST_BRIDGE_RETRY;
03395          goto return_from_bridge;
03396       }
03397 
03398 #ifdef PRI_2BCT
03399       q931c0 = p0->call;
03400       q931c1 = p1->call;
03401       if (p0->transfer && p1->transfer 
03402           && q931c0 && q931c1 
03403           && !triedtopribridge) {
03404          pri_channel_bridge(q931c0, q931c1);
03405          triedtopribridge = 1;
03406       }
03407 #endif
03408 
03409       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03410       if (!who) {
03411          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03412          continue;
03413       }
03414       f = ast_read(who);
03415       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03416          *fo = f;
03417          *rc = who;
03418          res = AST_BRIDGE_COMPLETE;
03419          goto return_from_bridge;
03420       }
03421       if (f->frametype == AST_FRAME_DTMF) {
03422          if ((who == c0) && p0->pulsedial) {
03423             ast_write(c1, f);
03424          } else if ((who == c1) && p1->pulsedial) {
03425             ast_write(c0, f);
03426          } else {
03427             *fo = f;
03428             *rc = who;
03429             res = AST_BRIDGE_COMPLETE;
03430             goto return_from_bridge;
03431          }
03432       }
03433       ast_frfree(f);
03434       
03435       /* Swap who gets priority */
03436       priority = !priority;
03437    }
03438 
03439 return_from_bridge:
03440    if (op0 == p0)
03441       zt_enable_ec(p0);
03442 
03443    if (op1 == p1)
03444       zt_enable_ec(p1);
03445 
03446    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03447       enable_dtmf_detect(op0);
03448 
03449    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03450       enable_dtmf_detect(op1);
03451 
03452    zt_unlink(slave, master, 1);
03453 
03454    return res;
03455 }
03456 
03457 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03458 {
03459    struct zt_pvt *p = newchan->tech_pvt;
03460    int x;
03461    ast_mutex_lock(&p->lock);
03462    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03463    if (p->owner == oldchan) {
03464       p->owner = newchan;
03465    }
03466    for (x = 0; x < 3; x++)
03467       if (p->subs[x].owner == oldchan) {
03468          if (!x)
03469             zt_unlink(NULL, p, 0);
03470          p->subs[x].owner = newchan;
03471       }
03472    if (newchan->_state == AST_STATE_RINGING) 
03473       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03474    update_conf(p);
03475    ast_mutex_unlock(&p->lock);
03476    return 0;
03477 }
03478 
03479 static int zt_ring_phone(struct zt_pvt *p)
03480 {
03481    int x;
03482    int res;
03483    /* Make sure our transmit state is on hook */
03484    x = 0;
03485    x = ZT_ONHOOK;
03486    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03487    do {
03488       x = ZT_RING;
03489       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03490       if (res) {
03491          switch (errno) {
03492          case EBUSY:
03493          case EINTR:
03494             /* Wait just in case */
03495             usleep(10000);
03496             continue;
03497          case EINPROGRESS:
03498             res = 0;
03499             break;
03500          default:
03501             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03502             res = 0;
03503          }
03504       }
03505    } while (res);
03506    return res;
03507 }
03508 
03509 static void *ss_thread(void *data);
03510 
03511 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03512 
03513 static int attempt_transfer(struct zt_pvt *p)
03514 {
03515    /* In order to transfer, we need at least one of the channels to
03516       actually be in a call bridge.  We can't conference two applications
03517       together (but then, why would we want to?) */
03518    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03519       /* The three-way person we're about to transfer to could still be in MOH, so
03520          stop if now if appropriate */
03521       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03522          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03523       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03524          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03525       }
03526       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03527          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03528       }
03529       if (p->subs[SUB_REAL].owner->cdr) {
03530          /* Move CDR from second channel to current one */
03531          p->subs[SUB_THREEWAY].owner->cdr =
03532             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03533          p->subs[SUB_REAL].owner->cdr = NULL;
03534       }
03535       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03536          /* Move CDR from second channel's bridge to current one */
03537          p->subs[SUB_THREEWAY].owner->cdr =
03538             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03539          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03540       }
03541        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03542          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03543                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03544          return -1;
03545       }
03546       /* Orphan the channel after releasing the lock */
03547       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03548       unalloc_sub(p, SUB_THREEWAY);
03549    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03550       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03551       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03552          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03553       }
03554       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03555          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03556       }
03557       if (p->subs[SUB_THREEWAY].owner->cdr) {
03558          /* Move CDR from second channel to current one */
03559          p->subs[SUB_REAL].owner->cdr = 
03560             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03561          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03562       }
03563       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03564          /* Move CDR from second channel's bridge to current one */
03565          p->subs[SUB_REAL].owner->cdr = 
03566             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03567          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03568       }
03569       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03570          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03571                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03572          return -1;
03573       }
03574       /* Three-way is now the REAL */
03575       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03576       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03577       unalloc_sub(p, SUB_THREEWAY);
03578       /* Tell the caller not to hangup */
03579       return 1;
03580    } else {
03581       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03582                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03583       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03584       return -1;
03585    }
03586    return 0;
03587 }
03588 
03589 static int check_for_conference(struct zt_pvt *p)
03590 {
03591    ZT_CONFINFO ci;
03592    /* Fine if we already have a master, etc */
03593    if (p->master || (p->confno > -1))
03594       return 0;
03595    memset(&ci, 0, sizeof(ci));
03596    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03597       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03598       return 0;
03599    }
03600    /* If we have no master and don't have a confno, then 
03601       if we're in a conference, it's probably a MeetMe room or
03602       some such, so don't let us 3-way out! */
03603    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03604       if (option_verbose > 2) 
03605          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03606       return 1;
03607    }
03608    return 0;
03609 }
03610 
03611 static int get_alarms(struct zt_pvt *p)
03612 {
03613    int res;
03614    ZT_SPANINFO zi;
03615    memset(&zi, 0, sizeof(zi));
03616    zi.spanno = p->span;
03617    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03618    if (res < 0) {
03619       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03620       return 0;
03621    }
03622    return zi.alarms;
03623 }
03624 
03625 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03626 {
03627    struct zt_pvt *p = ast->tech_pvt;
03628    struct ast_frame *f = *dest;
03629 
03630    if (option_debug)
03631       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03632 
03633    if (p->confirmanswer) {
03634       if (option_debug)
03635          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03636       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03637          of a DTMF digit */
03638       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03639       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03640       *dest = &p->subs[index].f;
03641       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03642       p->confirmanswer = 0;
03643    } else if (p->callwaitcas) {
03644       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03645          if (option_debug)
03646             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03647          if (p->cidspill)
03648             free(p->cidspill);
03649          send_cwcidspill(p);
03650       }
03651       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03652          p->callwaitcas = 0;
03653       p->subs[index].f.frametype = AST_FRAME_NULL;
03654       p->subs[index].f.subclass = 0;
03655       *dest = &p->subs[index].f;
03656    } else if (f->subclass == 'f') {
03657       /* Fax tone -- Handle and return NULL */
03658       if ((p->callprogress & 0x6) && !p->faxhandled) {
03659          p->faxhandled++;
03660          if (strcmp(ast->exten, "fax")) {
03661             const char *target_context = S_OR(ast->macrocontext, ast->context);
03662 
03663             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03664                if (option_verbose > 2)
03665                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03666                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03667                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03668                if (ast_async_goto(ast, target_context, "fax", 1))
03669                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03670             } else
03671                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03672          } else if (option_debug)
03673             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03674       } else if (option_debug)
03675             ast_log(LOG_DEBUG, "Fax already handled\n");
03676       zt_confmute(p, 0);
03677       p->subs[index].f.frametype = AST_FRAME_NULL;
03678       p->subs[index].f.subclass = 0;
03679       *dest = &p->subs[index].f;
03680    } else if (f->subclass == 'm') {
03681       /* Confmute request */
03682       zt_confmute(p, 1);
03683       p->subs[index].f.frametype = AST_FRAME_NULL;
03684       p->subs[index].f.subclass = 0;
03685       *dest = &p->subs[index].f;    
03686    } else if (f->subclass == 'u') {
03687       /* Unmute */
03688       zt_confmute(p, 0);
03689       p->subs[index].f.frametype = AST_FRAME_NULL;
03690       p->subs[index].f.subclass = 0;
03691       *dest = &p->subs[index].f;    
03692    } else
03693       zt_confmute(p, 0);
03694 }
03695          
03696 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03697 {
03698    int res, x;
03699    int index, mysig;
03700    char *c;
03701    struct zt_pvt *p = ast->tech_pvt;
03702    pthread_t threadid;
03703    pthread_attr_t attr;
03704    struct ast_channel *chan;
03705    struct ast_frame *f;
03706 
03707    index = zt_get_index(ast, p, 0);
03708    mysig = p->sig;
03709    if (p->outsigmod > -1)
03710       mysig = p->outsigmod;
03711    p->subs[index].f.frametype = AST_FRAME_NULL;
03712    p->subs[index].f.subclass = 0;
03713    p->subs[index].f.datalen = 0;
03714    p->subs[index].f.samples = 0;
03715    p->subs[index].f.mallocd = 0;
03716    p->subs[index].f.offset = 0;
03717    p->subs[index].f.src = "zt_handle_event";
03718    p->subs[index].f.data = NULL;
03719    f = &p->subs[index].f;
03720 
03721    if (index < 0)
03722       return &p->subs[index].f;
03723    if (p->fake_event) {
03724       res = p->fake_event;
03725       p->fake_event = 0;
03726    } else
03727       res = zt_get_event(p->subs[index].zfd);
03728 
03729    if (option_debug)
03730       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03731 
03732    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03733       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03734 
03735       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03736 #ifdef HAVE_PRI
03737       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03738          /* absorb event */
03739       } else {
03740 #endif
03741          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03742          p->subs[index].f.subclass = res & 0xff;
03743 #ifdef HAVE_PRI
03744       }
03745 #endif
03746       zt_handle_dtmfup(ast, index, &f);
03747       return f;
03748    }
03749 
03750    if (res & ZT_EVENT_DTMFDOWN) {
03751       if (option_debug)
03752          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03753       /* Mute conference */
03754       zt_confmute(p, 1);
03755       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03756       p->subs[index].f.subclass = res & 0xff;
03757       return &p->subs[index].f;
03758    }
03759 
03760    switch (res) {
03761 #ifdef ZT_EVENT_EC_DISABLED
03762       case ZT_EVENT_EC_DISABLED:
03763          if (option_verbose > 2) 
03764             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03765          p->echocanon = 0;
03766          break;
03767 #endif
03768       case ZT_EVENT_BITSCHANGED:
03769          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03770       case ZT_EVENT_PULSE_START:
03771          /* Stop tone if there's a pulse start and the PBX isn't started */
03772          if (!ast->pbx)
03773             tone_zone_play_tone(p->subs[index].zfd, -1);
03774          break;   
03775       case ZT_EVENT_DIALCOMPLETE:
03776          if (p->inalarm) break;
03777          if ((p->radio || (p->oprmode < 0))) break;
03778          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03779             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03780             return NULL;
03781          }
03782          if (!x) { /* if not still dialing in driver */
03783             zt_enable_ec(p);
03784             if (p->echobreak) {
03785                zt_train_ec(p);
03786                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03787                p->dop.op = ZT_DIAL_OP_REPLACE;
03788                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03789                p->echobreak = 0;
03790             } else {
03791                p->dialing = 0;
03792                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03793                   /* if thru with dialing after offhook */
03794                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03795                      ast_setstate(ast, AST_STATE_UP);
03796                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03797                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03798                      break;
03799                   } else { /* if to state wait for offhook to dial rest */
03800                      /* we now wait for off hook */
03801                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03802                   }
03803                }
03804                if (ast->_state == AST_STATE_DIALING) {
03805                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03806                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03807                   } 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)))) {
03808                      ast_setstate(ast, AST_STATE_RINGING);
03809                   } else if (!p->answeronpolarityswitch) {
03810                      ast_setstate(ast, AST_STATE_UP);
03811                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03812                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03813                      /* If aops=0 and hops=1, this is necessary */
03814                      p->polarity = POLARITY_REV;
03815                   } else {
03816                      /* Start clean, so we can catch the change to REV polarity when party answers */
03817                      p->polarity = POLARITY_IDLE;
03818                   }
03819                }
03820             }
03821          }
03822          break;
03823       case ZT_EVENT_ALARM:
03824 #ifdef HAVE_PRI
03825          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03826             /* T309 is not enabled : hangup calls when alarm occurs */
03827             if (p->call) {
03828                if (p->pri && p->pri->pri) {
03829                   if (!pri_grab(p, p->pri)) {
03830                      pri_hangup(p->pri->pri, p->call, -1);
03831                      pri_destroycall(p->pri->pri, p->call);
03832                      p->call = NULL;
03833                      pri_rel(p->pri);
03834                   } else
03835                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03836                } else
03837                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03838             }
03839             if (p->owner)
03840                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03841          }
03842          if (p->bearer)
03843             p->bearer->inalarm = 1;
03844          else
03845 #endif
03846          p->inalarm = 1;
03847          res = get_alarms(p);
03848          do {
03849             const char *alarm_str = alarm2str(res);
03850 
03851             /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
03852              * doesn't know what to do with it.  Don't confuse users with log messages. */
03853             if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
03854                p->unknown_alarm = 1;
03855                break;
03856             } else {
03857                p->unknown_alarm = 0;
03858             }
03859                
03860             ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
03861             manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03862                "Alarm: %s\r\n"
03863                "Channel: %d\r\n",
03864                alarm_str, p->channel);
03865          } while (0);
03866 #ifdef HAVE_LIBPRI
03867          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
03868             /* fall through intentionally */
03869          } else {
03870             break;
03871          }
03872 #endif
03873       case ZT_EVENT_ONHOOK:
03874          if (p->radio) {
03875             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03876             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03877             break;
03878          }
03879          if (p->oprmode < 0)
03880          {
03881             if (p->oprmode != -1) break;
03882             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03883             {
03884                /* Make sure it starts ringing */
03885                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03886                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
03887                save_conference(p->oprpeer);
03888                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03889             }
03890             break;
03891          }
03892          switch (p->sig) {
03893          case SIG_FXOLS:
03894          case SIG_FXOGS:
03895          case SIG_FXOKS:
03896             p->onhooktime = time(NULL);
03897             p->msgstate = -1;
03898             /* Check for some special conditions regarding call waiting */
03899             if (index == SUB_REAL) {
03900                /* The normal line was hung up */
03901                if (p->subs[SUB_CALLWAIT].owner) {
03902                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03903                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03904                   if (option_verbose > 2) 
03905                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03906                   unalloc_sub(p, SUB_CALLWAIT); 
03907 #if 0
03908                   p->subs[index].needanswer = 0;
03909                   p->subs[index].needringing = 0;
03910 #endif                  
03911                   p->callwaitingrepeat = 0;
03912                   p->cidcwexpire = 0;
03913                   p->owner = NULL;
03914                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03915                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03916                      p->dialing = 1;
03917                   zt_ring_phone(p);
03918                } else if (p->subs[SUB_THREEWAY].owner) {
03919                   unsigned int mssinceflash;
03920                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03921                      the private structure -- not especially easy or clean */
03922                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03923                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03924                      ast_mutex_unlock(&p->lock);
03925                      DEADLOCK_AVOIDANCE(&ast->lock);
03926                      /* We can grab ast and p in that order, without worry.  We should make sure
03927                         nothing seriously bad has happened though like some sort of bizarre double
03928                         masquerade! */
03929                      ast_mutex_lock(&p->lock);
03930                      if (p->owner != ast) {
03931                         ast_log(LOG_WARNING, "This isn't good...\n");
03932                         return NULL;
03933                      }
03934                   }
03935                   if (!p->subs[SUB_THREEWAY].owner) {
03936                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03937                      return NULL;
03938                   }
03939                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03940                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03941                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03942                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03943                         hanging up.  Hangup both channels now */
03944                      if (p->subs[SUB_THREEWAY].owner)
03945                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03946                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03947                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03948                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03949                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03950                      if (p->transfer) {
03951                         /* In any case this isn't a threeway call anymore */
03952                         p->subs[SUB_REAL].inthreeway = 0;
03953                         p->subs[SUB_THREEWAY].inthreeway = 0;
03954                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03955                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03956                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03957                            /* Swap subs and dis-own channel */
03958                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03959                            p->owner = NULL;
03960                            /* Ring the phone */
03961                            zt_ring_phone(p);
03962                         } else {
03963                            if ((res = attempt_transfer(p)) < 0) {
03964                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03965                               if (p->subs[SUB_THREEWAY].owner)
03966                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03967                            } else if (res) {
03968                               /* Don't actually hang up at this point */
03969                               if (p->subs[SUB_THREEWAY].owner)
03970                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03971                               break;
03972                            }
03973                         }
03974                      } else {
03975                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03976                         if (p->subs[SUB_THREEWAY].owner)
03977                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03978                      }
03979                   } else {
03980                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03981                      /* Swap subs and dis-own channel */
03982                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03983                      p->owner = NULL;
03984                      /* Ring the phone */
03985                      zt_ring_phone(p);
03986                   }
03987                }
03988             } else {
03989                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03990             }
03991             /* Fall through */
03992          default:
03993             zt_disable_ec(p);
03994             return NULL;
03995          }
03996          break;
03997       case ZT_EVENT_RINGOFFHOOK:
03998          if (p->inalarm) break;
03999          if (p->oprmode < 0)
04000          {
04001             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04002             {
04003                /* Make sure it stops ringing */
04004                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04005                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
04006                restore_conference(p->oprpeer);
04007             }
04008             break;
04009          }
04010          if (p->radio)
04011          {
04012             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04013             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04014             break;
04015          }
04016          /* for E911, its supposed to wait for offhook then dial
04017             the second half of the dial string */
04018          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04019             c = strchr(p->dialdest, '/');
04020             if (c)
04021                c++;
04022             else
04023                c = p->dialdest;
04024             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04025             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04026             if (strlen(p->dop.dialstr) > 4) {
04027                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04028                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04029                p->echorest[sizeof(p->echorest) - 1] = '\0';
04030                p->echobreak = 1;
04031                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04032             } else
04033                p->echobreak = 0;
04034             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
04035                x = ZT_ONHOOK;
04036                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
04037                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
04038                return NULL;
04039                }
04040             p->dialing = 1;
04041             return &p->subs[index].f;
04042          }
04043          switch (p->sig) {
04044          case SIG_FXOLS:
04045          case SIG_FXOGS:
04046          case SIG_FXOKS:
04047             switch (ast->_state) {
04048             case AST_STATE_RINGING:
04049                zt_enable_ec(p);
04050                zt_train_ec(p);
04051                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04052                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04053                /* Make sure it stops ringing */
04054                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04055                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04056                if (p->cidspill) {
04057                   /* Cancel any running CallerID spill */
04058                   free(p->cidspill);
04059                   p->cidspill = NULL;
04060                }
04061                p->dialing = 0;
04062                p->callwaitcas = 0;
04063                if (p->confirmanswer) {
04064                   /* Ignore answer if "confirm answer" is enabled */
04065                   p->subs[index].f.frametype = AST_FRAME_NULL;
04066                   p->subs[index].f.subclass = 0;
04067                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04068                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04069                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04070                   if (res < 0) {
04071                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04072                      p->dop.dialstr[0] = '\0';
04073                      return NULL;
04074                   } else {
04075                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04076                      p->subs[index].f.frametype = AST_FRAME_NULL;
04077                      p->subs[index].f.subclass = 0;
04078                      p->dialing = 1;
04079                   }
04080                   p->dop.dialstr[0] = '\0';
04081                   ast_setstate(ast, AST_STATE_DIALING);
04082                } else
04083                   ast_setstate(ast, AST_STATE_UP);
04084                return &p->subs[index].f;
04085             case AST_STATE_DOWN:
04086                ast_setstate(ast, AST_STATE_RING);
04087                ast->rings = 1;
04088                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04089                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04090                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04091                return &p->subs[index].f;
04092             case AST_STATE_UP:
04093                /* Make sure it stops ringing */
04094                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04095                /* Okay -- probably call waiting*/
04096                if (ast_bridged_channel(p->owner))
04097                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04098                p->subs[index].needunhold = 1;
04099                break;
04100             case AST_STATE_RESERVED:
04101                /* Start up dialtone */
04102                if (has_voicemail(p))
04103                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04104                else
04105                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04106                break;
04107             default:
04108                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04109             }
04110             break;
04111          case SIG_FXSLS:
04112          case SIG_FXSGS:
04113          case SIG_FXSKS:
04114             if (ast->_state == AST_STATE_RING) {
04115                p->ringt = p->ringt_base;
04116             }
04117 
04118             /* Fall through */
04119          case SIG_EM:
04120          case SIG_EM_E1:
04121          case SIG_EMWINK:
04122          case SIG_FEATD:
04123          case SIG_FEATDMF:
04124          case SIG_FEATDMF_TA:
04125          case SIG_E911:
04126          case SIG_FGC_CAMA:
04127          case SIG_FGC_CAMAMF:
04128          case SIG_FEATB:
04129          case SIG_SF:
04130          case SIG_SFWINK:
04131          case SIG_SF_FEATD:
04132          case SIG_SF_FEATDMF:
04133          case SIG_SF_FEATB:
04134             if (ast->_state == AST_STATE_PRERING)
04135                ast_setstate(ast, AST_STATE_RING);
04136             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04137                if (option_debug)
04138                   ast_log(LOG_DEBUG, "Ring detected\n");
04139                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04140                p->subs[index].f.subclass = AST_CONTROL_RING;
04141             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04142                if (option_debug)
04143                   ast_log(LOG_DEBUG, "Line answered\n");
04144                if (p->confirmanswer) {
04145                   p->subs[index].f.frametype = AST_FRAME_NULL;
04146                   p->subs[index].f.subclass = 0;
04147                } else {
04148                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04149                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04150                   ast_setstate(ast, AST_STATE_UP);
04151                }
04152             } else if (ast->_state != AST_STATE_RING)
04153                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04154             break;
04155          default:
04156             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04157          }
04158          break;
04159 #ifdef ZT_EVENT_RINGBEGIN
04160       case ZT_EVENT_RINGBEGIN:
04161          switch (p->sig) {
04162          case SIG_FXSLS:
04163          case SIG_FXSGS:
04164          case SIG_FXSKS:
04165             if (ast->_state == AST_STATE_RING) {
04166                p->ringt = p->ringt_base;
04167             }
04168             break;
04169          }
04170          break;
04171 #endif         
04172       case ZT_EVENT_RINGEROFF:
04173          if (p->inalarm) break;
04174          if ((p->radio || (p->oprmode < 0))) break;
04175          ast->rings++;
04176          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04177             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04178             free(p->cidspill);
04179             p->cidspill = NULL;
04180             p->callwaitcas = 0;
04181          }
04182          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04183          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04184          break;
04185       case ZT_EVENT_RINGERON:
04186          break;
04187       case ZT_EVENT_NOALARM:
04188          p->inalarm = 0;
04189 #ifdef HAVE_PRI
04190          /* Extremely unlikely but just in case */
04191          if (p->bearer)
04192             p->bearer->inalarm = 0;
04193 #endif            
04194          if (!p->unknown_alarm) {
04195             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04196             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04197                "Channel: %d\r\n", p->channel);
04198          } else {
04199             p->unknown_alarm = 0;
04200          }
04201          break;
04202       case ZT_EVENT_WINKFLASH:
04203          if (p->inalarm) break;
04204          if (p->radio) break;
04205          if (p->oprmode < 0) break;
04206          if (p->oprmode > 1)
04207          {
04208             struct zt_params par;
04209 
04210             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04211             {
04212                if (!par.rxisoffhook)
04213                {
04214                   /* Make sure it stops ringing */
04215                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04216                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04217                   save_conference(p);
04218                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04219                }
04220             }
04221             break;
04222          }
04223          /* Remember last time we got a flash-hook */
04224          gettimeofday(&p->flashtime, NULL);
04225          switch (mysig) {
04226          case SIG_FXOLS:
04227          case SIG_FXOGS:
04228          case SIG_FXOKS:
04229             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04230                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04231             p->callwaitcas = 0;
04232 
04233             if (index != SUB_REAL) {
04234                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04235                goto winkflashdone;
04236             }
04237             
04238             if (p->subs[SUB_CALLWAIT].owner) {
04239                /* Swap to call-wait */
04240                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04241                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04242                p->owner = p->subs[SUB_REAL].owner;
04243                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04244                if (p->owner->_state == AST_STATE_RINGING) {
04245                   ast_setstate(p->owner, AST_STATE_UP);
04246                   p->subs[SUB_REAL].needanswer = 1;
04247                }
04248                p->callwaitingrepeat = 0;
04249                p->cidcwexpire = 0;
04250                /* Start music on hold if appropriate */
04251                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04252                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04253                      S_OR(p->mohsuggest, NULL),
04254                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04255                }
04256                p->subs[SUB_CALLWAIT].needhold = 1;
04257                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04258                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04259                      S_OR(p->mohsuggest, NULL),
04260                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04261                }
04262                p->subs[SUB_REAL].needunhold = 1;
04263             } else if (!p->subs[SUB_THREEWAY].owner) {
04264                char cid_num[256];
04265                char cid_name[256];
04266 
04267                if (!p->threewaycalling) {
04268                   /* Just send a flash if no 3-way calling */
04269                   p->subs[SUB_REAL].needflash = 1;
04270                   goto winkflashdone;
04271                } else if (!check_for_conference(p)) {
04272                   if (p->zaptrcallerid && p->owner) {
04273                      if (p->owner->cid.cid_num)
04274                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04275                      if (p->owner->cid.cid_name)
04276                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04277                   }
04278                   /* XXX This section needs much more error checking!!! XXX */
04279                   /* Start a 3-way call if feasible */
04280                   if (!((ast->pbx) ||
04281                         (ast->_state == AST_STATE_UP) ||
04282                         (ast->_state == AST_STATE_RING))) {
04283                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04284                         goto winkflashdone;
04285                   }
04286                   if (alloc_sub(p, SUB_THREEWAY)) {
04287                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04288                      goto winkflashdone;
04289                   }
04290                   /* Make new channel */
04291                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04292                   if (p->zaptrcallerid) {
04293                      if (!p->origcid_num)
04294                         p->origcid_num = ast_strdup(p->cid_num);
04295                      if (!p->origcid_name)
04296                         p->origcid_name = ast_strdup(p->cid_name);
04297                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04298                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04299                   }
04300                   /* Swap things around between the three-way and real call */
04301                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04302                   /* Disable echo canceller for better dialing */
04303                   zt_disable_ec(p);
04304                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04305                   if (res)
04306                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04307                   p->owner = chan;
04308                   pthread_attr_init(&attr);
04309                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04310                   if (!chan) {
04311                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04312                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04313                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04314                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04315                      zt_enable_ec(p);
04316                      ast_hangup(chan);
04317                   } else {
04318                      if (option_verbose > 2) 
04319                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04320                      /* Start music on hold if appropriate */
04321                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04322                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04323                            S_OR(p->mohsuggest, NULL),
04324                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04325                      }
04326                      p->subs[SUB_THREEWAY].needhold = 1;
04327                   }
04328                   pthread_attr_destroy(&attr);
04329                }
04330             } else {
04331                /* Already have a 3 way call */
04332                if (p->subs[SUB_THREEWAY].inthreeway) {
04333                   /* Call is already up, drop the last person */
04334                   if (option_debug)
04335                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04336                   /* If the primary call isn't answered yet, use it */
04337                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04338                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04339                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04340                      p->owner = p->subs[SUB_REAL].owner;
04341                   }
04342                   /* Drop the last call and stop the conference */
04343                   if (option_verbose > 2)
04344                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04345                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04346                   p->subs[SUB_REAL].inthreeway = 0;
04347                   p->subs[SUB_THREEWAY].inthreeway = 0;
04348                } else {
04349                   /* Lets see what we're up to */
04350                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04351                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04352                      int otherindex = SUB_THREEWAY;
04353 
04354                      if (option_verbose > 2)
04355                         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);
04356                      /* Put them in the threeway, and flip */
04357                      p->subs[SUB_THREEWAY].inthreeway = 1;
04358                      p->subs[SUB_REAL].inthreeway = 1;
04359                      if (ast->_state == AST_STATE_UP) {
04360                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04361                         otherindex = SUB_REAL;
04362                      }
04363                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04364                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04365                      p->subs[otherindex].needunhold = 1;
04366                      p->owner = p->subs[SUB_REAL].owner;
04367                      if (ast->_state == AST_STATE_RINGING) {
04368                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04369                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04370                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04371                      }
04372                   } else {
04373                      if (option_verbose > 2)
04374                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04375                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04376                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04377                      p->owner = p->subs[SUB_REAL].owner;
04378                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04379                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04380                      p->subs[SUB_REAL].needunhold = 1;
04381                      zt_enable_ec(p);
04382                   }
04383                      
04384                }
04385             }
04386          winkflashdone:              
04387             update_conf(p);
04388             break;
04389          case SIG_EM:
04390          case SIG_EM_E1:
04391          case SIG_EMWINK:
04392          case SIG_FEATD:
04393          case SIG_SF:
04394          case SIG_SFWINK:
04395          case SIG_SF_FEATD:
04396          case SIG_FXSLS:
04397          case SIG_FXSGS:
04398             if (p->dialing)
04399                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04400             else
04401                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04402             break;
04403          case SIG_FEATDMF_TA:
04404             switch (p->whichwink) {
04405             case 0:
04406                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04407                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04408                break;
04409             case 1:
04410                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04411                break;
04412             case 2:
04413                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04414                return NULL;
04415             }
04416             p->whichwink++;
04417             /* Fall through */
04418          case SIG_FEATDMF:
04419          case SIG_E911:
04420          case SIG_FGC_CAMAMF:
04421          case SIG_FGC_CAMA:
04422          case SIG_FEATB:
04423          case SIG_SF_FEATDMF:
04424          case SIG_SF_FEATB:
04425             /* FGD MF *Must* wait for wink */
04426             if (!ast_strlen_zero(p->dop.dialstr)) {
04427                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04428                if (res < 0) {
04429                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04430                   p->dop.dialstr[0] = '\0';
04431                   return NULL;
04432                } else 
04433                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04434             }
04435             p->dop.dialstr[0] = '\0';
04436             break;
04437          default:
04438             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04439          }
04440          break;
04441       case ZT_EVENT_HOOKCOMPLETE:
04442          if (p->inalarm) break;
04443          if ((p->radio || (p->oprmode < 0))) break;
04444          switch (mysig) {
04445          case SIG_FXSLS:  /* only interesting for FXS */
04446          case SIG_FXSGS:
04447          case SIG_FXSKS:
04448          case SIG_EM:
04449          case SIG_EM_E1:
04450          case SIG_EMWINK:
04451          case SIG_FEATD:
04452          case SIG_SF:
04453          case SIG_SFWINK:
04454          case SIG_SF_FEATD:
04455             if (!ast_strlen_zero(p->dop.dialstr)) {
04456                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04457                if (res < 0) {
04458                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04459                   p->dop.dialstr[0] = '\0';
04460                   return NULL;
04461                } else 
04462                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04463             }
04464             p->dop.dialstr[0] = '\0';
04465             p->dop.op = ZT_DIAL_OP_REPLACE;
04466             break;
04467          case SIG_FEATDMF:
04468          case SIG_FEATDMF_TA:
04469          case SIG_E911:
04470          case SIG_FGC_CAMA:
04471          case SIG_FGC_CAMAMF:
04472          case SIG_FEATB:
04473          case SIG_SF_FEATDMF:
04474          case SIG_SF_FEATB:
04475             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04476             break;
04477          default:
04478             break;
04479          }
04480          break;
04481       case ZT_EVENT_POLARITY:
04482          /*
04483           * If we get a Polarity Switch event, check to see
04484           * if we should change the polarity state and
04485           * mark the channel as UP or if this is an indication
04486           * of remote end disconnect.
04487           */
04488          if (p->polarity == POLARITY_IDLE) {
04489             p->polarity = POLARITY_REV;
04490             if (p->answeronpolarityswitch &&
04491                 ((ast->_state == AST_STATE_DIALING) ||
04492                 (ast->_state == AST_STATE_RINGING))) {
04493                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04494                ast_setstate(p->owner, AST_STATE_UP);
04495                if (p->hanguponpolarityswitch) {
04496                   gettimeofday(&p->polaritydelaytv, NULL);
04497                }
04498             } else
04499                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04500          } 
04501          /* Removed else statement from here as it was preventing hangups from ever happening*/
04502          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04503          if (p->hanguponpolarityswitch &&
04504             (p->polarityonanswerdelay > 0) &&
04505                 (p->polarity == POLARITY_REV) &&
04506             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04507                                 /* Added log_debug information below to provide a better indication of what is going on */
04508             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) );
04509          
04510             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04511                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04512                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04513                p->polarity = POLARITY_IDLE;
04514             } else {
04515                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);
04516             }
04517          } else {
04518             p->polarity = POLARITY_IDLE;
04519             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04520          }
04521                         /* Added more log_debug information below to provide a better indication of what is going on */
04522          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) );
04523          break;
04524       default:
04525          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04526    }
04527    return &p->subs[index].f;
04528 }
04529 
04530 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04531 {
04532    struct zt_pvt *p = ast->tech_pvt;
04533    int res;
04534    int usedindex=-1;
04535    int index;
04536    struct ast_frame *f;
04537 
04538 
04539    index = zt_get_index(ast, p, 1);
04540    
04541    p->subs[index].f.frametype = AST_FRAME_NULL;
04542    p->subs[index].f.datalen = 0;
04543    p->subs[index].f.samples = 0;
04544    p->subs[index].f.mallocd = 0;
04545    p->subs[index].f.offset = 0;
04546    p->subs[index].f.subclass = 0;
04547    p->subs[index].f.delivery = ast_tv(0,0);
04548    p->subs[index].f.src = "zt_exception";
04549    p->subs[index].f.data = NULL;
04550    
04551    
04552    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04553       /* If nobody owns us, absorb the event appropriately, otherwise
04554          we loop indefinitely.  This occurs when, during call waiting, the
04555          other end hangs up our channel so that it no longer exists, but we
04556          have neither FLASH'd nor ONHOOK'd to signify our desire to
04557          change to the other channel. */
04558       if (p->fake_event) {
04559          res = p->fake_event;
04560          p->fake_event = 0;
04561       } else
04562          res = zt_get_event(p->subs[SUB_REAL].zfd);
04563       /* Switch to real if there is one and this isn't something really silly... */
04564       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04565          (res != ZT_EVENT_HOOKCOMPLETE)) {
04566          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04567          p->owner = p->subs[SUB_REAL].owner;
04568          if (p->owner && ast_bridged_channel(p->owner))
04569             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04570          p->subs[SUB_REAL].needunhold = 1;
04571       }
04572       switch (res) {
04573       case ZT_EVENT_ONHOOK:
04574          zt_disable_ec(p);
04575          if (p->owner) {
04576             if (option_verbose > 2) 
04577                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04578             zt_ring_phone(p);
04579             p->callwaitingrepeat = 0;
04580             p->cidcwexpire = 0;
04581          } else
04582             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04583          update_conf(p);
04584          break;
04585       case ZT_EVENT_RINGOFFHOOK:
04586          zt_enable_ec(p);
04587          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04588          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04589             p->subs[SUB_REAL].needanswer = 1;
04590             p->dialing = 0;
04591          }
04592          break;
04593       case ZT_EVENT_HOOKCOMPLETE:
04594       case ZT_EVENT_RINGERON:
04595       case ZT_EVENT_RINGEROFF:
04596          /* Do nothing */
04597          break;
04598       case ZT_EVENT_WINKFLASH:
04599          gettimeofday(&p->flashtime, NULL);
04600          if (p->owner) {
04601             if (option_verbose > 2) 
04602                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04603             if (p->owner->_state != AST_STATE_UP) {
04604                /* Answer if necessary */
04605                usedindex = zt_get_index(p->owner, p, 0);
04606                if (usedindex > -1) {
04607                   p->subs[usedindex].needanswer = 1;
04608                }
04609                ast_setstate(p->owner, AST_STATE_UP);
04610             }
04611             p->callwaitingrepeat = 0;
04612             p->cidcwexpire = 0;
04613             if (ast_bridged_channel(p->owner))
04614                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04615             p->subs[SUB_REAL].needunhold = 1;
04616          } else
04617             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04618          update_conf(p);
04619          break;
04620       default:
04621          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04622       }
04623       f = &p->subs[index].f;
04624       return f;
04625    }
04626    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04627       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04628    /* If it's not us, return NULL immediately */
04629    if (ast != p->owner) {
04630       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04631       f = &p->subs[index].f;
04632       return f;
04633    }
04634    f = zt_handle_event(ast);
04635    return f;
04636 }
04637 
04638 static struct ast_frame *zt_exception(struct ast_channel *ast)
04639 {
04640    struct zt_pvt *p = ast->tech_pvt;
04641    struct ast_frame *f;
04642    ast_mutex_lock(&p->lock);
04643    f = __zt_exception(ast);
04644    ast_mutex_unlock(&p->lock);
04645    return f;
04646 }
04647 
04648 static struct ast_frame  *zt_read(struct ast_channel *ast)
04649 {
04650    struct zt_pvt *p = ast->tech_pvt;
04651    int res;
04652    int index;
04653    void *readbuf;
04654    struct ast_frame *f;
04655    
04656 
04657    ast_mutex_lock(&p->lock);
04658    
04659    index = zt_get_index(ast, p, 0);
04660    
04661    /* Hang up if we don't really exist */
04662    if (index < 0) {
04663       ast_log(LOG_WARNING, "We dont exist?\n");
04664       ast_mutex_unlock(&p->lock);
04665       return NULL;
04666    }
04667    
04668    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04669 
04670    p->subs[index].f.frametype = AST_FRAME_NULL;
04671    p->subs[index].f.datalen = 0;
04672    p->subs[index].f.samples = 0;
04673    p->subs[index].f.mallocd = 0;
04674    p->subs[index].f.offset = 0;
04675    p->subs[index].f.subclass = 0;
04676    p->subs[index].f.delivery = ast_tv(0,0);
04677    p->subs[index].f.src = "zt_read";
04678    p->subs[index].f.data = NULL;
04679    
04680    /* make sure it sends initial key state as first frame */
04681    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04682    {
04683       ZT_PARAMS ps;
04684 
04685       ps.channo = p->channel;
04686       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04687          ast_mutex_unlock(&p->lock);
04688          return NULL;
04689       }
04690       p->firstradio = 1;
04691       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04692       if (ps.rxisoffhook)
04693       {
04694          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04695       }
04696       else
04697       {
04698          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04699       }
04700       ast_mutex_unlock(&p->lock);
04701       return &p->subs[index].f;
04702    }
04703    if (p->ringt == 1) {
04704       ast_mutex_unlock(&p->lock);
04705       return NULL;
04706    }
04707    else if (p->ringt > 0) 
04708       p->ringt--;
04709 
04710    if (p->subs[index].needringing) {
04711       /* Send ringing frame if requested */
04712       p->subs[index].needringing = 0;
04713       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04714       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04715       ast_setstate(ast, AST_STATE_RINGING);
04716       ast_mutex_unlock(&p->lock);
04717       return &p->subs[index].f;
04718    }
04719 
04720    if (p->subs[index].needbusy) {
04721       /* Send busy frame if requested */
04722       p->subs[index].needbusy = 0;
04723       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04724       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04725       ast_mutex_unlock(&p->lock);
04726       return &p->subs[index].f;
04727    }
04728 
04729    if (p->subs[index].needcongestion) {
04730       /* Send congestion frame if requested */
04731       p->subs[index].needcongestion = 0;
04732       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04733       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04734       ast_mutex_unlock(&p->lock);
04735       return &p->subs[index].f;
04736    }
04737 
04738    if (p->subs[index].needcallerid) {
04739       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04740                      S_OR(p->lastcid_name, NULL),
04741                      S_OR(p->lastcid_num, NULL)
04742                      );
04743       p->subs[index].needcallerid = 0;
04744    }
04745    
04746    if (p->subs[index].needanswer) {
04747       /* Send answer frame if requested */
04748       p->subs[index].needanswer = 0;
04749       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04750       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04751       ast_mutex_unlock(&p->lock);
04752       return &p->subs[index].f;
04753    }  
04754    
04755    if (p->subs[index].needflash) {
04756       /* Send answer frame if requested */
04757       p->subs[index].needflash = 0;
04758       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04759       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04760       ast_mutex_unlock(&p->lock);
04761       return &p->subs[index].f;
04762    }  
04763    
04764    if (p->subs[index].needhold) {
04765       /* Send answer frame if requested */
04766       p->subs[index].needhold = 0;
04767       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04768       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04769       ast_mutex_unlock(&p->lock);
04770       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04771       return &p->subs[index].f;
04772    }  
04773    
04774    if (p->subs[index].needunhold) {
04775       /* Send answer frame if requested */
04776       p->subs[index].needunhold = 0;
04777       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04778       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04779       ast_mutex_unlock(&p->lock);
04780       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04781       return &p->subs[index].f;
04782    }  
04783    
04784    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04785       if (!p->subs[index].linear) {
04786          p->subs[index].linear = 1;
04787          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04788          if (res) 
04789             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04790       }
04791    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04792          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04793       if (p->subs[index].linear) {
04794          p->subs[index].linear = 0;
04795          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04796          if (res) 
04797             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04798       }
04799    } else {
04800       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04801       ast_mutex_unlock(&p->lock);
04802       return NULL;
04803    }
04804    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04805    CHECK_BLOCKING(ast);
04806    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04807    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04808    /* Check for hangup */
04809    if (res < 0) {
04810       f = NULL;
04811       if (res == -1)  {
04812          if (errno == EAGAIN) {
04813             /* Return "NULL" frame if there is nobody there */
04814             ast_mutex_unlock(&p->lock);
04815             return &p->subs[index].f;
04816          } else if (errno == ELAST) {
04817             f = __zt_exception(ast);
04818          } else
04819             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04820       }
04821       ast_mutex_unlock(&p->lock);
04822       return f;
04823    }
04824    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04825       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04826       f = __zt_exception(ast);
04827       ast_mutex_unlock(&p->lock);
04828       return f;
04829    }
04830    if (p->tdd) { /* if in TDD mode, see if we receive that */
04831       int c;
04832 
04833       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04834       if (c < 0) {
04835          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04836          ast_mutex_unlock(&p->lock);
04837          return NULL;
04838       }
04839       if (c) { /* if a char to return */
04840          p->subs[index].f.subclass = 0;
04841          p->subs[index].f.frametype = AST_FRAME_TEXT;
04842          p->subs[index].f.mallocd = 0;
04843          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04844          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04845          p->subs[index].f.datalen = 1;
04846          *((char *) p->subs[index].f.data) = c;
04847          ast_mutex_unlock(&p->lock);
04848          return &p->subs[index].f;
04849       }
04850    }
04851    /* Ensure the CW timer decrements only on a single subchannel */
04852    if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) {
04853       p->callwaitingrepeat--;
04854    }
04855    if (p->cidcwexpire)
04856       p->cidcwexpire--;
04857    /* Repeat callwaiting */
04858    if (p->callwaitingrepeat == 1) {
04859       p->callwaitrings++;
04860       zt_callwait(ast);
04861    }
04862    /* Expire CID/CW */
04863    if (p->cidcwexpire == 1) {
04864       if (option_verbose > 2)
04865          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04866       restore_conference(p);
04867    }
04868    if (p->subs[index].linear) {
04869       p->subs[index].f.datalen = READ_SIZE * 2;
04870    } else 
04871       p->subs[index].f.datalen = READ_SIZE;
04872 
04873    /* Handle CallerID Transmission */
04874    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04875       send_callerid(p);
04876    }
04877 
04878    p->subs[index].f.frametype = AST_FRAME_VOICE;
04879    p->subs[index].f.subclass = ast->rawreadformat;
04880    p->subs[index].f.samples = READ_SIZE;
04881    p->subs[index].f.mallocd = 0;
04882    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04883    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
04884 #if 0
04885    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04886 #endif   
04887    if (p->dialing || /* Transmitting something */
04888       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04889       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04890       ) {
04891       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04892          don't send anything */
04893       p->subs[index].f.frametype = AST_FRAME_NULL;
04894       p->subs[index].f.subclass = 0;
04895       p->subs[index].f.samples = 0;
04896       p->subs[index].f.mallocd = 0;
04897       p->subs[index].f.offset = 0;
04898       p->subs[index].f.data = NULL;
04899       p->subs[index].f.datalen= 0;
04900    }
04901    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04902       /* Perform busy detection. etc on the zap line */
04903       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04904       if (f) {
04905          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04906             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04907                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04908                   a busy  */
04909                f = NULL;
04910             }
04911          } else if (f->frametype == AST_FRAME_DTMF) {
04912 #ifdef HAVE_PRI
04913             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04914                /* Don't accept in-band DTMF when in overlap dial mode */
04915                f->frametype = AST_FRAME_NULL;
04916                f->subclass = 0;
04917             }
04918 #endif            
04919             /* DSP clears us of being pulse */
04920             p->pulsedial = 0;
04921          }
04922       }
04923    } else 
04924       f = &p->subs[index].f; 
04925 
04926    if (f && (f->frametype == AST_FRAME_DTMF))
04927       zt_handle_dtmfup(ast, index, &f);
04928 
04929    /* If we have a fake_event, trigger exception to handle it */
04930    if (p->fake_event)
04931       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04932 
04933    ast_mutex_unlock(&p->lock);
04934    return f;
04935 }
04936 
04937 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
04938 {
04939    int sent=0;
04940    int size;
04941    int res;
04942    int fd;
04943    fd = p->subs[index].zfd;
04944    while (len) {
04945       size = len;
04946       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04947          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04948       res = write(fd, buf, size);
04949       if (res != size) {
04950          if (option_debug)
04951             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04952          return sent;
04953       }
04954       len -= size;
04955       buf += size;
04956    }
04957    return sent;
04958 }
04959 
04960 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
04961 {
04962    struct zt_pvt *p = ast->tech_pvt;
04963    int res;
04964    int index;
04965    index = zt_get_index(ast, p, 0);
04966    if (index < 0) {
04967       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04968       return -1;
04969    }
04970 
04971 #if 0
04972 #ifdef HAVE_PRI
04973    ast_mutex_lock(&p->lock);
04974    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04975       if (p->pri->pri) {      
04976          if (!pri_grab(p, p->pri)) {
04977                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04978                pri_rel(p->pri);
04979          } else
04980                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04981       }
04982       p->proceeding=1;
04983    }
04984    ast_mutex_unlock(&p->lock);
04985 #endif
04986 #endif
04987    /* Write a frame of (presumably voice) data */
04988    if (frame->frametype != AST_FRAME_VOICE) {
04989       if (frame->frametype != AST_FRAME_IMAGE)
04990          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04991       return 0;
04992    }
04993    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04994        (frame->subclass != AST_FORMAT_ULAW) &&
04995        (frame->subclass != AST_FORMAT_ALAW)) {
04996       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04997       return -1;
04998    }
04999    if (p->dialing) {
05000       if (option_debug)
05001          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
05002       return 0;
05003    }
05004    if (!p->owner) {
05005       if (option_debug)
05006          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
05007       return 0;
05008    }
05009    if (p->cidspill) {
05010       if (option_debug)
05011          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
05012       return 0;
05013    }
05014    /* Return if it's not valid data */
05015    if (!frame->data || !frame->datalen)
05016       return 0;
05017 
05018    if (frame->subclass == AST_FORMAT_SLINEAR) {
05019       if (!p->subs[index].linear) {
05020          p->subs[index].linear = 1;
05021          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05022          if (res)
05023             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05024       }
05025       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05026    } else {
05027       /* x-law already */
05028       if (p->subs[index].linear) {
05029          p->subs[index].linear = 0;
05030          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05031          if (res)
05032             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05033       }
05034       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05035    }
05036    if (res < 0) {
05037       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05038       return -1;
05039    } 
05040    return 0;
05041 }
05042 
05043 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05044 {
05045    struct zt_pvt *p = chan->tech_pvt;
05046    int res=-1;
05047    int index;
05048    int func = ZT_FLASH;
05049    ast_mutex_lock(&p->lock);
05050    index = zt_get_index(chan, p, 0);
05051    if (option_debug)
05052       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05053    if (index == SUB_REAL) {
05054       switch (condition) {
05055       case AST_CONTROL_BUSY:
05056 #ifdef HAVE_PRI
05057          if (p->priindication_oob && p->sig == SIG_PRI) {
05058             chan->hangupcause = AST_CAUSE_USER_BUSY;
05059             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05060             res = 0;
05061          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05062             if (p->pri->pri) {      
05063                if (!pri_grab(p, p->pri)) {
05064                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05065                   pri_rel(p->pri);
05066                }
05067                else
05068                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05069             }
05070             p->progress = 1;
05071             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05072          } else
05073 #endif
05074             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05075          break;
05076       case AST_CONTROL_RINGING:
05077 #ifdef HAVE_PRI
05078          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05079             if (p->pri->pri) {      
05080                if (!pri_grab(p, p->pri)) {
05081                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05082                   pri_rel(p->pri);
05083                }
05084                else
05085                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05086             }
05087             p->alerting = 1;
05088          }
05089 #endif
05090          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05091          if (chan->_state != AST_STATE_UP) {
05092             if ((chan->_state != AST_STATE_RING) ||
05093                ((p->sig != SIG_FXSKS) &&
05094                 (p->sig != SIG_FXSLS) &&
05095                 (p->sig != SIG_FXSGS)))
05096                ast_setstate(chan, AST_STATE_RINGING);
05097          }
05098          break;
05099       case AST_CONTROL_PROCEEDING:
05100          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05101 #ifdef HAVE_PRI
05102          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05103             if (p->pri->pri) {      
05104                if (!pri_grab(p, p->pri)) {
05105                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05106                   pri_rel(p->pri);
05107                }
05108                else
05109                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05110             }
05111             p->proceeding = 1;
05112          }
05113 #endif
05114          /* don't continue in ast_indicate */
05115          res = 0;
05116          break;
05117       case AST_CONTROL_PROGRESS:
05118          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05119 #ifdef HAVE_PRI
05120          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05121          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05122             if (p->pri->pri) {      
05123                if (!pri_grab(p, p->pri)) {
05124                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05125                   pri_rel(p->pri);
05126                }
05127                else
05128                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05129             }
05130             p->progress = 1;
05131          }
05132 #endif
05133          /* don't continue in ast_indicate */
05134          res = 0;
05135          break;
05136       case AST_CONTROL_CONGESTION:
05137          chan->hangupcause = AST_CAUSE_CONGESTION;
05138 #ifdef HAVE_PRI
05139          if (p->priindication_oob && p->sig == SIG_PRI) {
05140             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05141             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05142             res = 0;
05143          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05144             if (p->pri) {     
05145                if (!pri_grab(p, p->pri)) {
05146                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05147                   pri_rel(p->pri);
05148                } else
05149                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05150             }
05151             p->progress = 1;
05152             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05153          } else
05154 #endif
05155             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05156          break;
05157       case AST_CONTROL_HOLD:
05158 #ifdef HAVE_PRI
05159          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05160             if (!pri_grab(p, p->pri)) {
05161                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05162                pri_rel(p->pri);
05163             } else
05164                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05165          } else
05166 #endif
05167             ast_moh_start(chan, data, p->mohinterpret);
05168          break;
05169       case AST_CONTROL_UNHOLD:
05170 #ifdef HAVE_PRI
05171          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05172             if (!pri_grab(p, p->pri)) {
05173                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05174                pri_rel(p->pri);
05175             } else
05176                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05177          } else
05178 #endif
05179             ast_moh_stop(chan);
05180          break;
05181       case AST_CONTROL_RADIO_KEY:
05182          if (p->radio) 
05183              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05184          res = 0;
05185          break;
05186       case AST_CONTROL_RADIO_UNKEY:
05187          if (p->radio)
05188              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05189          res = 0;
05190          break;
05191       case AST_CONTROL_FLASH:
05192          /* flash hookswitch */
05193          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05194             /* Clear out the dial buffer */
05195             p->dop.dialstr[0] = '\0';
05196             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05197                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05198                   chan->name, strerror(errno));
05199             } else
05200                res = 0;
05201          } else
05202             res = 0;
05203          break;
05204       case AST_CONTROL_SRCUPDATE:
05205          res = 0;
05206          break;
05207       case -1:
05208          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05209          break;
05210       }
05211    } else
05212       res = 0;
05213    ast_mutex_unlock(&p->lock);
05214    return res;
05215 }
05216 
05217 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05218 {
05219    struct ast_channel *tmp;
05220    int deflaw;
05221    int res;
05222    int x,y;
05223    int features;
05224    char *b2 = NULL;
05225    ZT_PARAMS ps;
05226    if (i->subs[index].owner) {
05227       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05228       return NULL;
05229    }
05230    y = 1;
05231    do {
05232       if (b2)
05233          free(b2);
05234 #ifdef HAVE_PRI
05235       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05236          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05237       else
05238 #endif
05239       if (i->channel == CHAN_PSEUDO)
05240          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05241       else  
05242          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05243       for (x = 0; x < 3; x++) {
05244          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05245             break;
05246       }
05247       y++;
05248    } while (x < 3);
05249    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05250    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05251       free(b2);
05252    if (!tmp)
05253       return NULL;
05254    tmp->tech = &zap_tech;
05255    ps.channo = i->channel;
05256    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05257    if (res) {
05258       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05259       ps.curlaw = ZT_LAW_MULAW;
05260    }
05261    if (ps.curlaw == ZT_LAW_ALAW)
05262       deflaw = AST_FORMAT_ALAW;
05263    else
05264       deflaw = AST_FORMAT_ULAW;
05265    if (law) {
05266       if (law == ZT_LAW_ALAW)
05267          deflaw = AST_FORMAT_ALAW;
05268       else
05269          deflaw = AST_FORMAT_ULAW;
05270    }
05271    tmp->fds[0] = i->subs[index].zfd;
05272    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05273    /* Start out assuming ulaw since it's smaller :) */
05274    tmp->rawreadformat = deflaw;
05275    tmp->readformat = deflaw;
05276    tmp->rawwriteformat = deflaw;
05277    tmp->writeformat = deflaw;
05278    i->subs[index].linear = 0;
05279    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05280    features = 0;
05281    if (index == SUB_REAL) {
05282       if (i->busydetect && CANBUSYDETECT(i))
05283          features |= DSP_FEATURE_BUSY_DETECT;
05284       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05285          features |= DSP_FEATURE_CALL_PROGRESS;
05286       if ((!i->outgoing && (i->callprogress & 4)) || 
05287           (i->outgoing && (i->callprogress & 2))) {
05288          features |= DSP_FEATURE_FAX_DETECT;
05289       }
05290 #ifdef ZT_TONEDETECT
05291       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05292       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05293 #endif      
05294          i->hardwaredtmf = 0;
05295          features |= DSP_FEATURE_DTMF_DETECT;
05296 #ifdef ZT_TONEDETECT
05297       } else if (NEED_MFDETECT(i)) {
05298          i->hardwaredtmf = 1;
05299          features |= DSP_FEATURE_DTMF_DETECT;
05300       }
05301 #endif
05302    }
05303    if (features) {
05304       if (i->dsp) {
05305          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05306       } else {
05307          if (i->channel != CHAN_PSEUDO)
05308             i->dsp = ast_dsp_new();
05309          else
05310             i->dsp = NULL;
05311          if (i->dsp) {
05312             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05313 #ifdef HAVE_PRI
05314             /* We cannot do progress detection until receives PROGRESS message */
05315             if (i->outgoing && (i->sig == SIG_PRI)) {
05316                /* Remember requested DSP features, don't treat
05317                   talking as ANSWER */
05318                features = 0;
05319             }
05320 #endif
05321             ast_dsp_set_features(i->dsp, features);
05322             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05323             if (!ast_strlen_zero(progzone))
05324                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05325             if (i->busydetect && CANBUSYDETECT(i)) {
05326                if(i->silencethreshold > 0)
05327                   ast_dsp_set_threshold(i->dsp, i->silencethreshold);
05328                ast_dsp_set_busy_count(i->dsp, i->busycount);
05329                if(i->busytonelength > 0)
05330                   ast_dsp_set_busy_pattern(i->dsp, i->busytonelength, i->busyquietlength, i->busyfuzziness);
05331                if((i->busytonelength == i->busyquietlength) && i->busycompare)
05332                   ast_dsp_set_busy_compare(i->dsp, i->busycompare);
05333             }
05334          }
05335       }
05336    }
05337       
05338    if (state == AST_STATE_RING)
05339       tmp->rings = 1;
05340    tmp->tech_pvt = i;
05341    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05342       /* Only FXO signalled stuff can be picked up */
05343       tmp->callgroup = i->callgroup;
05344       tmp->pickupgroup = i->pickupgroup;
05345    }
05346    if (!ast_strlen_zero(i->language))
05347       ast_string_field_set(tmp, language, i->language);
05348    if (!i->owner)
05349       i->owner = tmp;
05350    if (!ast_strlen_zero(i->accountcode))
05351       ast_string_field_set(tmp, accountcode, i->accountcode);
05352    if (i->amaflags)
05353       tmp->amaflags = i->amaflags;
05354    i->subs[index].owner = tmp;
05355    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05356    ast_string_field_set(tmp, call_forward, i->call_forward);
05357    /* If we've been told "no ADSI" then enforce it */
05358    if (!i->adsi)
05359       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05360    if (!ast_strlen_zero(i->exten))
05361       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05362    if (!ast_strlen_zero(i->rdnis))
05363       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05364    if (!ast_strlen_zero(i->dnid))
05365       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05366 
05367    /* Don't use ast_set_callerid() here because it will
05368     * generate a needless NewCallerID event */
05369 #ifdef PRI_ANI
05370    if (!ast_strlen_zero(i->cid_ani))
05371       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05372    else  
05373       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05374 #else
05375    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05376 #endif
05377    tmp->cid.cid_pres = i->callingpres;
05378    tmp->cid.cid_ton = i->cid_ton;
05379 #ifdef HAVE_PRI
05380    tmp->transfercapability = transfercapability;
05381    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05382    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05383       i->digital = 1;
05384    /* Assume calls are not idle calls unless we're told differently */
05385    i->isidlecall = 0;
05386    i->alreadyhungup = 0;
05387 #endif
05388    /* clear the fake event in case we posted one before we had ast_channel */
05389    i->fake_event = 0;
05390    /* Assure there is no confmute on this channel */
05391    zt_confmute(i, 0);
05392    /* Configure the new channel jb */
05393    ast_jb_configure(tmp, &global_jbconf);
05394    if (startpbx) {
05395       if (ast_pbx_start(tmp)) {
05396          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05397          ast_hangup(tmp);
05398          i->owner = NULL;
05399          return NULL;
05400       }
05401    }
05402 
05403    ast_module_ref(ast_module_info->self);
05404    
05405    return tmp;
05406 }
05407 
05408 
05409 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05410 {
05411    char c;
05412 
05413    *str = 0; /* start with empty output buffer */
05414    for (;;)
05415    {
05416       /* Wait for the first digit (up to specified ms). */
05417       c = ast_waitfordigit(chan, ms);
05418       /* if timeout, hangup or error, return as such */
05419       if (c < 1)
05420          return c;
05421       *str++ = c;
05422       *str = 0;
05423       if (strchr(term, c))
05424          return 1;
05425    }
05426 }
05427 
05428 static int zt_wink(struct zt_pvt *p, int index)
05429 {
05430    int j;
05431    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05432    for (;;)
05433    {
05434          /* set bits of interest */
05435       j = ZT_IOMUX_SIGEVENT;
05436           /* wait for some happening */
05437       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05438          /* exit loop if we have it */
05439       if (j & ZT_IOMUX_SIGEVENT) break;
05440    }
05441      /* get the event info */
05442    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05443    return 0;
05444 }
05445 
05446 static void *ss_thread(void *data)
05447 {
05448    struct ast_channel *chan = data;
05449    struct zt_pvt *p = chan->tech_pvt;
05450    char exten[AST_MAX_EXTENSION] = "";
05451    char exten2[AST_MAX_EXTENSION] = "";
05452    unsigned char buf[256];
05453    char dtmfcid[300];
05454    char dtmfbuf[300];
05455    struct callerid_state *cs = NULL;
05456    char *name = NULL, *number = NULL;
05457    int distMatches;
05458    int curRingData[3];
05459    int receivedRingT;
05460    int counter1;
05461    int counter;
05462    int samples = 0;
05463    struct ast_smdi_md_message *smdi_msg = NULL;
05464    int flags;
05465    int i;
05466    int timeout;
05467    int getforward = 0;
05468    char *s1, *s2;
05469    int len = 0;
05470    int res;
05471    int index;
05472 
05473    /* in the bizarre case where the channel has become a zombie before we
05474       even get started here, abort safely
05475    */
05476    if (!p) {
05477       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05478       ast_hangup(chan);
05479       return NULL;
05480    }
05481 
05482    if (option_verbose > 2) 
05483       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05484    index = zt_get_index(chan, p, 1);
05485    if (index < 0) {
05486       ast_log(LOG_WARNING, "Huh?\n");
05487       ast_hangup(chan);
05488       return NULL;
05489    }
05490    if (p->dsp)
05491       ast_dsp_digitreset(p->dsp);
05492    switch (p->sig) {
05493 #ifdef HAVE_PRI
05494    case SIG_PRI:
05495       /* Now loop looking for an extension */
05496       ast_copy_string(exten, p->exten, sizeof(exten));
05497       len = strlen(exten);
05498       res = 0;
05499       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05500          if (len && !ast_ignore_pattern(chan->context, exten))
05501             tone_zone_play_tone(p->subs[index].zfd, -1);
05502          else
05503             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05504          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05505             timeout = matchdigittimeout;
05506          else
05507             timeout = gendigittimeout;
05508          res = ast_waitfordigit(chan, timeout);
05509          if (res < 0) {
05510             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05511             ast_hangup(chan);
05512             return NULL;
05513          } else if (res) {
05514             exten[len++] = res;
05515             exten[len] = '\0';
05516          } else
05517             break;
05518       }
05519       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05520       if (ast_strlen_zero(exten)) {
05521          if (option_verbose > 2)
05522             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05523          exten[0] = 's';
05524          exten[1] = '\0';
05525       }
05526       tone_zone_play_tone(p->subs[index].zfd, -1);
05527       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05528          /* Start the real PBX */
05529          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05530          if (p->dsp) ast_dsp_digitreset(p->dsp);
05531          zt_enable_ec(p);
05532          ast_setstate(chan, AST_STATE_RING);
05533          res = ast_pbx_run(chan);
05534          if (res) {
05535             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05536          }
05537       } else {
05538          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05539          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05540          ast_hangup(chan);
05541          p->exten[0] = '\0';
05542          /* Since we send release complete here, we won't get one */
05543          p->call = NULL;
05544       }
05545       return NULL;
05546       break;
05547 #endif
05548    case SIG_FEATD:
05549    case SIG_FEATDMF:
05550    case SIG_FEATDMF_TA:
05551    case SIG_E911:
05552    case SIG_FGC_CAMAMF:
05553    case SIG_FEATB:
05554    case SIG_EMWINK:
05555    case SIG_SF_FEATD:
05556    case SIG_SF_FEATDMF:
05557    case SIG_SF_FEATB:
05558    case SIG_SFWINK:
05559       if (zt_wink(p, index))  
05560          return NULL;
05561       /* Fall through */
05562    case SIG_EM:
05563    case SIG_EM_E1:
05564    case SIG_SF:
05565    case SIG_FGC_CAMA:
05566       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05567       if (p->dsp)
05568          ast_dsp_digitreset(p->dsp);
05569       /* set digit mode appropriately */
05570       if (p->dsp) {
05571          if (NEED_MFDETECT(p))
05572             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05573          else 
05574             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05575       }
05576       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05577       /* Wait for the first digit only if immediate=no */
05578       if (!p->immediate)
05579          /* Wait for the first digit (up to 5 seconds). */
05580          res = ast_waitfordigit(chan, 5000);
05581       else
05582          res = 0;
05583       if (res > 0) {
05584          /* save first char */
05585          dtmfbuf[0] = res;
05586          switch (p->sig) {
05587          case SIG_FEATD:
05588          case SIG_SF_FEATD:
05589             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05590             if (res > 0)
05591                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05592             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05593             break;
05594          case SIG_FEATDMF_TA:
05595             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05596             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05597             if (zt_wink(p, index)) return NULL;
05598             dtmfbuf[0] = 0;
05599             /* Wait for the first digit (up to 5 seconds). */
05600             res = ast_waitfordigit(chan, 5000);
05601             if (res <= 0) break;
05602             dtmfbuf[0] = res;
05603             /* fall through intentionally */
05604          case SIG_FEATDMF:
05605          case SIG_E911:
05606          case SIG_FGC_CAMAMF:
05607          case SIG_SF_FEATDMF:
05608             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05609             /* if international caca, do it again to get real ANO */
05610             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05611             {
05612                if (zt_wink(p, index)) return NULL;
05613                dtmfbuf[0] = 0;
05614                /* Wait for the first digit (up to 5 seconds). */
05615                res = ast_waitfordigit(chan, 5000);
05616                if (res <= 0) break;
05617                dtmfbuf[0] = res;
05618                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05619             }
05620             if (res > 0) {
05621                /* if E911, take off hook */
05622                if (p->sig == SIG_E911)
05623                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05624                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05625             }
05626             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05627             break;
05628          case SIG_FEATB:
05629          case SIG_SF_FEATB:
05630             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05631             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05632             break;
05633          case SIG_EMWINK:
05634             /* if we received a '*', we are actually receiving Feature Group D
05635                dial syntax, so use that mode; otherwise, fall through to normal
05636                mode
05637             */
05638             if (res == '*') {
05639                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05640                if (res > 0)
05641                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05642                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05643                break;
05644             }
05645          default:
05646             /* If we got the first digit, get the rest */
05647             len = 1;
05648             dtmfbuf[len] = '\0';
05649             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05650                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05651                   timeout = matchdigittimeout;
05652                } else {
05653                   timeout = gendigittimeout;
05654                }
05655                res = ast_waitfordigit(chan, timeout);
05656                if (res < 0) {
05657                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05658                   ast_hangup(chan);
05659                   return NULL;
05660                } else if (res) {
05661                   dtmfbuf[len++] = res;
05662                   dtmfbuf[len] = '\0';
05663                } else {
05664                   break;
05665                }
05666             }
05667             break;
05668          }
05669       }
05670       if (res == -1) {
05671          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05672          ast_hangup(chan);
05673          return NULL;
05674       } else if (res < 0) {
05675          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05676          ast_hangup(chan);
05677          return NULL;
05678       }
05679 
05680       if (p->sig == SIG_FGC_CAMA) {
05681          char anibuf[100];
05682 
05683          if (ast_safe_sleep(chan,1000) == -1) {
05684                            ast_hangup(chan);
05685                            return NULL;
05686          }
05687                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05688                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05689                         res = my_getsigstr(chan, anibuf, "#", 10000);
05690                         if ((res > 0) && (strlen(anibuf) > 2)) {
05691             if (anibuf[strlen(anibuf) - 1] == '#')
05692                anibuf[strlen(anibuf) - 1] = 0;
05693             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05694          }
05695                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05696       }
05697 
05698       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05699       if (ast_strlen_zero(exten))
05700          ast_copy_string(exten, "s", sizeof(exten));
05701       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05702          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05703          if (exten[0] == '*') {
05704             char *stringp=NULL;
05705             ast_copy_string(exten2, exten, sizeof(exten2));
05706             /* Parse out extension and callerid */
05707             stringp=exten2 +1;
05708             s1 = strsep(&stringp, "*");
05709             s2 = strsep(&stringp, "*");
05710             if (s2) {
05711                if (!ast_strlen_zero(p->cid_num))
05712                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05713                else
05714                   ast_set_callerid(chan, s1, NULL, s1);
05715                ast_copy_string(exten, s2, sizeof(exten));
05716             } else
05717                ast_copy_string(exten, s1, sizeof(exten));
05718          } else if (p->sig == SIG_FEATD)
05719             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05720       }
05721       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05722          if (exten[0] == '*') {
05723             char *stringp=NULL;
05724             ast_copy_string(exten2, exten, sizeof(exten2));
05725             /* Parse out extension and callerid */
05726             stringp=exten2 +1;
05727             s1 = strsep(&stringp, "#");
05728             s2 = strsep(&stringp, "#");
05729             if (s2) {
05730                if (!ast_strlen_zero(p->cid_num))
05731                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05732                else
05733                   if (*(s1 + 2))
05734                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05735                ast_copy_string(exten, s2 + 1, sizeof(exten));
05736             } else
05737                ast_copy_string(exten, s1 + 2, sizeof(exten));
05738          } else
05739             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05740       }
05741       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05742          if (exten[0] == '*') {
05743             char *stringp=NULL;
05744             ast_copy_string(exten2, exten, sizeof(exten2));
05745             /* Parse out extension and callerid */
05746             stringp=exten2 +1;
05747             s1 = strsep(&stringp, "#");
05748             s2 = strsep(&stringp, "#");
05749             if (s2 && (*(s2 + 1) == '0')) {
05750                if (*(s2 + 2))
05751                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05752             }
05753             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05754             else ast_copy_string(exten, "911", sizeof(exten));
05755          } else
05756             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05757       }
05758       if (p->sig == SIG_FEATB) {
05759          if (exten[0] == '*') {
05760             char *stringp=NULL;
05761             ast_copy_string(exten2, exten, sizeof(exten2));
05762             /* Parse out extension and callerid */
05763             stringp=exten2 +1;
05764             s1 = strsep(&stringp, "#");
05765             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05766          } else
05767             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05768       }
05769       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05770          zt_wink(p, index);
05771                         /* some switches require a minimum guard time between
05772                            the last FGD wink and something that answers
05773                            immediately. This ensures it */
05774                         if (ast_safe_sleep(chan,100)) return NULL;
05775       }
05776       zt_enable_ec(p);
05777       if (NEED_MFDETECT(p)) {
05778          if (p->dsp) {
05779             if (!p->hardwaredtmf)
05780                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05781             else {
05782                ast_dsp_free(p->dsp);
05783                p->dsp = NULL;
05784             }
05785          }
05786       }
05787 
05788       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05789          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05790          if (p->dsp) ast_dsp_digitreset(p->dsp);
05791          res = ast_pbx_run(chan);
05792          if (res) {
05793             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05794             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05795          }
05796          return NULL;
05797       } else {
05798          if (option_verbose > 2)
05799             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05800          sleep(2);
05801          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05802          if (res < 0)
05803             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05804          else
05805             sleep(1);
05806          res = ast_streamfile(chan, "ss-noservice", chan->language);
05807          if (res >= 0)
05808             ast_waitstream(chan, "");
05809          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05810          ast_hangup(chan);
05811          return NULL;
05812       }
05813       break;
05814    case SIG_FXOLS:
05815    case SIG_FXOGS:
05816    case SIG_FXOKS:
05817       /* Read the first digit */
05818       timeout = firstdigittimeout;
05819       /* If starting a threeway call, never timeout on the first digit so someone
05820          can use flash-hook as a "hold" feature */
05821       if (p->subs[SUB_THREEWAY].owner) 
05822          timeout = 999999;
05823       while (len < AST_MAX_EXTENSION-1) {
05824          /* Read digit unless it's supposed to be immediate, in which case the
05825             only answer is 's' */
05826          if (p->immediate) 
05827             res = 's';
05828          else
05829             res = ast_waitfordigit(chan, timeout);
05830          timeout = 0;
05831          if (res < 0) {
05832             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05833             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05834             ast_hangup(chan);
05835             return NULL;
05836          } else if (res)  {
05837             exten[len++]=res;
05838             exten[len] = '\0';
05839          }
05840          if (!ast_ignore_pattern(chan->context, exten))
05841             tone_zone_play_tone(p->subs[index].zfd, -1);
05842          else
05843             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05844          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05845             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05846                if (getforward) {
05847                   /* Record this as the forwarding extension */
05848                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05849                   if (option_verbose > 2)
05850                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05851                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05852                   if (res)
05853                      break;
05854                   usleep(500000);
05855                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05856                   sleep(1);
05857                   memset(exten, 0, sizeof(exten));
05858                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05859                   len = 0;
05860                   getforward = 0;
05861                } else  {
05862                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05863                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05864                   if (!ast_strlen_zero(p->cid_num)) {
05865                      if (!p->hidecallerid)
05866                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05867                      else
05868                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05869                   }
05870                   if (!ast_strlen_zero(p->cid_name)) {
05871                      if (!p->hidecallerid)
05872                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05873                   }
05874                   ast_setstate(chan, AST_STATE_RING);
05875                   zt_enable_ec(p);
05876                   res = ast_pbx_run(chan);
05877                   if (res) {
05878                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05879                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05880                   }
05881                   return NULL;
05882                }
05883             } else {
05884                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05885                   so just set the timeout to matchdigittimeout and wait some more */
05886                timeout = matchdigittimeout;
05887             }
05888          } else if (res == 0) {
05889             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05890             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05891             zt_wait_event(p->subs[index].zfd);
05892             ast_hangup(chan);
05893             return NULL;
05894          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05895             if (option_verbose > 2) 
05896                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05897             /* Disable call waiting if enabled */
05898             p->callwaiting = 0;
05899             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05900             if (res) {
05901                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05902                   chan->name, strerror(errno));
05903             }
05904             len = 0;
05905             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05906             memset(exten, 0, sizeof(exten));
05907             timeout = firstdigittimeout;
05908                
05909          } else if (!strcmp(exten,ast_pickup_ext())) {
05910             /* Scan all channels and see if there are any
05911              * ringing channels that have call groups
05912              * that equal this channels pickup group  
05913              */
05914             if (index == SUB_REAL) {
05915                /* Switch us from Third call to Call Wait */
05916                if (p->subs[SUB_THREEWAY].owner) {
05917                   /* If you make a threeway call and the *8# a call, it should actually 
05918                      look like a callwait */
05919                   alloc_sub(p, SUB_CALLWAIT);   
05920                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05921                   unalloc_sub(p, SUB_THREEWAY);
05922                }
05923                zt_enable_ec(p);
05924                if (ast_pickup_call(chan)) {
05925                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05926                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05927                   zt_wait_event(p->subs[index].zfd);
05928                }
05929                ast_hangup(chan);
05930                return NULL;
05931             } else {
05932                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05933                ast_hangup(chan);
05934                return NULL;
05935             }
05936             
05937          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05938             if (option_verbose > 2) 
05939                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05940             /* Disable Caller*ID if enabled */
05941             p->hidecallerid = 1;
05942             if (chan->cid.cid_num)
05943                free(chan->cid.cid_num);
05944             chan->cid.cid_num = NULL;
05945             if (chan->cid.cid_name)
05946                free(chan->cid.cid_name);
05947             chan->cid.cid_name = NULL;
05948             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05949             if (res) {
05950                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05951                   chan->name, strerror(errno));
05952             }
05953             len = 0;
05954             memset(exten, 0, sizeof(exten));
05955             timeout = firstdigittimeout;
05956          } else if (p->callreturn && !strcmp(exten, "*69")) {
05957             res = 0;
05958             if (!ast_strlen_zero(p->lastcid_num)) {
05959                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05960             }
05961             if (!res)
05962                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05963             break;
05964          } else if (!strcmp(exten, "*78")) {
05965             /* Do not disturb */
05966             if (option_verbose > 2)
05967                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05968             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05969                      "Channel: Zap/%d\r\n"
05970                      "Status: enabled\r\n", p->channel);
05971             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05972             p->dnd = 1;
05973             getforward = 0;
05974             memset(exten, 0, sizeof(exten));
05975             len = 0;
05976          } else if (!strcmp(exten, "*79")) {
05977             /* Do not disturb */
05978             if (option_verbose > 2)
05979                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05980             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05981                      "Channel: Zap/%d\r\n"
05982                      "Status: disabled\r\n", p->channel);
05983             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05984             p->dnd = 0;
05985             getforward = 0;
05986             memset(exten, 0, sizeof(exten));
05987             len = 0;
05988          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05989             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05990             getforward = 1;
05991             memset(exten, 0, sizeof(exten));
05992             len = 0;
05993          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05994             if (option_verbose > 2)
05995                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05996             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05997             memset(p->call_forward, 0, sizeof(p->call_forward));
05998             getforward = 0;
05999             memset(exten, 0, sizeof(exten));
06000             len = 0;
06001          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
06002                   p->subs[SUB_THREEWAY].owner &&
06003                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
06004             /* This is a three way call, the main call being a real channel, 
06005                and we're parking the first call. */
06006             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
06007             if (option_verbose > 2)
06008                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
06009             break;
06010          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
06011             if (option_verbose > 2)
06012                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
06013             res = ast_db_put("blacklist", p->lastcid_num, "1");
06014             if (!res) {
06015                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06016                memset(exten, 0, sizeof(exten));
06017                len = 0;
06018             }
06019          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
06020             if (option_verbose > 2) 
06021                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
06022             /* Enable Caller*ID if enabled */
06023             p->hidecallerid = 0;
06024             if (chan->cid.cid_num)
06025                free(chan->cid.cid_num);
06026             chan->cid.cid_num = NULL;
06027             if (chan->cid.cid_name)
06028                free(chan->cid.cid_name);
06029             chan->cid.cid_name = NULL;
06030             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
06031             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06032             if (res) {
06033                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06034                   chan->name, strerror(errno));
06035             }
06036             len = 0;
06037             memset(exten, 0, sizeof(exten));
06038             timeout = firstdigittimeout;
06039          } else if (!strcmp(exten, "*0")) {
06040             struct ast_channel *nbridge = 
06041                p->subs[SUB_THREEWAY].owner;
06042             struct zt_pvt *pbridge = NULL;
06043               /* set up the private struct of the bridged one, if any */
06044             if (nbridge && ast_bridged_channel(nbridge)) 
06045                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06046             if (nbridge && pbridge && 
06047                 (nbridge->tech == &zap_tech) && 
06048                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06049                 ISTRUNK(pbridge)) {
06050                int func = ZT_FLASH;
06051                /* Clear out the dial buffer */
06052                p->dop.dialstr[0] = '\0';
06053                /* flash hookswitch */
06054                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06055                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06056                      nbridge->name, strerror(errno));
06057                }
06058                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06059                unalloc_sub(p, SUB_THREEWAY);
06060                p->owner = p->subs[SUB_REAL].owner;
06061                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06062                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06063                ast_hangup(chan);
06064                return NULL;
06065             } else {
06066                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06067                zt_wait_event(p->subs[index].zfd);
06068                tone_zone_play_tone(p->subs[index].zfd, -1);
06069                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06070                unalloc_sub(p, SUB_THREEWAY);
06071                p->owner = p->subs[SUB_REAL].owner;
06072                ast_hangup(chan);
06073                return NULL;
06074             }              
06075          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06076                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06077             if (option_debug)
06078                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);
06079             break;
06080          }
06081          if (!timeout)
06082             timeout = gendigittimeout;
06083          if (len && !ast_ignore_pattern(chan->context, exten))
06084             tone_zone_play_tone(p->subs[index].zfd, -1);
06085       }
06086       break;
06087    case SIG_FXSLS:
06088    case SIG_FXSGS:
06089    case SIG_FXSKS:
06090 #ifdef HAVE_PRI
06091       if (p->pri) {
06092          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06093          struct ast_frame *f;
06094          int res;
06095          time_t start;
06096 
06097          time(&start);
06098          ast_setstate(chan, AST_STATE_RING);
06099          while (time(NULL) < start + 3) {
06100             res = ast_waitfor(chan, 1000);
06101             if (res) {
06102                f = ast_read(chan);
06103                if (!f) {
06104                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06105                   ast_hangup(chan);
06106                   return NULL;
06107                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06108                   res = 1;
06109                } else
06110                   res = 0;
06111                ast_frfree(f);
06112                if (res) {
06113                   ast_log(LOG_DEBUG, "Got ring!\n");
06114                   res = 0;
06115                   break;
06116                }
06117             }
06118          }
06119       }
06120 #endif
06121       /* check for SMDI messages */
06122       if (p->use_smdi && p->smdi_iface) {
06123          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06124 
06125          if (smdi_msg != NULL) {
06126             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06127 
06128             if (smdi_msg->type == 'B')
06129                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06130             else if (smdi_msg->type == 'N')
06131                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06132 
06133             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06134          } else {
06135             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06136          }
06137       }
06138 
06139       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06140             number = smdi_msg->calling_st;
06141 
06142       /* If we want caller id, we're in a prering state due to a polarity reversal
06143        * and we're set to use a polarity reversal to trigger the start of caller id,
06144        * grab the caller id and wait for ringing to start... */
06145       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06146          /* If set to use DTMF CID signalling, listen for DTMF */
06147          if (p->cid_signalling == CID_SIG_DTMF) {
06148             int i = 0;
06149             cs = NULL;
06150             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06151                "channel %s\n", chan->name);
06152             zt_setlinear(p->subs[index].zfd, 0);
06153             res = 2000;
06154             for (;;) {
06155                struct ast_frame *f;
06156                res = ast_waitfor(chan, res);
06157                if (res <= 0) {
06158                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06159                      "Exiting simple switch\n");
06160                   ast_hangup(chan);
06161                   return NULL;
06162                } 
06163                f = ast_read(chan);
06164                if (!f)
06165                   break;
06166                if (f->frametype == AST_FRAME_DTMF) {
06167                   dtmfbuf[i++] = f->subclass;
06168                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06169                   res = 2000;
06170                }
06171                ast_frfree(f);
06172                if (chan->_state == AST_STATE_RING ||
06173                    chan->_state == AST_STATE_RINGING) 
06174                   break; /* Got ring */
06175             }
06176             dtmfbuf[i] = '\0';
06177             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06178             /* Got cid and ring. */
06179             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06180             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06181             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06182                dtmfcid, flags);
06183             /* If first byte is NULL, we have no cid */
06184             if (!ast_strlen_zero(dtmfcid)) 
06185                number = dtmfcid;
06186             else
06187                number = NULL;
06188          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06189          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06190             cs = callerid_new(p->cid_signalling);
06191             if (cs) {
06192                samples = 0;
06193 #if 1
06194                bump_gains(p);
06195 #endif            
06196                /* Take out of linear mode for Caller*ID processing */
06197                zt_setlinear(p->subs[index].zfd, 0);
06198                
06199                /* First we wait and listen for the Caller*ID */
06200                for (;;) {  
06201                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06202                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06203                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06204                      callerid_free(cs);
06205                      ast_hangup(chan);
06206                      return NULL;
06207                   }
06208                   if (i & ZT_IOMUX_SIGEVENT) {
06209                      res = zt_get_event(p->subs[index].zfd);
06210                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06211 
06212                      if (p->cid_signalling == CID_SIG_V23_JP) {
06213 #ifdef ZT_EVENT_RINGBEGIN
06214                         if (res == ZT_EVENT_RINGBEGIN) {
06215                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06216                            usleep(1);
06217                         }
06218 #endif
06219                      } else {
06220                         res = 0;
06221                         break;
06222                      }
06223                   } else if (i & ZT_IOMUX_READ) {
06224                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06225                      if (res < 0) {
06226                         if (errno != ELAST) {
06227                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06228                            callerid_free(cs);
06229                            ast_hangup(chan);
06230                            return NULL;
06231                         }
06232                         break;
06233                      }
06234                      samples += res;
06235 
06236                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06237                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06238                      } else {
06239                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06240                      }
06241 
06242                      if (res < 0) {
06243                         ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
06244                         break;
06245                      } else if (res)
06246                         break;
06247                      else if (samples > (8000 * 10))
06248                         break;
06249                   }
06250                }
06251                if (res == 1) {
06252                   callerid_get(cs, &name, &number, &flags);
06253                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06254                }
06255 
06256                if (p->cid_signalling == CID_SIG_V23_JP) {
06257                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06258                   usleep(1);
06259                   res = 4000;
06260                } else {
06261 
06262                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06263                   res = 2000;
06264                }
06265 
06266                for (;;) {
06267                   struct ast_frame *f;
06268                   res = ast_waitfor(chan, res);
06269                   if (res <= 0) {
06270                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06271                         "Exiting simple switch\n");
06272                      ast_hangup(chan);
06273                      return NULL;
06274                   } 
06275                   f = ast_read(chan);
06276                   ast_frfree(f);
06277                   if (chan->_state == AST_STATE_RING ||
06278                       chan->_state == AST_STATE_RINGING) 
06279                      break; /* Got ring */
06280                }
06281    
06282                /* We must have a ring by now, so, if configured, lets try to listen for
06283                 * distinctive ringing */ 
06284                if (p->usedistinctiveringdetection == 1) {
06285                   len = 0;
06286                   distMatches = 0;
06287                   /* Clear the current ring data array so we dont have old data in it. */
06288                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06289                      curRingData[receivedRingT] = 0;
06290                   receivedRingT = 0;
06291                   counter = 0;
06292                   counter1 = 0;
06293                   /* Check to see if context is what it should be, if not set to be. */
06294                   if (strcmp(p->context,p->defcontext) != 0) {
06295                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06296                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06297                   }
06298       
06299                   for (;;) {  
06300                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06301                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06302                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06303                         callerid_free(cs);
06304                         ast_hangup(chan);
06305                         return NULL;
06306                      }
06307                      if (i & ZT_IOMUX_SIGEVENT) {
06308                         res = zt_get_event(p->subs[index].zfd);
06309                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06310                         res = 0;
06311                         /* Let us detect distinctive ring */
06312       
06313                         curRingData[receivedRingT] = p->ringt;
06314       
06315                         if (p->ringt < p->ringt_base/2)
06316                            break;
06317                         /* Increment the ringT counter so we can match it against
06318                            values in zapata.conf for distinctive ring */
06319                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06320                            break;
06321                      } else if (i & ZT_IOMUX_READ) {
06322                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06323                         if (res < 0) {
06324                            if (errno != ELAST) {
06325                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06326                               callerid_free(cs);
06327                               ast_hangup(chan);
06328                               return NULL;
06329                            }
06330                            break;
06331                         }
06332                         if (p->ringt) 
06333                            p->ringt--;
06334                         if (p->ringt == 1) {
06335                            res = -1;
06336                            break;
06337                         }
06338                      }
06339                   }
06340                   if (option_verbose > 2)
06341                      /* this only shows up if you have n of the dring patterns filled in */
06342                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06343    
06344                   for (counter = 0; counter < 3; counter++) {
06345                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06346                      channel */
06347                      distMatches = 0;
06348                      for (counter1 = 0; counter1 < 3; counter1++) {
06349                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06350                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06351                            distMatches++;
06352                         }
06353                      }
06354                      if (distMatches == 3) {
06355                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06356                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06357                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06358                         if (option_verbose > 2)
06359                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06360                         break;
06361                      }
06362                   }
06363                }
06364                /* Restore linear mode (if appropriate) for Caller*ID processing */
06365                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06366 #if 1
06367                restore_gains(p);
06368 #endif            
06369             } else
06370                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06371          } else {
06372             ast_log(LOG_WARNING, "Channel %s in prering "
06373                "state, but I have nothing to do. "
06374                "Terminating simple switch, should be "
06375                "restarted by the actual ring.\n", 
06376                chan->name);
06377             ast_hangup(chan);
06378             return NULL;
06379          }
06380       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06381          /* FSK Bell202 callerID */
06382          cs = callerid_new(p->cid_signalling);
06383          if (cs) {
06384 #if 1
06385             bump_gains(p);
06386 #endif            
06387             samples = 0;
06388             len = 0;
06389             distMatches = 0;
06390             /* Clear the current ring data array so we dont have old data in it. */
06391             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06392                curRingData[receivedRingT] = 0;
06393             receivedRingT = 0;
06394             counter = 0;
06395             counter1 = 0;
06396             /* Check to see if context is what it should be, if not set to be. */
06397             if (strcmp(p->context,p->defcontext) != 0) {
06398                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06399                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06400             }
06401 
06402             /* Take out of linear mode for Caller*ID processing */
06403             zt_setlinear(p->subs[index].zfd, 0);
06404             for (;;) {  
06405                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06406                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06407                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06408                   callerid_free(cs);
06409                   ast_hangup(chan);
06410                   return NULL;
06411                }
06412                if (i & ZT_IOMUX_SIGEVENT) {
06413                   res = zt_get_event(p->subs[index].zfd);
06414                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06415                   /* If we get a PR event, they hung up while processing calerid */
06416                   if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
06417                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
06418                      p->polarity = POLARITY_IDLE;
06419                      callerid_free(cs);
06420                      ast_hangup(chan);
06421                      return NULL;
06422                   }
06423                   res = 0;
06424                   /* Let us detect callerid when the telco uses distinctive ring */
06425 
06426                   curRingData[receivedRingT] = p->ringt;
06427 
06428                   if (p->ringt < p->ringt_base/2)
06429                      break;
06430                   /* Increment the ringT counter so we can match it against
06431                      values in zapata.conf for distinctive ring */
06432                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06433                      break;
06434                } else if (i & ZT_IOMUX_READ) {
06435                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06436                   if (res < 0) {
06437                      if (errno != ELAST) {
06438                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06439                         callerid_free(cs);
06440                         ast_hangup(chan);
06441                         return NULL;
06442                      }
06443                      break;
06444                   }
06445                   if (p->ringt) 
06446                      p->ringt--;
06447                   if (p->ringt == 1) {
06448                      res = -1;
06449                      break;
06450                   }
06451                   samples += res;
06452                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06453                   if (res < 0) {
06454                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06455                      break;
06456                   } else if (res)
06457                      break;
06458                   else if (samples > (8000 * 10))
06459                      break;
06460                }
06461             }
06462             if (res == 1) {
06463                callerid_get(cs, &name, &number, &flags);
06464                if (option_debug)
06465                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06466             }
06467             if (distinctiveringaftercid == 1) {
06468                /* Clear the current ring data array so we dont have old data in it. */
06469                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06470                   curRingData[receivedRingT] = 0;
06471                }
06472                receivedRingT = 0;
06473                if (option_verbose > 2)
06474                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06475                for (;;) {
06476                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06477                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06478                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06479                      callerid_free(cs);
06480                      ast_hangup(chan);
06481                      return NULL;
06482                   }
06483                   if (i & ZT_IOMUX_SIGEVENT) {
06484                      res = zt_get_event(p->subs[index].zfd);
06485                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06486                      res = 0;
06487                      /* Let us detect callerid when the telco uses distinctive ring */
06488 
06489                      curRingData[receivedRingT] = p->ringt;
06490 
06491                      if (p->ringt < p->ringt_base/2)
06492                         break;
06493                      /* Increment the ringT counter so we can match it against
06494                         values in zapata.conf for distinctive ring */
06495                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06496                         break;
06497                   } else if (i & ZT_IOMUX_READ) {
06498                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06499                      if (res < 0) {
06500                         if (errno != ELAST) {
06501                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06502                            callerid_free(cs);
06503                            ast_hangup(chan);
06504                            return NULL;
06505                         }
06506                         break;
06507                      }
06508                   if (p->ringt)
06509                      p->ringt--;
06510                      if (p->ringt == 1) {
06511                         res = -1;
06512                         break;
06513                      }
06514                   }
06515                }
06516             }
06517             if (p->usedistinctiveringdetection == 1) {
06518                if (option_verbose > 2)
06519                   /* this only shows up if you have n of the dring patterns filled in */
06520                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06521 
06522                for (counter = 0; counter < 3; counter++) {
06523                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06524                   channel */
06525                   if (option_verbose > 2)
06526                      /* this only shows up if you have n of the dring patterns filled in */
06527                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06528                         p->drings.ringnum[counter].ring[0],
06529                         p->drings.ringnum[counter].ring[1],
06530                         p->drings.ringnum[counter].ring[2]);
06531                   distMatches = 0;
06532                   for (counter1 = 0; counter1 < 3; counter1++) {
06533                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06534                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06535                         distMatches++;
06536                      }
06537                   }
06538                   if (distMatches == 3) {
06539                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06540                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06541                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06542                      if (option_verbose > 2)
06543                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06544                      break;
06545                   }
06546                }
06547             }
06548             /* Restore linear mode (if appropriate) for Caller*ID processing */
06549             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06550 #if 1
06551             restore_gains(p);
06552 #endif            
06553             if (res < 0) {
06554                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06555             }
06556          } else
06557             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06558       }
06559       else
06560          cs = NULL;
06561 
06562       if (number)
06563          ast_shrink_phone_number(number);
06564       ast_set_callerid(chan, number, name, number);
06565 
06566       if (smdi_msg)
06567          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06568 
06569       if (cs)
06570          callerid_free(cs);
06571 
06572       ast_setstate(chan, AST_STATE_RING);
06573       chan->rings = 1;
06574       p->ringt = p->ringt_base;
06575       res = ast_pbx_run(chan);
06576       if (res) {
06577          ast_hangup(chan);
06578          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06579       }
06580       return NULL;
06581    default:
06582       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06583       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06584       if (res < 0)
06585             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06586    }
06587    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06588    if (res < 0)
06589          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06590    ast_hangup(chan);
06591    return NULL;
06592 }
06593 
06594 /* destroy a zaptel channel, identified by its number */
06595 static int zap_destroy_channel_bynum(int channel)
06596 {
06597    struct zt_pvt *tmp = NULL;
06598    struct zt_pvt *prev = NULL;
06599 
06600    tmp = iflist;
06601    while (tmp) {
06602       if (tmp->channel == channel) {
06603          destroy_channel(prev, tmp, 1);
06604          return RESULT_SUCCESS;
06605       }
06606       prev = tmp;
06607       tmp = tmp->next;
06608    }
06609    return RESULT_FAILURE;
06610 }
06611 
06612 static int handle_init_event(struct zt_pvt *i, int event)
06613 {
06614    int res;
06615    pthread_t threadid;
06616    pthread_attr_t attr;
06617    struct ast_channel *chan;
06618    pthread_attr_init(&attr);
06619    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06620    /* Handle an event on a given channel for the monitor thread. */
06621    switch (event) {
06622    case ZT_EVENT_NONE:
06623    case ZT_EVENT_BITSCHANGED:
06624       break;
06625    case ZT_EVENT_WINKFLASH:
06626    case ZT_EVENT_RINGOFFHOOK:
06627       if (i->inalarm) break;
06628       if (i->radio) break;
06629       /* Got a ring/answer.  What kind of channel are we? */
06630       switch (i->sig) {
06631       case SIG_FXOLS:
06632       case SIG_FXOGS:
06633       case SIG_FXOKS:
06634          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06635          if (res && (errno == EBUSY))
06636             break;
06637          if (i->cidspill) {
06638             /* Cancel VMWI spill */
06639             free(i->cidspill);
06640             i->cidspill = NULL;
06641          }
06642          if (i->immediate) {
06643             zt_enable_ec(i);
06644             /* The channel is immediately up.  Start right away */
06645             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06646             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06647             if (!chan) {
06648                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06649                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06650                if (res < 0)
06651                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06652             }
06653          } else {
06654             /* Check for callerid, digits, etc */
06655             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06656             if (chan) {
06657                if (has_voicemail(i))
06658                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06659                else
06660                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06661                if (res < 0) 
06662                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06663                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06664                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06665                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06666                   if (res < 0)
06667                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06668                   ast_hangup(chan);
06669                }
06670             } else
06671                ast_log(LOG_WARNING, "Unable to create channel\n");
06672          }
06673          break;
06674       case SIG_FXSLS:
06675       case SIG_FXSGS:
06676       case SIG_FXSKS:
06677             i->ringt = i->ringt_base;
06678             /* Fall through */
06679       case SIG_EMWINK:
06680       case SIG_FEATD:
06681       case SIG_FEATDMF:
06682       case SIG_FEATDMF_TA:
06683       case SIG_E911:
06684       case SIG_FGC_CAMA:
06685       case SIG_FGC_CAMAMF:
06686       case SIG_FEATB:
06687       case SIG_EM:
06688       case SIG_EM_E1:
06689       case SIG_SFWINK:
06690       case SIG_SF_FEATD:
06691       case SIG_SF_FEATDMF:
06692       case SIG_SF_FEATB:
06693       case SIG_SF:
06694             /* Check for callerid, digits, etc */
06695             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06696             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06697                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06698                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06699                if (res < 0)
06700                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06701                ast_hangup(chan);
06702             } else if (!chan) {
06703                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06704             }
06705             break;
06706       default:
06707          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06708          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06709          if (res < 0)
06710                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06711          return -1;
06712       }
06713       break;
06714    case ZT_EVENT_NOALARM:
06715       i->inalarm = 0;
06716       if (!i->unknown_alarm) {
06717          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06718          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06719             "Channel: %d\r\n", i->channel);
06720       } else {
06721          i->unknown_alarm = 0;
06722       }
06723       break;
06724    case ZT_EVENT_ALARM:
06725       i->inalarm = 1;
06726       res = get_alarms(i);
06727       do {
06728          const char *alarm_str = alarm2str(res);
06729 
06730          /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
06731           * doesn't know what to do with it.  Don't confuse users with log messages. */
06732          if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
06733             i->unknown_alarm = 1;
06734             break;
06735          } else {
06736             i->unknown_alarm = 0;
06737          }
06738 
06739          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str);
06740          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06741             "Alarm: %s\r\n"
06742             "Channel: %d\r\n",
06743             alarm_str, i->channel);
06744       } while (0);
06745       /* fall thru intentionally */
06746    case ZT_EVENT_ONHOOK:
06747       if (i->radio)
06748          break;
06749       /* Back on hook.  Hang up. */
06750       switch (i->sig) {
06751       case SIG_FXOLS:
06752       case SIG_FXOGS:
06753       case SIG_FEATD:
06754       case SIG_FEATDMF:
06755       case SIG_FEATDMF_TA:
06756       case SIG_E911:
06757       case SIG_FGC_CAMA:
06758       case SIG_FGC_CAMAMF:
06759       case SIG_FEATB:
06760       case SIG_EM:
06761       case SIG_EM_E1:
06762       case SIG_EMWINK:
06763       case SIG_SF_FEATD:
06764       case SIG_SF_FEATDMF:
06765       case SIG_SF_FEATB:
06766       case SIG_SF:
06767       case SIG_SFWINK:
06768       case SIG_FXSLS:
06769       case SIG_FXSGS:
06770       case SIG_FXSKS:
06771       case SIG_GR303FXSKS:
06772          zt_disable_ec(i);
06773          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06774          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06775          break;
06776       case SIG_GR303FXOKS:
06777       case SIG_FXOKS:
06778          zt_disable_ec(i);
06779          /* Diddle the battery for the zhone */
06780 #ifdef ZHONE_HACK
06781          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06782          usleep(1);
06783 #endif         
06784          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06785          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06786          break;
06787       case SIG_PRI:
06788          zt_disable_ec(i);
06789          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06790          break;
06791       default:
06792          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06793          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06794          return -1;
06795       }
06796       break;
06797    case ZT_EVENT_POLARITY:
06798       switch (i->sig) {
06799       case SIG_FXSLS:
06800       case SIG_FXSKS:
06801       case SIG_FXSGS:
06802          /* We have already got a PR before the channel was 
06803             created, but it wasn't handled. We need polarity 
06804             to be REV for remote hangup detection to work. 
06805             At least in Spain */
06806          if (i->hanguponpolarityswitch)
06807             i->polarity = POLARITY_REV;
06808 
06809          if (i->cid_start == CID_START_POLARITY) {
06810             i->polarity = POLARITY_REV;
06811             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06812                    "CID detection on channel %d\n",
06813                    i->channel);
06814             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06815             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06816                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06817             }
06818          }
06819          break;
06820       default:
06821          ast_log(LOG_WARNING, "handle_init_event detected "
06822             "polarity reversal on non-FXO (SIG_FXS) "
06823             "interface %d\n", i->channel);
06824       }
06825       break;
06826    case ZT_EVENT_REMOVED: /* destroy channel */
06827       ast_log(LOG_NOTICE, 
06828             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
06829             i->channel);
06830       zap_destroy_channel_bynum(i->channel);
06831       break;
06832    }
06833    pthread_attr_destroy(&attr);
06834    return 0;
06835 }
06836 
06837 static void *do_monitor(void *data)
06838 {
06839    int count, res, res2, spoint, pollres=0;
06840    struct zt_pvt *i;
06841    struct zt_pvt *last = NULL;
06842    time_t thispass = 0, lastpass = 0;
06843    int found;
06844    char buf[1024];
06845    struct pollfd *pfds=NULL;
06846    int lastalloc = -1;
06847    /* This thread monitors all the frame relay interfaces which are not yet in use
06848       (and thus do not have a separate thread) indefinitely */
06849    /* From here on out, we die whenever asked */
06850 #if 0
06851    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06852       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06853       return NULL;
06854    }
06855    ast_log(LOG_DEBUG, "Monitor starting...\n");
06856 #endif
06857    for (;;) {
06858       /* Lock the interface list */
06859       ast_mutex_lock(&iflock);
06860       if (!pfds || (lastalloc != ifcount)) {
06861          if (pfds) {
06862             free(pfds);
06863             pfds = NULL;
06864          }
06865          if (ifcount) {
06866             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
06867                ast_mutex_unlock(&iflock);
06868                return NULL;
06869             }
06870          }
06871          lastalloc = ifcount;
06872       }
06873       /* Build the stuff we're going to poll on, that is the socket of every
06874          zt_pvt that does not have an associated owner channel */
06875       count = 0;
06876       i = iflist;
06877       while (i) {
06878          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06879             if (!i->owner && !i->subs[SUB_REAL].owner) {
06880                /* This needs to be watched, as it lacks an owner */
06881                pfds[count].fd = i->subs[SUB_REAL].zfd;
06882                pfds[count].events = POLLPRI;
06883                pfds[count].revents = 0;
06884                /* Message waiting or r2 channels also get watched for reading */
06885                if (i->cidspill)
06886                   pfds[count].events |= POLLIN;
06887                count++;
06888             }
06889          }
06890          i = i->next;
06891       }
06892       /* Okay, now that we know what to do, release the interface lock */
06893       ast_mutex_unlock(&iflock);
06894       
06895       pthread_testcancel();
06896       /* Wait at least a second for something to happen */
06897       res = poll(pfds, count, 1000);
06898       pthread_testcancel();
06899       /* Okay, poll has finished.  Let's see what happened.  */
06900       if (res < 0) {
06901          if ((errno != EAGAIN) && (errno != EINTR))
06902             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06903          continue;
06904       }
06905       /* Alright, lock the interface list again, and let's look and see what has
06906          happened */
06907       ast_mutex_lock(&iflock);
06908       found = 0;
06909       spoint = 0;
06910       lastpass = thispass;
06911       thispass = time(NULL);
06912       i = iflist;
06913       while (i) {
06914          if (thispass != lastpass) {
06915             if (!found && ((i == last) || ((i == iflist) && !last))) {
06916                last = i;
06917                if (last) {
06918                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06919                      (last->sig & __ZT_SIG_FXO)) {
06920                      res = ast_app_has_voicemail(last->mailbox, NULL);
06921                      if (last->msgstate != res) {
06922                         int x;
06923                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06924                         x = ZT_FLUSH_BOTH;
06925                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06926                         if (res2)
06927                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06928                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
06929                            /* Turn on on hook transfer for 4 seconds */
06930                            x = 4000;
06931                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06932                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06933                            last->cidpos = 0;
06934                            last->msgstate = res;
06935                            last->onhooktime = thispass;
06936                         }
06937                         found ++;
06938                      }
06939                   }
06940                   last = last->next;
06941                }
06942             }
06943          }
06944          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06945             if (i->radio && !i->owner)
06946             {
06947                res = zt_get_event(i->subs[SUB_REAL].zfd);
06948                if (res)
06949                {
06950                   if (option_debug)
06951                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06952                   /* Don't hold iflock while handling init events */
06953                   ast_mutex_unlock(&iflock);
06954                   handle_init_event(i, res);
06955                   ast_mutex_lock(&iflock);   
06956                }
06957                i = i->next;
06958                continue;
06959             }              
06960             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06961             if (pollres & POLLIN) {
06962                if (i->owner || i->subs[SUB_REAL].owner) {
06963 #ifdef HAVE_PRI
06964                   if (!i->pri)
06965 #endif                  
06966                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06967                   i = i->next;
06968                   continue;
06969                }
06970                if (!i->cidspill) {
06971                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06972                   i = i->next;
06973                   continue;
06974                }
06975                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06976                if (res > 0) {
06977                   /* We read some number of bytes.  Write an equal amount of data */
06978                   if (res > i->cidlen - i->cidpos) 
06979                      res = i->cidlen - i->cidpos;
06980                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06981                   if (res2 > 0) {
06982                      i->cidpos += res2;
06983                      if (i->cidpos >= i->cidlen) {
06984                         free(i->cidspill);
06985                         i->cidspill = 0;
06986                         i->cidpos = 0;
06987                         i->cidlen = 0;
06988                      }
06989                   } else {
06990                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06991                      i->msgstate = -1;
06992                   }
06993                } else {
06994                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06995                }
06996             }
06997             if (pollres & POLLPRI) {
06998                if (i->owner || i->subs[SUB_REAL].owner) {
06999 #ifdef HAVE_PRI
07000                   if (!i->pri)
07001 #endif                  
07002                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
07003                   i = i->next;
07004                   continue;
07005                }
07006                res = zt_get_event(i->subs[SUB_REAL].zfd);
07007                if (option_debug)
07008                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07009                /* Don't hold iflock while handling init events */
07010                ast_mutex_unlock(&iflock);
07011                handle_init_event(i, res);
07012                ast_mutex_lock(&iflock);   
07013             }
07014          }
07015          i=i->next;
07016       }
07017       ast_mutex_unlock(&iflock);
07018    }
07019    /* Never reached */
07020    return NULL;
07021    
07022 }
07023 
07024 static int restart_monitor(void)
07025 {
07026    pthread_attr_t attr;
07027    pthread_attr_init(&attr);
07028    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07029    /* If we're supposed to be stopped -- stay stopped */
07030    if (monitor_thread == AST_PTHREADT_STOP)
07031       return 0;
07032    ast_mutex_lock(&monlock);
07033    if (monitor_thread == pthread_self()) {
07034       ast_mutex_unlock(&monlock);
07035       ast_log(LOG_WARNING, "Cannot kill myself\n");
07036       return -1;
07037    }
07038    if (monitor_thread != AST_PTHREADT_NULL) {
07039       /* Wake up the thread */
07040       pthread_kill(monitor_thread, SIGURG);
07041    } else {
07042       /* Start a new monitor */
07043       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
07044          ast_mutex_unlock(&monlock);
07045          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
07046          pthread_attr_destroy(&attr);
07047          return -1;
07048       }
07049    }
07050    ast_mutex_unlock(&monlock);
07051    pthread_attr_destroy(&attr);
07052    return 0;
07053 }
07054 
07055 #ifdef HAVE_PRI
07056 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
07057 {
07058    int x;
07059    int trunkgroup;
07060    /* Get appropriate trunk group if there is one */
07061    trunkgroup = pris[*span].mastertrunkgroup;
07062    if (trunkgroup) {
07063       /* Select a specific trunk group */
07064       for (x = 0; x < NUM_SPANS; x++) {
07065          if (pris[x].trunkgroup == trunkgroup) {
07066             *span = x;
07067             return 0;
07068          }
07069       }
07070       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
07071       *span = -1;
07072    } else {
07073       if (pris[*span].trunkgroup) {
07074          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07075          *span = -1;
07076       } else if (pris[*span].mastertrunkgroup) {
07077          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07078          *span = -1;
07079       } else {
07080          if (si->totalchans == 31) { /* if it's an E1 */
07081             pris[*span].dchannels[0] = 16 + offset;
07082          } else {
07083             pris[*span].dchannels[0] = 24 + offset;
07084          }
07085          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07086          pris[*span].offset = offset;
07087          pris[*span].span = *span + 1;
07088       }
07089    }
07090    return 0;
07091 }
07092 
07093 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07094 {
07095    struct zt_spaninfo si;
07096    ZT_PARAMS p;
07097    int fd;
07098    int span;
07099    int ospan=0;
07100    int x,y;
07101    for (x = 0; x < NUM_SPANS; x++) {
07102       if (pris[x].trunkgroup == trunkgroup) {
07103          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07104          return -1;
07105       }
07106    }
07107    for (y = 0; y < NUM_DCHANS; y++) {
07108       if (!channels[y]) 
07109          break;
07110       memset(&si, 0, sizeof(si));
07111       memset(&p, 0, sizeof(p));
07112       fd = open("/dev/zap/channel", O_RDWR);
07113       if (fd < 0) {
07114          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07115          return -1;
07116       }
07117       x = channels[y];
07118       if (ioctl(fd, ZT_SPECIFY, &x)) {
07119          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07120          zt_close(fd);
07121          return -1;
07122       }
07123       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07124          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07125          return -1;
07126       }
07127       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07128          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07129          zt_close(fd);
07130          return -1;
07131       }
07132       span = p.spanno - 1;
07133       if (pris[span].trunkgroup) {
07134          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07135          zt_close(fd);
07136          return -1;
07137       }
07138       if (pris[span].pvts[0]) {
07139          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07140          zt_close(fd);
07141          return -1;
07142       }
07143       if (!y) {
07144          pris[span].trunkgroup = trunkgroup;
07145          pris[span].offset = channels[y] - p.chanpos;
07146          ospan = span;
07147       }
07148       pris[ospan].dchannels[y] = channels[y];
07149       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07150       pris[span].span = span + 1;
07151       zt_close(fd);
07152    }
07153    return 0;   
07154 }
07155 
07156 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07157 {
07158    if (pris[span].mastertrunkgroup) {
07159       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);
07160       return -1;
07161    }
07162    pris[span].mastertrunkgroup = trunkgroup;
07163    pris[span].prilogicalspan = logicalspan;
07164    return 0;
07165 }
07166 
07167 #endif
07168 
07169 static struct zt_pvt *mkintf(int channel, const struct zt_chan_conf *conf, struct zt_pri *pri, int reloading)
07170 {
07171    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07172    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07173    char fn[80];
07174 #if 1
07175    struct zt_bufferinfo bi;
07176 #endif
07177    struct zt_spaninfo si;
07178    int res;
07179    int span=0;
07180    int here = 0;
07181    int x;
07182    struct zt_pvt **wlist;
07183    struct zt_pvt **wend;
07184    ZT_PARAMS p;
07185 
07186    wlist = &iflist;
07187    wend = &ifend;
07188 
07189 #ifdef HAVE_PRI
07190    if (pri) {
07191       wlist = &pri->crvs;
07192       wend = &pri->crvend;
07193    }
07194 #endif
07195 
07196    tmp2 = *wlist;
07197    prev = NULL;
07198 
07199    while (tmp2) {
07200       if (!tmp2->destroy) {
07201          if (tmp2->channel == channel) {
07202             tmp = tmp2;
07203             here = 1;
07204             break;
07205          }
07206          if (tmp2->channel > channel) {
07207             break;
07208          }
07209       }
07210       prev = tmp2;
07211       tmp2 = tmp2->next;
07212    }
07213 
07214    if (!here && !reloading) {
07215       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07216          destroy_zt_pvt(&tmp);
07217          return NULL;
07218       }
07219       ast_mutex_init(&tmp->lock);
07220       ifcount++;
07221       for (x = 0; x < 3; x++)
07222          tmp->subs[x].zfd = -1;
07223       tmp->channel = channel;
07224    }
07225 
07226    if (tmp) {
07227       int chan_sig = conf->chan.sig;
07228       if (!here) {
07229          if ((channel != CHAN_PSEUDO) && !pri) {
07230             snprintf(fn, sizeof(fn), "%d", channel);
07231             /* Open non-blocking */
07232             if (!here)
07233                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07234             /* Allocate a zapata structure */
07235             if (tmp->subs[SUB_REAL].zfd < 0) {
07236                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);
07237                destroy_zt_pvt(&tmp);
07238                return NULL;
07239             }
07240             memset(&p, 0, sizeof(p));
07241             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07242             if (res < 0) {
07243                ast_log(LOG_ERROR, "Unable to get parameters\n");
07244                destroy_zt_pvt(&tmp);
07245                return NULL;
07246             }
07247             if (p.sigtype != (conf->chan.sig & 0x3ffff)) {
07248                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));
07249                destroy_zt_pvt(&tmp);
07250                return NULL;
07251             }
07252             tmp->law = p.curlaw;
07253             tmp->span = p.spanno;
07254             span = p.spanno - 1;
07255          } else {
07256             if (channel == CHAN_PSEUDO)
07257                chan_sig = 0;
07258             else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) {
07259                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07260                return NULL;
07261             }
07262          }
07263 #ifdef HAVE_PRI
07264          if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) {
07265             int offset;
07266             int myswitchtype;
07267             int matchesdchan;
07268             int x,y;
07269             offset = 0;
07270             if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07271                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07272                destroy_zt_pvt(&tmp);
07273                return NULL;
07274             }
07275             if (span >= NUM_SPANS) {
07276                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07277                destroy_zt_pvt(&tmp);
07278                return NULL;
07279             } else {
07280                si.spanno = 0;
07281                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07282                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07283                   destroy_zt_pvt(&tmp);
07284                   return NULL;
07285                }
07286                /* Store the logical span first based upon the real span */
07287                tmp->logicalspan = pris[span].prilogicalspan;
07288                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07289                if (span < 0) {
07290                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07291                   destroy_zt_pvt(&tmp);
07292                   return NULL;
07293                }
07294                if (chan_sig == SIG_PRI)
07295                   myswitchtype = conf->pri.switchtype;
07296                else
07297                   myswitchtype = PRI_SWITCH_GR303_TMC;
07298                /* Make sure this isn't a d-channel */
07299                matchesdchan=0;
07300                for (x = 0; x < NUM_SPANS; x++) {
07301                   for (y = 0; y < NUM_DCHANS; y++) {
07302                      if (pris[x].dchannels[y] == tmp->channel) {
07303                         matchesdchan = 1;
07304                         break;
07305                      }
07306                   }
07307                }
07308                offset = p.chanpos;
07309                if (!matchesdchan) {
07310                   if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) {
07311                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07312                      destroy_zt_pvt(&tmp);
07313                      return NULL;
07314                   }
07315                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07316                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07317                      destroy_zt_pvt(&tmp);
07318                      return NULL;
07319                   }
07320                   if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) {
07321                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07322                      destroy_zt_pvt(&tmp);
07323                      return NULL;
07324                   }
07325                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) {
07326                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial);
07327                      destroy_zt_pvt(&tmp);
07328                      return NULL;
07329                   }
07330                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) {
07331                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext);
07332                      destroy_zt_pvt(&tmp);
07333                      return NULL;
07334                   }
07335                   if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) {
07336                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused);
07337                      destroy_zt_pvt(&tmp);
07338                      return NULL;
07339                   }
07340                   if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) {
07341                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle);
07342                      destroy_zt_pvt(&tmp);
07343                      return NULL;
07344                   }
07345                   if (pris[span].numchans >= MAX_CHANNELS) {
07346                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07347                         pris[span].trunkgroup);
07348                      destroy_zt_pvt(&tmp);
07349                      return NULL;
07350                   }
07351                   pris[span].nodetype = conf->pri.nodetype;
07352                   pris[span].switchtype = myswitchtype;
07353                   pris[span].nsf = conf->pri.nsf;
07354                   pris[span].dialplan = conf->pri.dialplan;
07355                   pris[span].localdialplan = conf->pri.localdialplan;
07356                   pris[span].pvts[pris[span].numchans++] = tmp;
07357                   pris[span].minunused = conf->pri.minunused;
07358                   pris[span].minidle = conf->pri.minidle;
07359                   pris[span].overlapdial = conf->pri.overlapdial;
07360                   pris[span].facilityenable = conf->pri.facilityenable;
07361                   ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial));
07362                   ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext));
07363                   ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix));
07364                   ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix));
07365                   ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix));
07366                   ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix));
07367                   ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix));
07368                   pris[span].resetinterval = conf->pri.resetinterval;
07369                   
07370                   tmp->pri = &pris[span];
07371                   tmp->prioffset = offset;
07372                   tmp->call = NULL;
07373                } else {
07374                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07375                   destroy_zt_pvt(&tmp);
07376                   return NULL;
07377                }
07378             }
07379          } else {
07380             tmp->prioffset = 0;
07381          }
07382 #endif
07383       } else {
07384          chan_sig = tmp->sig;
07385          memset(&p, 0, sizeof(p));
07386          if (tmp->subs[SUB_REAL].zfd > -1)
07387             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07388       }
07389       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07390       switch (chan_sig) {
07391       case SIG_FXSKS:
07392       case SIG_FXSLS:
07393       case SIG_EM:
07394       case SIG_EM_E1:
07395       case SIG_EMWINK:
07396       case SIG_FEATD:
07397       case SIG_FEATDMF:
07398       case SIG_FEATDMF_TA:
07399       case SIG_FEATB:
07400       case SIG_E911:
07401       case SIG_SF:
07402       case SIG_SFWINK:
07403       case SIG_FGC_CAMA:
07404       case SIG_FGC_CAMAMF:
07405       case SIG_SF_FEATD:
07406       case SIG_SF_FEATDMF:
07407       case SIG_SF_FEATB:
07408          p.starttime = 250;
07409          break;
07410       }
07411 
07412       if (tmp->radio) {
07413          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07414          p.channo = channel;
07415          p.rxwinktime = 1;
07416          p.rxflashtime = 1;
07417          p.starttime = 1;
07418          p.debouncetime = 5;
07419       }
07420       if (!tmp->radio) {
07421          p.channo = channel;
07422          /* Override timing settings based on config file */
07423          if (conf->timing.prewinktime >= 0)
07424             p.prewinktime = conf->timing.prewinktime;
07425          if (conf->timing.preflashtime >= 0)
07426             p.preflashtime = conf->timing.preflashtime;
07427          if (conf->timing.winktime >= 0)
07428             p.winktime = conf->timing.winktime;
07429          if (conf->timing.flashtime >= 0)
07430             p.flashtime = conf->timing.flashtime;
07431          if (conf->timing.starttime >= 0)
07432             p.starttime = conf->timing.starttime;
07433          if (conf->timing.rxwinktime >= 0)
07434             p.rxwinktime = conf->timing.rxwinktime;
07435          if (conf->timing.rxflashtime >= 0)
07436             p.rxflashtime = conf->timing.rxflashtime;
07437          if (conf->timing.debouncetime >= 0)
07438             p.debouncetime = conf->timing.debouncetime;
07439       }
07440       
07441       /* dont set parms on a pseudo-channel (or CRV) */
07442       if (tmp->subs[SUB_REAL].zfd >= 0)
07443       {
07444          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07445          if (res < 0) {
07446             ast_log(LOG_ERROR, "Unable to set parameters\n");
07447             destroy_zt_pvt(&tmp);
07448             return NULL;
07449          }
07450       }
07451 #if 1
07452       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07453          memset(&bi, 0, sizeof(bi));
07454          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07455          if (!res) {
07456             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07457             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07458             bi.numbufs = numbufs;
07459             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07460             if (res < 0) {
07461                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07462             }
07463          } else
07464             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07465       }
07466 #endif
07467       tmp->immediate = conf->chan.immediate;
07468       tmp->transfertobusy = conf->chan.transfertobusy;
07469       tmp->sig = chan_sig;
07470       tmp->outsigmod = conf->chan.outsigmod;
07471       tmp->ringt_base = ringt_base;
07472       tmp->firstradio = 0;
07473       if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
07474          tmp->permcallwaiting = conf->chan.callwaiting;
07475       else
07476          tmp->permcallwaiting = 0;
07477       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07478       tmp->destroy = 0;
07479       tmp->drings = drings;
07480       tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
07481       tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
07482       tmp->threewaycalling = conf->chan.threewaycalling;
07483       tmp->adsi = conf->chan.adsi;
07484       tmp->use_smdi = conf->chan.use_smdi;
07485       tmp->permhidecallerid = conf->chan.hidecallerid;
07486       tmp->callreturn = conf->chan.callreturn;
07487       tmp->echocancel = conf->chan.echocancel;
07488       tmp->echotraining = conf->chan.echotraining;
07489       tmp->pulse = conf->chan.pulse;
07490       if (tmp->echocancel)
07491          tmp->echocanbridged = conf->chan.echocanbridged;
07492       else {
07493          if (conf->chan.echocanbridged)
07494             ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
07495          tmp->echocanbridged = 0;
07496       }
07497       tmp->busydetect = conf->chan.busydetect;
07498       tmp->busycount = conf->chan.busycount;
07499       tmp->busycompare = conf->chan.busycompare;
07500       tmp->busytonelength = conf->chan.busytonelength;
07501       tmp->busyquietlength = conf->chan.busyquietlength;
07502       tmp->busyfuzziness = conf->chan.busyfuzziness;
07503       tmp->silencethreshold = conf->chan.silencethreshold;
07504       tmp->callprogress = conf->chan.callprogress;
07505       tmp->cancallforward = conf->chan.cancallforward;
07506       tmp->dtmfrelax = conf->chan.dtmfrelax;
07507       tmp->callwaiting = tmp->permcallwaiting;
07508       tmp->hidecallerid = tmp->permhidecallerid;
07509       tmp->channel = channel;
07510       tmp->stripmsd = conf->chan.stripmsd;
07511       tmp->use_callerid = conf->chan.use_callerid;
07512       tmp->cid_signalling = conf->chan.cid_signalling;
07513       tmp->cid_start = conf->chan.cid_start;
07514       tmp->zaptrcallerid = conf->chan.zaptrcallerid;
07515       tmp->restrictcid = conf->chan.restrictcid;
07516       tmp->use_callingpres = conf->chan.use_callingpres;
07517       tmp->priindication_oob = conf->chan.priindication_oob;
07518       tmp->priexclusive = conf->chan.priexclusive;
07519       if (tmp->usedistinctiveringdetection) {
07520          if (!tmp->use_callerid) {
07521             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07522             tmp->use_callerid = 1;
07523          }
07524       }
07525 
07526       if (tmp->cid_signalling == CID_SIG_SMDI) {
07527          if (!tmp->use_smdi) {
07528             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07529             tmp->use_smdi = 1;
07530          }
07531       }
07532       if (tmp->use_smdi) {
07533          tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
07534          if (!(tmp->smdi_iface)) {
07535             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07536             tmp->use_smdi = 0;
07537          }
07538       }
07539 
07540       ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
07541       tmp->amaflags = conf->chan.amaflags;
07542       if (!here) {
07543          tmp->confno = -1;
07544          tmp->propconfno = -1;
07545       }
07546       tmp->canpark = conf->chan.canpark;
07547       tmp->transfer = conf->chan.transfer;
07548       ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
07549       ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
07550       ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
07551       ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
07552       ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
07553       ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
07554       tmp->cid_ton = 0;
07555       ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
07556       ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
07557       tmp->msgstate = -1;
07558       tmp->group = conf->chan.group;
07559       tmp->callgroup = conf->chan.callgroup;
07560       tmp->pickupgroup= conf->chan.pickupgroup;
07561       tmp->rxgain = conf->chan.rxgain;
07562       tmp->txgain = conf->chan.txgain;
07563       tmp->tonezone = conf->chan.tonezone;
07564       tmp->onhooktime = time(NULL);
07565       if (tmp->subs[SUB_REAL].zfd > -1) {
07566          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07567          if (tmp->dsp)
07568             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07569          update_conf(tmp);
07570          if (!here) {
07571             if (chan_sig != SIG_PRI)
07572                /* Hang it up to be sure it's good */
07573                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07574          }
07575          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07576 #ifdef HAVE_PRI
07577          /* the dchannel is down so put the channel in alarm */
07578          if (tmp->pri && !pri_is_up(tmp->pri))
07579             tmp->inalarm = 1;
07580          else
07581             tmp->inalarm = 0;
07582 #endif            
07583          memset(&si, 0, sizeof(si));
07584          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07585             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07586             destroy_zt_pvt(&tmp);
07587             return NULL;
07588          }
07589          if (si.alarms) tmp->inalarm = 1;
07590       }
07591 
07592       tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
07593       tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
07594       tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
07595       tmp->sendcalleridafter = conf->chan.sendcalleridafter;
07596 
07597    }
07598    if (tmp && !here) {
07599       /* nothing on the iflist */
07600       if (!*wlist) {
07601          *wlist = tmp;
07602          tmp->prev = NULL;
07603          tmp->next = NULL;
07604          *wend = tmp;
07605       } else {
07606          /* at least one member on the iflist */
07607          struct zt_pvt *working = *wlist;
07608 
07609          /* check if we maybe have to put it on the begining */
07610          if (working->channel > tmp->channel) {
07611             tmp->next = *wlist;
07612             tmp->prev = NULL;
07613             (*wlist)->prev = tmp;
07614             *wlist = tmp;
07615          } else {
07616          /* go through all the members and put the member in the right place */
07617             while (working) {
07618                /* in the middle */
07619                if (working->next) {
07620                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07621                      tmp->next = working->next;
07622                      tmp->prev = working;
07623                      working->next->prev = tmp;
07624                      working->next = tmp;
07625                      break;
07626                   }
07627                } else {
07628                /* the last */
07629                   if (working->channel < tmp->channel) {
07630                      working->next = tmp;
07631                      tmp->next = NULL;
07632                      tmp->prev = working;
07633                      *wend = tmp;
07634                      break;
07635                   }
07636                }
07637                working = working->next;
07638             }
07639          }
07640       }
07641    }
07642    return tmp;
07643 }
07644 
07645 static inline int available(struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
07646 {
07647    int res;
07648    ZT_PARAMS par;
07649 
07650    /* First, check group matching */
07651    if (groupmatch) {
07652       if ((p->group & groupmatch) != groupmatch)
07653          return 0;
07654       *groupmatched = 1;
07655    }
07656    /* Check to see if we have a channel match */
07657    if (channelmatch != -1) {
07658       if (p->channel != channelmatch)
07659          return 0;
07660       *channelmatched = 1;
07661    }
07662    /* We're at least busy at this point */
07663    if (busy) {
07664       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07665          *busy = 1;
07666    }
07667    /* If do not disturb, definitely not */
07668    if (p->dnd)
07669       return 0;
07670    /* If guard time, definitely not */
07671    if (p->guardtime && (time(NULL) < p->guardtime)) 
07672       return 0;
07673       
07674    /* If no owner definitely available */
07675    if (!p->owner) {
07676 #ifdef HAVE_PRI
07677       /* Trust PRI */
07678       if (p->pri) {
07679          if (p->resetting || p->call)
07680             return 0;
07681          else
07682             return 1;
07683       }
07684 #endif
07685       if (!(p->radio || (p->oprmode < 0)))
07686       {
07687          if (!p->sig || (p->sig == SIG_FXSLS))
07688             return 1;
07689          /* Check hook state */
07690          if (p->subs[SUB_REAL].zfd > -1)
07691             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07692          else {
07693             /* Assume not off hook on CVRS */
07694             res = 0;
07695             par.rxisoffhook = 0;
07696          }
07697          if (res) {
07698             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07699          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07700             /* When "onhook" that means no battery on the line, and thus
07701               it is out of service..., if it's on a TDM card... If it's a channel
07702               bank, there is no telling... */
07703             if (par.rxbits > -1)
07704                return 1;
07705             if (par.rxisoffhook)
07706                return 1;
07707             else
07708 #ifdef ZAP_CHECK_HOOKSTATE
07709                return 0;
07710 #else
07711                return 1;
07712 #endif
07713          } else if (par.rxisoffhook) {
07714             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07715             /* Not available when the other end is off hook */
07716             return 0;
07717          }
07718       }
07719       return 1;
07720    }
07721 
07722    /* If it's not an FXO, forget about call wait */
07723    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07724       return 0;
07725 
07726    if (!p->callwaiting) {
07727       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07728       return 0;
07729    }
07730 
07731    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07732       /* If there is already a call waiting call, then we can't take a second one */
07733       return 0;
07734    }
07735    
07736    if ((p->owner->_state != AST_STATE_UP) &&
07737        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07738       /* If the current call is not up, then don't allow the call */
07739       return 0;
07740    }
07741    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07742       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07743       return 0;
07744    }
07745    /* We're cool */
07746    return 1;
07747 }
07748 
07749 static struct zt_pvt *chandup(struct zt_pvt *src)
07750 {
07751    struct zt_pvt *p;
07752    ZT_BUFFERINFO bi;
07753    int res;
07754    
07755    if ((p = ast_malloc(sizeof(*p)))) {
07756       memcpy(p, src, sizeof(struct zt_pvt));
07757       ast_mutex_init(&p->lock);
07758       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07759       /* Allocate a zapata structure */
07760       if (p->subs[SUB_REAL].zfd < 0) {
07761          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07762          destroy_zt_pvt(&p);
07763          return NULL;
07764       }
07765       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07766       if (!res) {
07767          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07768          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07769          bi.numbufs = numbufs;
07770          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07771          if (res < 0) {
07772             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07773          }
07774       } else
07775          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07776    }
07777    p->destroy = 1;
07778    p->next = iflist;
07779    p->prev = NULL;
07780    iflist = p;
07781    if (iflist->next)
07782       iflist->next->prev = p;
07783    return p;
07784 }
07785    
07786 
07787 #ifdef HAVE_PRI
07788 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
07789 {
07790    int x;
07791    if (backwards)
07792       x = pri->numchans;
07793    else
07794       x = 0;
07795    for (;;) {
07796       if (backwards && (x < 0))
07797          break;
07798       if (!backwards && (x >= pri->numchans))
07799          break;
07800       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
07801          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
07802             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
07803          return x;
07804       }
07805       if (backwards)
07806          x--;
07807       else
07808          x++;
07809    }
07810    return -1;
07811 }
07812 #endif
07813 
07814 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
07815 {
07816    ast_group_t groupmatch = 0;
07817    int channelmatch = -1;
07818    int roundrobin = 0;
07819    int callwait = 0;
07820    int busy = 0;
07821    struct zt_pvt *p;
07822    struct ast_channel *tmp = NULL;
07823    char *dest=NULL;
07824    int x;
07825    char *s;
07826    char opt=0;
07827    int res=0, y=0;
07828    int backwards = 0;
07829 #ifdef HAVE_PRI
07830    int crv;
07831    int bearer = -1;
07832    int trunkgroup;
07833    struct zt_pri *pri=NULL;
07834 #endif   
07835    struct zt_pvt *exit, *start, *end;
07836    ast_mutex_t *lock;
07837    int channelmatched = 0;
07838    int groupmatched = 0;
07839    
07840    /* Assume we're locking the iflock */
07841    lock = &iflock;
07842    start = iflist;
07843    end = ifend;
07844    if (data) {
07845       dest = ast_strdupa((char *)data);
07846    } else {
07847       ast_log(LOG_WARNING, "Channel requested with no data\n");
07848       return NULL;
07849    }
07850    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07851       /* Retrieve the group number */
07852       char *stringp=NULL;
07853       stringp=dest + 1;
07854       s = strsep(&stringp, "/");
07855       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07856          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07857          return NULL;
07858       }
07859       groupmatch = ((ast_group_t) 1 << x);
07860       if (toupper(dest[0]) == 'G') {
07861          if (dest[0] == 'G') {
07862             backwards = 1;
07863             p = ifend;
07864          } else
07865             p = iflist;
07866       } else {
07867          if (dest[0] == 'R') {
07868             backwards = 1;
07869             p = round_robin[x]?round_robin[x]->prev:ifend;
07870             if (!p)
07871                p = ifend;
07872          } else {
07873             p = round_robin[x]?round_robin[x]->next:iflist;
07874             if (!p)
07875                p = iflist;
07876          }
07877          roundrobin = 1;
07878       }
07879    } else {
07880       char *stringp=NULL;
07881       stringp=dest;
07882       s = strsep(&stringp, "/");
07883       p = iflist;
07884       if (!strcasecmp(s, "pseudo")) {
07885          /* Special case for pseudo */
07886          x = CHAN_PSEUDO;
07887          channelmatch = x;
07888       } 
07889 #ifdef HAVE_PRI
07890       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07891          if ((trunkgroup < 1) || (crv < 1)) {
07892             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07893             return NULL;
07894          }
07895          res--;
07896          for (x = 0; x < NUM_SPANS; x++) {
07897             if (pris[x].trunkgroup == trunkgroup) {
07898                pri = pris + x;
07899                lock = &pri->lock;
07900                start = pri->crvs;
07901                end = pri->crvend;
07902                break;
07903             }
07904          }
07905          if (!pri) {
07906             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07907             return NULL;
07908          }
07909          channelmatch = crv;
07910          p = pris[x].crvs;
07911       }
07912 #endif   
07913       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07914          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07915          return NULL;
07916       } else {
07917          channelmatch = x;
07918       }
07919    }
07920    /* Search for an unowned channel */
07921    ast_mutex_lock(lock);
07922    exit = p;
07923    while (p && !tmp) {
07924       if (roundrobin)
07925          round_robin[x] = p;
07926 #if 0
07927       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07928 #endif
07929 
07930       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07931          if (option_debug)
07932             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07933             if (p->inalarm) 
07934                goto next;
07935 
07936          callwait = (p->owner != NULL);
07937 #ifdef HAVE_PRI
07938          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07939             if (p->sig != SIG_FXSKS) {
07940                /* Gotta find an actual channel to use for this
07941                   CRV if this isn't a callwait */
07942                bearer = pri_find_empty_chan(pri, 0);
07943                if (bearer < 0) {
07944                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07945                   p = NULL;
07946                   break;
07947                }
07948                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07949             } else {
07950                if (alloc_sub(p, 0)) {
07951                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07952                   p = NULL;
07953                   break;
07954                } else
07955                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07956                p->pri = pri;
07957             }
07958          }
07959 #endif         
07960          if (p->channel == CHAN_PSEUDO) {
07961             p = chandup(p);
07962             if (!p) {
07963                break;
07964             }
07965          }
07966          if (p->owner) {
07967             if (alloc_sub(p, SUB_CALLWAIT)) {
07968                p = NULL;
07969                break;
07970             }
07971          }
07972          p->outgoing = 1;
07973          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07974 #ifdef HAVE_PRI
07975          if (p->bearer) {
07976             /* Log owner to bearer channel, too */
07977             p->bearer->owner = tmp;
07978          }
07979 #endif         
07980          /* Make special notes */
07981          if (res > 1) {
07982             if (opt == 'c') {
07983                /* Confirm answer */
07984                p->confirmanswer = 1;
07985             } else if (opt == 'r') {
07986                /* Distinctive ring */
07987                if (res < 3)
07988                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07989                else
07990                   p->distinctivering = y;
07991             } else if (opt == 'd') {
07992                /* If this is an ISDN call, make it digital */
07993                p->digital = 1;
07994                if (tmp)
07995                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07996             } else {
07997                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07998             }
07999          }
08000          /* Note if the call is a call waiting call */
08001          if (tmp && callwait)
08002             tmp->cdrflags |= AST_CDR_CALLWAIT;
08003          break;
08004       }
08005 next:
08006       if (backwards) {
08007          p = p->prev;
08008          if (!p)
08009             p = end;
08010       } else {
08011          p = p->next;
08012          if (!p)
08013             p = start;
08014       }
08015       /* stop when you roll to the one that we started from */
08016       if (p == exit)
08017          break;
08018    }
08019    ast_mutex_unlock(lock);
08020    restart_monitor();
08021    if (callwait)
08022       *cause = AST_CAUSE_BUSY;
08023    else if (!tmp) {
08024       if (channelmatched) {
08025          if (busy)
08026             *cause = AST_CAUSE_BUSY;
08027       } else if (groupmatched) {
08028          *cause = AST_CAUSE_CONGESTION;
08029       }
08030    }
08031       
08032    return tmp;
08033 }
08034 
08035 
08036 #ifdef HAVE_PRI
08037 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
08038 {
08039    struct zt_pvt *p;
08040    p = pri->crvs;
08041    while (p) {
08042       if (p->channel == crv)
08043          return p;
08044       p = p->next;
08045    }
08046    return NULL;
08047 }
08048 
08049 
08050 static int pri_find_principle(struct zt_pri *pri, int channel)
08051 {
08052    int x;
08053    int span = PRI_SPAN(channel);
08054    int spanfd;
08055    ZT_PARAMS param;
08056    int principle = -1;
08057    int explicit = PRI_EXPLICIT(channel);
08058    channel = PRI_CHANNEL(channel);
08059 
08060    if (!explicit) {
08061       spanfd = pri_active_dchan_fd(pri);
08062       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
08063          return -1;
08064       span = pris[param.spanno - 1].prilogicalspan;
08065    }
08066 
08067    for (x = 0; x < pri->numchans; x++) {
08068       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
08069          principle = x;
08070          break;
08071       }
08072    }
08073    
08074    return principle;
08075 }
08076 
08077 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
08078 {
08079    int x;
08080    struct zt_pvt *crv;
08081    if (!c) {
08082       if (principle < 0)
08083          return -1;
08084       return principle;
08085    }
08086    if ((principle > -1) && 
08087       (principle < pri->numchans) && 
08088       (pri->pvts[principle]) && 
08089       (pri->pvts[principle]->call == c))
08090       return principle;
08091    /* First, check for other bearers */
08092    for (x = 0; x < pri->numchans; x++) {
08093       if (!pri->pvts[x])
08094          continue;
08095       if (pri->pvts[x]->call == c) {
08096          /* Found our call */
08097          if (principle != x) {
08098             struct zt_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
08099 
08100             if (option_verbose > 2)
08101                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08102                   old->channel, new->channel);
08103             if (new->owner) {
08104                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08105                   old->channel, new->channel, new->channel);
08106                return -1;
08107             }
08108             /* Fix it all up now */
08109             new->owner = old->owner;
08110             old->owner = NULL;
08111             if (new->owner) {
08112                ast_string_field_build(new->owner, name, 
08113                             "Zap/%d:%d-%d", pri->trunkgroup,
08114                             new->channel, 1);
08115                new->owner->tech_pvt = new;
08116                new->owner->fds[0] = new->subs[SUB_REAL].zfd;
08117                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
08118                old->subs[SUB_REAL].owner = NULL;
08119             } else
08120                ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel);
08121             new->call = old->call;
08122             old->call = NULL;
08123 
08124             /* Copy any DSP that may be present */
08125             new->dsp = old->dsp;
08126             new->dsp_features = old->dsp_features;
08127             old->dsp = NULL;
08128             old->dsp_features = 0;
08129          }
08130          return principle;
08131       }
08132    }
08133    /* Now check for a CRV with no bearer */
08134    crv = pri->crvs;
08135    while (crv) {
08136       if (crv->call == c) {
08137          /* This is our match...  Perform some basic checks */
08138          if (crv->bearer)
08139             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08140          else if (pri->pvts[principle]->owner) 
08141             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08142          else {
08143             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08144                wakeup the potential sleeper */
08145             zt_close(crv->subs[SUB_REAL].zfd);
08146             pri->pvts[principle]->call = crv->call;
08147             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08148             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08149                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08150                            pri->trunkgroup, crv->channel);
08151             wakeup_sub(crv, SUB_REAL, pri);
08152          }
08153          return principle;
08154       }
08155       crv = crv->next;
08156    }
08157    ast_log(LOG_WARNING, "Call specified, but not found?\n");
08158    return -1;
08159 }
08160 
08161 static void *do_idle_thread(void *vchan)
08162 {
08163    struct ast_channel *chan = vchan;
08164    struct zt_pvt *pvt = chan->tech_pvt;
08165    struct ast_frame *f;
08166    char ex[80];
08167    /* Wait up to 30 seconds for an answer */
08168    int newms, ms = 30000;
08169    if (option_verbose > 2) 
08170       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08171    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08172    if (ast_call(chan, ex, 0)) {
08173       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08174       ast_hangup(chan);
08175       return NULL;
08176    }
08177    while ((newms = ast_waitfor(chan, ms)) > 0) {
08178       f = ast_read(chan);
08179       if (!f) {
08180          /* Got hangup */
08181          break;
08182       }
08183       if (f->frametype == AST_FRAME_CONTROL) {
08184          switch (f->subclass) {
08185          case AST_CONTROL_ANSWER:
08186             /* Launch the PBX */
08187             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08188             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08189             chan->priority = 1;
08190             if (option_verbose > 3) 
08191                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08192             ast_pbx_run(chan);
08193             /* It's already hungup, return immediately */
08194             return NULL;
08195          case AST_CONTROL_BUSY:
08196             if (option_verbose > 3) 
08197                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08198             break;
08199          case AST_CONTROL_CONGESTION:
08200             if (option_verbose > 3) 
08201                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08202             break;
08203          };
08204       }
08205       ast_frfree(f);
08206       ms = newms;
08207    }
08208    /* Hangup the channel since nothing happend */
08209    ast_hangup(chan);
08210    return NULL;
08211 }
08212 
08213 #ifndef PRI_RESTART
08214 #error "Upgrade your libpri"
08215 #endif
08216 static void zt_pri_message(struct pri *pri, char *s)
08217 {
08218    int x, y;
08219    int dchan = -1, span = -1;
08220    int dchancount = 0;
08221 
08222    if (pri) {
08223       for (x = 0; x < NUM_SPANS; x++) {
08224          for (y = 0; y < NUM_DCHANS; y++) {
08225             if (pris[x].dchans[y])
08226                dchancount++;
08227 
08228             if (pris[x].dchans[y] == pri)
08229                dchan = y;
08230          }
08231          if (dchan >= 0) {
08232             span = x;
08233             break;
08234          }
08235          dchancount = 0;
08236       }
08237       if ((dchan >= 0) && (span >= 0)) {
08238          if (dchancount > 1)
08239             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
08240          else
08241             ast_verbose("%s", s);
08242       } else
08243          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08244    } else
08245       ast_verbose("%s", s);
08246 
08247    ast_mutex_lock(&pridebugfdlock);
08248 
08249    if (pridebugfd >= 0)
08250       write(pridebugfd, s, strlen(s));
08251 
08252    ast_mutex_unlock(&pridebugfdlock);
08253 }
08254 
08255 static void zt_pri_error(struct pri *pri, char *s)
08256 {
08257    int x, y;
08258    int dchan = -1, span = -1;
08259    int dchancount = 0;
08260 
08261    if (pri) {
08262       for (x = 0; x < NUM_SPANS; x++) {
08263          for (y = 0; y < NUM_DCHANS; y++) {
08264             if (pris[x].dchans[y])
08265                dchancount++;
08266 
08267             if (pris[x].dchans[y] == pri)
08268                dchan = y;
08269          }
08270          if (dchan >= 0) {
08271             span = x;
08272             break;
08273          }
08274          dchancount = 0;
08275       }
08276       if ((dchan >= 0) && (span >= 0)) {
08277          if (dchancount > 1)
08278             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
08279          else
08280             ast_log(LOG_ERROR, "%s", s);
08281       } else
08282          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08283    } else
08284       ast_log(LOG_ERROR, "%s", s);
08285 
08286    ast_mutex_lock(&pridebugfdlock);
08287 
08288    if (pridebugfd >= 0)
08289       write(pridebugfd, s, strlen(s));
08290 
08291    ast_mutex_unlock(&pridebugfdlock);
08292 }
08293 
08294 static int pri_check_restart(struct zt_pri *pri)
08295 {
08296    do {
08297       pri->resetpos++;
08298    } while ((pri->resetpos < pri->numchans) &&
08299        (!pri->pvts[pri->resetpos] ||
08300         pri->pvts[pri->resetpos]->call ||
08301         pri->pvts[pri->resetpos]->resetting));
08302    if (pri->resetpos < pri->numchans) {
08303       /* Mark the channel as resetting and restart it */
08304       pri->pvts[pri->resetpos]->resetting = 1;
08305       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08306    } else {
08307       pri->resetting = 0;
08308       time(&pri->lastreset);
08309    }
08310    return 0;
08311 }
08312 
08313 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08314 {
08315    int x;
08316    int redo;
08317    ast_mutex_unlock(&pri->lock);
08318    ast_mutex_lock(&p->lock);
08319    do {
08320       redo = 0;
08321       for (x = 0; x < 3; x++) {
08322          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08323             redo++;
08324             DEADLOCK_AVOIDANCE(&p->lock);
08325          }
08326          if (p->subs[x].owner) {
08327             ast_queue_hangup(p->subs[x].owner);
08328             ast_mutex_unlock(&p->subs[x].owner->lock);
08329          }
08330       }
08331    } while (redo);
08332    ast_mutex_unlock(&p->lock);
08333    ast_mutex_lock(&pri->lock);
08334    return 0;
08335 }
08336 
08337 static char * redirectingreason2str(int redirectingreason)
08338 {
08339    switch (redirectingreason) {
08340    case 0:
08341       return "UNKNOWN";
08342    case 1:
08343       return "BUSY";
08344    case 2:
08345       return "NO_REPLY";
08346    case 0xF:
08347       return "UNCONDITIONAL";
08348    default:
08349       return "NOREDIRECT";
08350    }
08351 }
08352 
08353 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08354 {
08355    switch (plan) {
08356    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08357       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08358       break;
08359    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08360       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08361       break;
08362    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08363       snprintf(buf, size, "%s%s", pri->localprefix, number);
08364       break;
08365    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08366       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08367       break;
08368    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08369       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08370       break;
08371    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08372       snprintf(buf, size, "%s", number);
08373       break;
08374    }
08375 }
08376 
08377 static int zt_setlaw(int zfd, int law)
08378 {
08379    int res;
08380    res = ioctl(zfd, ZT_SETLAW, &law);
08381    if (res)
08382       return res;
08383    return 0;
08384 }
08385 
08386 static void *pri_dchannel(void *vpri)
08387 {
08388    struct zt_pri *pri = vpri;
08389    pri_event *e;
08390    struct pollfd fds[NUM_DCHANS];
08391    int res;
08392    int chanpos = 0;
08393    int x;
08394    int haveidles;
08395    int activeidles;
08396    int nextidle = -1;
08397    struct ast_channel *c;
08398    struct timeval tv, lowest, *next;
08399    struct timeval lastidle = { 0, 0 };
08400    int doidling=0;
08401    char *cc;
08402    char idlen[80];
08403    struct ast_channel *idle;
08404    pthread_t p;
08405    time_t t;
08406    int i, which=-1;
08407    int numdchans;
08408    int cause=0;
08409    struct zt_pvt *crv;
08410    pthread_t threadid;
08411    pthread_attr_t attr;
08412    char ani2str[6];
08413    char plancallingnum[256];
08414    char plancallingani[256];
08415    char calledtonstr[10];
08416    
08417    gettimeofday(&lastidle, NULL);
08418    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08419       /* Need to do idle dialing, check to be sure though */
08420       cc = strchr(pri->idleext, '@');
08421       if (cc) {
08422          *cc = '\0';
08423          cc++;
08424          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08425 #if 0
08426          /* Extensions may not be loaded yet */
08427          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08428             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08429          else
08430 #endif
08431             doidling = 1;
08432       } else
08433          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08434    }
08435    for (;;) {
08436       for (i = 0; i < NUM_DCHANS; i++) {
08437          if (!pri->dchannels[i])
08438             break;
08439          fds[i].fd = pri->fds[i];
08440          fds[i].events = POLLIN | POLLPRI;
08441          fds[i].revents = 0;
08442       }
08443       numdchans = i;
08444       time(&t);
08445       ast_mutex_lock(&pri->lock);
08446       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08447          if (pri->resetting && pri_is_up(pri)) {
08448             if (pri->resetpos < 0)
08449                pri_check_restart(pri);
08450          } else {
08451             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08452                pri->resetting = 1;
08453                pri->resetpos = -1;
08454             }
08455          }
08456       }
08457       /* Look for any idle channels if appropriate */
08458       if (doidling && pri_is_up(pri)) {
08459          nextidle = -1;
08460          haveidles = 0;
08461          activeidles = 0;
08462          for (x = pri->numchans; x >= 0; x--) {
08463             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08464                 !pri->pvts[x]->call) {
08465                if (haveidles < pri->minunused) {
08466                   haveidles++;
08467                } else if (!pri->pvts[x]->resetting) {
08468                   nextidle = x;
08469                   break;
08470                }
08471             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08472                activeidles++;
08473          }
08474          if (nextidle > -1) {
08475             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08476                /* Don't create a new idle call more than once per second */
08477                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08478                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08479                if (idle) {
08480                   pri->pvts[nextidle]->isidlecall = 1;
08481                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08482                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08483                      zt_hangup(idle);
08484                   }
08485                } else
08486                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08487                gettimeofday(&lastidle, NULL);
08488             }
08489          } else if ((haveidles < pri->minunused) &&
08490                (activeidles > pri->minidle)) {
08491             /* Mark something for hangup if there is something 
08492                that can be hungup */
08493             for (x = pri->numchans; x >= 0; x--) {
08494                /* find a candidate channel */
08495                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08496                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08497                   haveidles++;
08498                   /* Stop if we have enough idle channels or
08499                     can't spare any more active idle ones */
08500                   if ((haveidles >= pri->minunused) ||
08501                       (activeidles <= pri->minidle))
08502                      break;
08503                } 
08504             }
08505          }
08506       }
08507       /* Start with reasonable max */
08508       lowest = ast_tv(60, 0);
08509       for (i = 0; i < NUM_DCHANS; i++) {
08510          /* Find lowest available d-channel */
08511          if (!pri->dchannels[i])
08512             break;
08513          if ((next = pri_schedule_next(pri->dchans[i]))) {
08514             /* We need relative time here */
08515             tv = ast_tvsub(*next, ast_tvnow());
08516             if (tv.tv_sec < 0) {
08517                tv = ast_tv(0,0);
08518             }
08519             if (doidling || pri->resetting) {
08520                if (tv.tv_sec > 1) {
08521                   tv = ast_tv(1, 0);
08522                }
08523             } else {
08524                if (tv.tv_sec > 60) {
08525                   tv = ast_tv(60, 0);
08526                }
08527             }
08528          } else if (doidling || pri->resetting) {
08529             /* Make sure we stop at least once per second if we're
08530                monitoring idle channels */
08531             tv = ast_tv(1,0);
08532          } else {
08533             /* Don't poll for more than 60 seconds */
08534             tv = ast_tv(60, 0);
08535          }
08536          if (!i || ast_tvcmp(tv, lowest) < 0) {
08537             lowest = tv;
08538          }
08539       }
08540       ast_mutex_unlock(&pri->lock);
08541 
08542       e = NULL;
08543       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
08544 
08545       ast_mutex_lock(&pri->lock);
08546       if (!res) {
08547          for (which = 0; which < NUM_DCHANS; which++) {
08548             if (!pri->dchans[which])
08549                break;
08550             /* Just a timeout, run the scheduler */
08551             e = pri_schedule_run(pri->dchans[which]);
08552             if (e)
08553                break;
08554          }
08555       } else if (res > -1) {
08556          for (which = 0; which < NUM_DCHANS; which++) {
08557             if (!pri->dchans[which])
08558                break;
08559             if (fds[which].revents & POLLPRI) {
08560                /* Check for an event */
08561                x = 0;
08562                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
08563                if (x) 
08564                   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);
08565                /* Keep track of alarm state */  
08566                if (x == ZT_EVENT_ALARM) {
08567                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
08568                   pri_find_dchan(pri);
08569                } else if (x == ZT_EVENT_NOALARM) {
08570                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
08571                   pri_restart(pri->dchans[which]);
08572                }
08573             
08574                if (option_debug)
08575                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
08576             } else if (fds[which].revents & POLLIN) {
08577                e = pri_check_event(pri->dchans[which]);
08578             }
08579             if (e)
08580                break;
08581          }
08582       } else if (errno != EINTR)
08583          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
08584 
08585       if (e) {
08586          if (pri->debug)
08587             pri_dump_event(pri->dchans[which], e);
08588 
08589          if (e->e != PRI_EVENT_DCHAN_DOWN) {
08590             if (!(pri->dchanavail[which] & DCHAN_UP)) {
08591                if (option_verbose > 1) 
08592                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
08593             }
08594             pri->dchanavail[which] |= DCHAN_UP;
08595          } else {
08596             if (pri->dchanavail[which] & DCHAN_UP) {
08597                if (option_verbose > 1) 
08598                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
08599             }
08600             pri->dchanavail[which] &= ~DCHAN_UP;
08601          }
08602 
08603          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
08604             /* Must be an NFAS group that has the secondary dchan active */
08605             pri->pri = pri->dchans[which];
08606 
08607          switch (e->e) {
08608          case PRI_EVENT_DCHAN_UP:
08609             if (!pri->pri) pri_find_dchan(pri);
08610 
08611             /* Note presense of D-channel */
08612             time(&pri->lastreset);
08613 
08614             /* Restart in 5 seconds */
08615             if (pri->resetinterval > -1) {
08616                pri->lastreset -= pri->resetinterval;
08617                pri->lastreset += 5;
08618             }
08619             pri->resetting = 0;
08620             /* Take the channels from inalarm condition */
08621             for (i = 0; i < pri->numchans; i++)
08622                if (pri->pvts[i]) {
08623                   pri->pvts[i]->inalarm = 0;
08624                }
08625             break;
08626          case PRI_EVENT_DCHAN_DOWN:
08627             pri_find_dchan(pri);
08628             if (!pri_is_up(pri)) {
08629                pri->resetting = 0;
08630                /* Hangup active channels and put them in alarm mode */
08631                for (i = 0; i < pri->numchans; i++) {
08632                   struct zt_pvt *p = pri->pvts[i];
08633                   if (p) {
08634                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08635                         /* T309 is not enabled : hangup calls when alarm occurs */
08636                         if (p->call) {
08637                            if (p->pri && p->pri->pri) {
08638                               pri_hangup(p->pri->pri, p->call, -1);
08639                               pri_destroycall(p->pri->pri, p->call);
08640                               p->call = NULL;
08641                            } else
08642                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
08643                         }
08644                         if (p->realcall) {
08645                            pri_hangup_all(p->realcall, pri);
08646                         } else if (p->owner)
08647                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08648                      }
08649                      p->inalarm = 1;
08650                   }
08651                }
08652             }
08653             break;
08654          case PRI_EVENT_RESTART:
08655             if (e->restart.channel > -1) {
08656                chanpos = pri_find_principle(pri, e->restart.channel);
08657                if (chanpos < 0)
08658                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
08659                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08660                else {
08661                   if (option_verbose > 2)
08662                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
08663                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08664                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08665                   if (pri->pvts[chanpos]->call) {
08666                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
08667                      pri->pvts[chanpos]->call = NULL;
08668                   }
08669                   /* Force soft hangup if appropriate */
08670                   if (pri->pvts[chanpos]->realcall) 
08671                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08672                   else if (pri->pvts[chanpos]->owner)
08673                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08674                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08675                }
08676             } else {
08677                if (option_verbose > 2)
08678                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
08679                for (x = 0; x < pri->numchans; x++)
08680                   if (pri->pvts[x]) {
08681                      ast_mutex_lock(&pri->pvts[x]->lock);
08682                      if (pri->pvts[x]->call) {
08683                         pri_destroycall(pri->pri, pri->pvts[x]->call);
08684                         pri->pvts[x]->call = NULL;
08685                      }
08686                      if (pri->pvts[chanpos]->realcall) 
08687                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08688                      else if (pri->pvts[x]->owner)
08689                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08690                      ast_mutex_unlock(&pri->pvts[x]->lock);
08691                   }
08692             }
08693             break;
08694          case PRI_EVENT_KEYPAD_DIGIT:
08695             chanpos = pri_find_principle(pri, e->digit.channel);
08696             if (chanpos < 0) {
08697                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
08698                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
08699             } else {
08700                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
08701                if (chanpos > -1) {
08702                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08703                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
08704                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
08705                      /* how to do that */
08706                      int digitlen = strlen(e->digit.digits);
08707                      char digit;
08708                      int i;               
08709                      for (i = 0; i < digitlen; i++) { 
08710                         digit = e->digit.digits[i];
08711                         {
08712                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08713                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08714                         }
08715                      }
08716                   }
08717                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08718                }
08719             }
08720             break;
08721             
08722          case PRI_EVENT_INFO_RECEIVED:
08723             chanpos = pri_find_principle(pri, e->ring.channel);
08724             if (chanpos < 0) {
08725                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
08726                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08727             } else {
08728                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
08729                if (chanpos > -1) {
08730                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08731                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
08732                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
08733                      /* how to do that */
08734                      int digitlen = strlen(e->ring.callednum);
08735                      char digit;
08736                      int i;               
08737                      for (i = 0; i < digitlen; i++) { 
08738                         digit = e->ring.callednum[i];
08739                         {
08740                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08741                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08742                         }
08743                      }
08744                   }
08745                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08746                }
08747             }
08748             break;
08749          case PRI_EVENT_RING:
08750             crv = NULL;
08751             if (e->ring.channel == -1)
08752                chanpos = pri_find_empty_chan(pri, 1);
08753             else
08754                chanpos = pri_find_principle(pri, e->ring.channel);
08755             /* if no channel specified find one empty */
08756             if (chanpos < 0) {
08757                ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 
08758                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08759             } else {
08760                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08761                if (pri->pvts[chanpos]->owner) {
08762                   if (pri->pvts[chanpos]->call == e->ring.call) {
08763                      ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
08764                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08765                      break;
08766                   } else {
08767                      /* This is where we handle initial glare */
08768                      ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiating channel.\n", 
08769                      PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08770                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08771                      chanpos = -1;
08772                   }
08773                }
08774                if (chanpos > -1)
08775                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08776             }
08777             if ((chanpos < 0) && (e->ring.flexible))
08778                chanpos = pri_find_empty_chan(pri, 1);
08779             if (chanpos > -1) {
08780                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08781                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
08782                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
08783                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
08784                   if (crv)
08785                      ast_mutex_lock(&crv->lock);
08786                   if (!crv || crv->owner) {
08787                      pri->pvts[chanpos]->call = NULL;
08788                      if (crv) {
08789                         if (crv->owner)
08790                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08791                         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);
08792                      } else
08793                         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);
08794                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
08795                      if (crv)
08796                         ast_mutex_unlock(&crv->lock);
08797                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08798                      break;
08799                   }
08800                }
08801                pri->pvts[chanpos]->call = e->ring.call;
08802                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
08803                if (pri->pvts[chanpos]->use_callerid) {
08804                   ast_shrink_phone_number(plancallingnum);
08805                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
08806 #ifdef PRI_ANI
08807                   if (!ast_strlen_zero(e->ring.callingani)) {
08808                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
08809                      ast_shrink_phone_number(plancallingani);
08810                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
08811                   } else {
08812                      pri->pvts[chanpos]->cid_ani[0] = '\0';
08813                   }
08814 #endif
08815                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
08816                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
08817                } else {
08818                   pri->pvts[chanpos]->cid_num[0] = '\0';
08819                   pri->pvts[chanpos]->cid_ani[0] = '\0';
08820                   pri->pvts[chanpos]->cid_name[0] = '\0';
08821                   pri->pvts[chanpos]->cid_ton = 0;
08822                }
08823                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
08824                           e->ring.redirectingnum, e->ring.callingplanrdnis);
08825                /* If immediate=yes go to s|1 */
08826                if (pri->pvts[chanpos]->immediate) {
08827                   if (option_verbose > 2)
08828                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
08829                   pri->pvts[chanpos]->exten[0] = 's';
08830                   pri->pvts[chanpos]->exten[1] = '\0';
08831                }
08832                /* Get called number */
08833                else if (!ast_strlen_zero(e->ring.callednum)) {
08834                   ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
08835                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08836                } else if (pri->overlapdial)
08837                   pri->pvts[chanpos]->exten[0] = '\0';
08838                else {
08839                   /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
08840                   pri->pvts[chanpos]->exten[0] = 's';
08841                   pri->pvts[chanpos]->exten[1] = '\0';
08842                }
08843                /* Set DNID on all incoming calls -- even immediate */
08844                if (!ast_strlen_zero(e->ring.callednum))
08845                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08846                /* No number yet, but received "sending complete"? */
08847                if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
08848                   if (option_verbose > 2)
08849                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
08850                   pri->pvts[chanpos]->exten[0] = 's';
08851                   pri->pvts[chanpos]->exten[1] = '\0';
08852                }
08853                /* Make sure extension exists (or in overlap dial mode, can exist) */
08854                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
08855                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08856                   /* Setup law */
08857                   int law;
08858                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
08859                      /* Set to audio mode at this point */
08860                      law = 1;
08861                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08862                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
08863                   }
08864                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
08865                      law = ZT_LAW_ALAW;
08866                   else
08867                      law = ZT_LAW_MULAW;
08868                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
08869                   if (res < 0) 
08870                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
08871                   res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
08872                   if (res < 0)
08873                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
08874                   if (e->ring.complete || !pri->overlapdial) {
08875                      /* Just announce proceeding */
08876                      pri->pvts[chanpos]->proceeding = 1;
08877                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
08878                   } else {
08879                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
08880                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08881                      else
08882                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08883                   }
08884                   /* Get the use_callingpres state */
08885                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
08886                
08887                   /* Start PBX */
08888                   if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08889                      /* Release the PRI lock while we create the channel */
08890                      ast_mutex_unlock(&pri->lock);
08891                      if (crv) {
08892                         /* Set bearer and such */
08893                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
08894                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08895                         pri->pvts[chanpos]->owner = &inuse;
08896                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
08897                      } else {
08898                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08899                      }
08900 
08901                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08902 
08903                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
08904                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
08905                      }
08906                      if (e->ring.ani2 >= 0) {
08907                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
08908                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08909                      }
08910 
08911 #ifdef SUPPORT_USERUSER
08912                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
08913                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08914                      }
08915 #endif
08916 
08917                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08918                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08919                      if (e->ring.redirectingreason >= 0)
08920                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08921                   
08922                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
08923                      ast_mutex_lock(&pri->lock);
08924 
08925                      pthread_attr_init(&attr);
08926                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08927                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
08928                         if (option_verbose > 2)
08929                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
08930                               plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
08931                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08932                      } else {
08933                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08934                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08935                         if (c)
08936                            ast_hangup(c);
08937                         else {
08938                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08939                            pri->pvts[chanpos]->call = NULL;
08940                         }
08941                      }
08942                      pthread_attr_destroy(&attr);
08943                   } else  {
08944                      ast_mutex_unlock(&pri->lock);
08945                      /* Release PRI lock while we create the channel */
08946                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
08947                      if (c) {
08948                         char calledtonstr[10];
08949 
08950                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08951 
08952                         if (e->ring.ani2 >= 0) {
08953                            snprintf(ani2str, 5, "%d", e->ring.ani2);
08954                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08955                         }
08956 
08957 #ifdef SUPPORT_USERUSER
08958                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
08959                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08960                         }
08961 #endif
08962 
08963                         if (e->ring.redirectingreason >= 0)
08964                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08965                      
08966                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08967                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08968 
08969                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
08970                         ast_mutex_lock(&pri->lock);
08971 
08972                         if (option_verbose > 2)
08973                            ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
08974                               plancallingnum, pri->pvts[chanpos]->exten, 
08975                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08976                         zt_enable_ec(pri->pvts[chanpos]);
08977                      } else {
08978 
08979                         ast_mutex_lock(&pri->lock);
08980 
08981                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08982                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08983                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08984                         pri->pvts[chanpos]->call = NULL;
08985                      }
08986                   }
08987                } else {
08988                   if (option_verbose > 2)
08989                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
08990                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
08991                            pri->pvts[chanpos]->prioffset, pri->span);
08992                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
08993                   pri->pvts[chanpos]->call = NULL;
08994                   pri->pvts[chanpos]->exten[0] = '\0';
08995                }
08996                if (crv)
08997                   ast_mutex_unlock(&crv->lock);
08998                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08999             } else {
09000                if (e->ring.flexible)
09001                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
09002                else
09003                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
09004             }
09005             break;
09006          case PRI_EVENT_RINGING:
09007             chanpos = pri_find_principle(pri, e->ringing.channel);
09008             if (chanpos < 0) {
09009                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
09010                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09011             } else {
09012                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
09013                if (chanpos < 0) {
09014                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
09015                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09016                } else {
09017                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09018                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09019                      zt_enable_ec(pri->pvts[chanpos]);
09020                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
09021                      pri->pvts[chanpos]->alerting = 1;
09022                   } else
09023                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
09024 #ifdef PRI_PROGRESS_MASK
09025                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09026 #else
09027                   if (e->ringing.progress == 8) {
09028 #endif
09029                      /* Now we can do call progress detection */
09030                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09031                         /* RINGING detection isn't required because we got ALERTING signal */
09032                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
09033                         pri->pvts[chanpos]->dsp_features = 0;
09034                      }
09035                   }
09036 
09037 #ifdef SUPPORT_USERUSER
09038                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
09039                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09040                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09041                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
09042                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09043                   }
09044 #endif
09045 
09046                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09047                }
09048             }
09049             break;
09050          case PRI_EVENT_PROGRESS:
09051             /* Get chan value if e->e is not PRI_EVNT_RINGING */
09052             chanpos = pri_find_principle(pri, e->proceeding.channel);
09053             if (chanpos > -1) {
09054 #ifdef PRI_PROGRESS_MASK
09055                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
09056 #else
09057                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
09058 #endif
09059                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
09060 
09061                   if (e->proceeding.cause > -1) {
09062                      if (option_verbose > 2)
09063                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
09064 
09065                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
09066                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
09067                         if (pri->pvts[chanpos]->owner) {
09068                            if (option_verbose > 2)
09069                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
09070 
09071                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
09072                            f.subclass = AST_CONTROL_BUSY;
09073                         }
09074                      }
09075                   }
09076                   
09077                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09078                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
09079                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09080                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09081 #ifdef PRI_PROGRESS_MASK
09082                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09083 #else
09084                   if (e->proceeding.progress == 8) {
09085 #endif
09086                      /* Now we can do call progress detection */
09087                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09088                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09089                         pri->pvts[chanpos]->dsp_features = 0;
09090                      }
09091                   }
09092                   pri->pvts[chanpos]->progress = 1;
09093                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09094                }
09095             }
09096             break;
09097          case PRI_EVENT_PROCEEDING:
09098             chanpos = pri_find_principle(pri, e->proceeding.channel);
09099             if (chanpos > -1) {
09100                if (!pri->pvts[chanpos]->proceeding) {
09101                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
09102                   
09103                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09104                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
09105                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09106                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09107 #ifdef PRI_PROGRESS_MASK
09108                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09109 #else
09110                   if (e->proceeding.progress == 8) {
09111 #endif
09112                      /* Now we can do call progress detection */
09113                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09114                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09115                         pri->pvts[chanpos]->dsp_features = 0;
09116                      }
09117                      /* Bring voice path up */
09118                      f.subclass = AST_CONTROL_PROGRESS;
09119                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
09120                   }
09121                   pri->pvts[chanpos]->proceeding = 1;
09122                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09123                }
09124             }
09125             break;
09126          case PRI_EVENT_FACNAME:
09127             chanpos = pri_find_principle(pri, e->facname.channel);
09128             if (chanpos < 0) {
09129                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09130                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09131             } else {
09132                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09133                if (chanpos < 0) {
09134                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09135                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09136                } else {
09137                   /* Re-use *69 field for PRI */
09138                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09139                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09140                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09141                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09142                   zt_enable_ec(pri->pvts[chanpos]);
09143                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09144                }
09145             }
09146             break;            
09147          case PRI_EVENT_ANSWER:
09148             chanpos = pri_find_principle(pri, e->answer.channel);
09149             if (chanpos < 0) {
09150                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09151                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09152             } else {
09153                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09154                if (chanpos < 0) {
09155                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09156                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09157                } else {
09158                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09159                   /* Now we can do call progress detection */
09160 
09161                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09162                    * By this time, we need DTMF detection and other features that were previously disabled
09163                    * -- Matt F */
09164                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09165                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09166                      pri->pvts[chanpos]->dsp_features = 0;
09167                   }
09168                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09169                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09170                      x = ZT_START;
09171                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09172                      if (res < 0) {
09173                         if (errno != EINPROGRESS) {
09174                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09175                         }
09176                      }
09177                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09178                      pri->pvts[chanpos]->dialing = 1;
09179                      /* Send any "w" waited stuff */
09180                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09181                      if (res < 0) {
09182                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09183                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09184                      } else 
09185                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
09186                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09187                   } else if (pri->pvts[chanpos]->confirmanswer) {
09188                      ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
09189                   } else {
09190                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
09191                      /* Enable echo cancellation if it's not on already */
09192                      zt_enable_ec(pri->pvts[chanpos]);
09193                   }
09194 
09195 #ifdef SUPPORT_USERUSER
09196                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
09197                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09198                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09199                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
09200                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09201                   }
09202 #endif
09203 
09204                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09205                }
09206             }
09207             break;            
09208          case PRI_EVENT_HANGUP:
09209             chanpos = pri_find_principle(pri, e->hangup.channel);
09210             if (chanpos < 0) {
09211                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
09212                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09213             } else {
09214                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09215                if (chanpos > -1) {
09216                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09217                   if (!pri->pvts[chanpos]->alreadyhungup) {
09218                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
09219                      pri->pvts[chanpos]->alreadyhungup = 1;
09220                      if (pri->pvts[chanpos]->realcall) 
09221                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09222                      else if (pri->pvts[chanpos]->owner) {
09223                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
09224                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09225                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09226                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09227                         else {
09228                            switch (e->hangup.cause) {
09229                               case PRI_CAUSE_USER_BUSY:
09230                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09231                                  break;
09232                               case PRI_CAUSE_CALL_REJECTED:
09233                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09234                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09235                               case PRI_CAUSE_SWITCH_CONGESTION:
09236                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09237                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09238                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09239                                  break;
09240                               default:
09241                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09242                            }
09243                         }
09244                      }
09245                      if (option_verbose > 2) 
09246                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
09247                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
09248                   } else {
09249                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09250                      pri->pvts[chanpos]->call = NULL;
09251                   }
09252                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09253                      if (option_verbose > 2)
09254                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
09255                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09256                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09257                      pri->pvts[chanpos]->resetting = 1;
09258                   }
09259                   if (e->hangup.aoc_units > -1)
09260                      if (option_verbose > 2)
09261                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09262                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09263 
09264 #ifdef SUPPORT_USERUSER
09265                   if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
09266                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09267                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09268                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09269                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09270                   }
09271 #endif
09272 
09273                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09274                } else {
09275                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
09276                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09277                }
09278             } 
09279             break;
09280 #ifndef PRI_EVENT_HANGUP_REQ
09281 #error please update libpri
09282 #endif
09283          case PRI_EVENT_HANGUP_REQ:
09284             chanpos = pri_find_principle(pri, e->hangup.channel);
09285             if (chanpos < 0) {
09286                ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
09287                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09288             } else {
09289                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09290                if (chanpos > -1) {
09291                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09292                   if (pri->pvts[chanpos]->realcall) 
09293                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09294                   else if (pri->pvts[chanpos]->owner) {
09295                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09296                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09297                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09298                      else {
09299                         switch (e->hangup.cause) {
09300                            case PRI_CAUSE_USER_BUSY:
09301                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09302                               break;
09303                            case PRI_CAUSE_CALL_REJECTED:
09304                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09305                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09306                            case PRI_CAUSE_SWITCH_CONGESTION:
09307                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09308                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09309                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09310                               break;
09311                            default:
09312                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09313                         }
09314                      }
09315                      if (option_verbose > 2) 
09316                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
09317                      if (e->hangup.aoc_units > -1)
09318                         if (option_verbose > 2)
09319                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09320                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09321                   } else {
09322                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09323                      pri->pvts[chanpos]->call = NULL;
09324                   }
09325                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09326                      if (option_verbose > 2)
09327                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
09328                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09329                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09330                      pri->pvts[chanpos]->resetting = 1;
09331                   }
09332 
09333 #ifdef SUPPORT_USERUSER
09334                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09335                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09336                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09337                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09338                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09339                   }
09340 #endif
09341 
09342                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09343                } else {
09344                   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);
09345                }
09346             } 
09347             break;
09348          case PRI_EVENT_HANGUP_ACK:
09349             chanpos = pri_find_principle(pri, e->hangup.channel);
09350             if (chanpos < 0) {
09351                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
09352                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09353             } else {
09354                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09355                if (chanpos > -1) {
09356                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09357                   pri->pvts[chanpos]->call = NULL;
09358                   pri->pvts[chanpos]->resetting = 0;
09359                   if (pri->pvts[chanpos]->owner) {
09360                      if (option_verbose > 2) 
09361                         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);
09362                   }
09363 
09364 #ifdef SUPPORT_USERUSER
09365                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09366                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09367                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09368                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09369                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09370                   }
09371 #endif
09372 
09373                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09374                }
09375             }
09376             break;
09377          case PRI_EVENT_CONFIG_ERR:
09378             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
09379             break;
09380          case PRI_EVENT_RESTART_ACK:
09381             chanpos = pri_find_principle(pri, e->restartack.channel);
09382             if (chanpos < 0) {
09383                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
09384                   channel number, so we have to figure it out...  This must be why
09385                   everybody resets exactly a channel at a time. */
09386                for (x = 0; x < pri->numchans; x++) {
09387                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
09388                      chanpos = x;
09389                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09390                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
09391                            pri->pvts[chanpos]->prioffset, pri->span);
09392                      if (pri->pvts[chanpos]->realcall) 
09393                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09394                      else if (pri->pvts[chanpos]->owner) {
09395                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
09396                            pri->pvts[chanpos]->prioffset, pri->span);
09397                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09398                      }
09399                      pri->pvts[chanpos]->resetting = 0;
09400                      if (option_verbose > 2)
09401                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09402                            pri->pvts[chanpos]->prioffset, pri->span);
09403                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09404                      if (pri->resetting)
09405                         pri_check_restart(pri);
09406                      break;
09407                   }
09408                }
09409                if (chanpos < 0) {
09410                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
09411                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09412                }
09413             } else {
09414                if (pri->pvts[chanpos]) {
09415                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09416                   if (pri->pvts[chanpos]->realcall) 
09417                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09418                   else if (pri->pvts[chanpos]->owner) {
09419                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
09420                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09421                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09422                   }
09423                   pri->pvts[chanpos]->resetting = 0;
09424                   if (option_verbose > 2)
09425                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09426                            pri->pvts[chanpos]->prioffset, pri->span);
09427                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09428                   if (pri->resetting)
09429                      pri_check_restart(pri);
09430                }
09431             }
09432             break;
09433          case PRI_EVENT_SETUP_ACK:
09434             chanpos = pri_find_principle(pri, e->setup_ack.channel);
09435             if (chanpos < 0) {
09436                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
09437                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
09438             } else {
09439                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
09440                if (chanpos > -1) {
09441                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09442                   pri->pvts[chanpos]->setup_ack = 1;
09443                   /* Send any queued digits */
09444                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
09445                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
09446                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
09447                         pri->pvts[chanpos]->dialdest[x]);
09448                   }
09449                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09450                } else
09451                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
09452             }
09453             break;
09454          case PRI_EVENT_NOTIFY:
09455             chanpos = pri_find_principle(pri, e->notify.channel);
09456             if (chanpos < 0) {
09457                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
09458                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
09459             } else {
09460                struct ast_frame f = { AST_FRAME_CONTROL, };
09461                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09462                switch (e->notify.info) {
09463                case PRI_NOTIFY_REMOTE_HOLD:
09464                   f.subclass = AST_CONTROL_HOLD;
09465                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09466                   break;
09467                case PRI_NOTIFY_REMOTE_RETRIEVAL:
09468                   f.subclass = AST_CONTROL_UNHOLD;
09469                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09470                   break;
09471                }
09472                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09473             }
09474             break;
09475          default:
09476             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
09477          }
09478       }  
09479       ast_mutex_unlock(&pri->lock);
09480    }
09481    /* Never reached */
09482    return NULL;
09483 }
09484 
09485 static int start_pri(struct zt_pri *pri)
09486 {
09487    int res, x;
09488    ZT_PARAMS p;
09489    ZT_BUFFERINFO bi;
09490    struct zt_spaninfo si;
09491    int i;
09492    
09493    for (i = 0; i < NUM_DCHANS; i++) {
09494       if (!pri->dchannels[i])
09495          break;
09496       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
09497       x = pri->dchannels[i];
09498       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
09499          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
09500          return -1;
09501       }
09502       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
09503       if (res) {
09504          zt_close(pri->fds[i]);
09505          pri->fds[i] = -1;
09506          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
09507          return -1;
09508       }
09509       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
09510          zt_close(pri->fds[i]);
09511          pri->fds[i] = -1;
09512          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
09513          return -1;
09514       }
09515       memset(&si, 0, sizeof(si));
09516       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
09517       if (res) {
09518          zt_close(pri->fds[i]);
09519          pri->fds[i] = -1;
09520          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
09521       }
09522       if (!si.alarms)
09523          pri->dchanavail[i] |= DCHAN_NOTINALARM;
09524       else
09525          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
09526       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
09527       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
09528       bi.numbufs = 32;
09529       bi.bufsize = 1024;
09530       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
09531          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
09532          zt_close(pri->fds[i]);
09533          pri->fds[i] = -1;
09534          return -1;
09535       }
09536       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
09537       /* Force overlap dial if we're doing GR-303! */
09538       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
09539          pri->overlapdial = 1;
09540       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
09541       /* Enslave to master if appropriate */
09542       if (i)
09543          pri_enslave(pri->dchans[0], pri->dchans[i]);
09544       if (!pri->dchans[i]) {
09545          zt_close(pri->fds[i]);
09546          pri->fds[i] = -1;
09547          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
09548          return -1;
09549       }
09550       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
09551       pri_set_nsf(pri->dchans[i], pri->nsf);
09552 #ifdef PRI_GETSET_TIMERS
09553       for (x = 0; x < PRI_MAX_TIMERS; x++) {
09554          if (pritimers[x] != 0)
09555             pri_set_timer(pri->dchans[i], x, pritimers[x]);
09556       }
09557 #endif
09558    }
09559    /* Assume primary is the one we use */
09560    pri->pri = pri->dchans[0];
09561    pri->resetpos = -1;
09562    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
09563       for (i = 0; i < NUM_DCHANS; i++) {
09564          if (!pri->dchannels[i])
09565             break;
09566          zt_close(pri->fds[i]);
09567          pri->fds[i] = -1;
09568       }
09569       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
09570       return -1;
09571    }
09572    return 0;
09573 }
09574 
09575 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
09576 {
09577    int which, span;
09578    char *ret = NULL;
09579 
09580    if (pos != rpos)
09581       return ret;
09582 
09583    for (which = span = 0; span < NUM_SPANS; span++) {
09584       if (pris[span].pri && ++which > state) {
09585          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
09586          break;
09587       }
09588    }
09589    return ret;
09590 }
09591 
09592 static char *complete_span_4(const char *line, const char *word, int pos, int state)
09593 {
09594    return complete_span_helper(line,word,pos,state,3);
09595 }
09596 
09597 static char *complete_span_5(const char *line, const char *word, int pos, int state)
09598 {
09599    return complete_span_helper(line,word,pos,state,4);
09600 }
09601 
09602 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
09603 {
09604    int myfd;
09605 
09606    if (!strncasecmp(argv[1], "set", 3)) {
09607       if (argc < 5) 
09608          return RESULT_SHOWUSAGE;
09609 
09610       if (ast_strlen_zero(argv[4]))
09611          return RESULT_SHOWUSAGE;
09612 
09613       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
09614       if (myfd < 0) {
09615          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
09616          return RESULT_SUCCESS;
09617       }
09618 
09619       ast_mutex_lock(&pridebugfdlock);
09620 
09621       if (pridebugfd >= 0)
09622          close(pridebugfd);
09623 
09624       pridebugfd = myfd;
09625       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
09626       
09627       ast_mutex_unlock(&pridebugfdlock);
09628 
09629       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
09630    } else {
09631       /* Assume it is unset */
09632       ast_mutex_lock(&pridebugfdlock);
09633       close(pridebugfd);
09634       pridebugfd = -1;
09635       ast_cli(fd, "PRI debug output to file disabled\n");
09636       ast_mutex_unlock(&pridebugfdlock);
09637    }
09638 
09639    return RESULT_SUCCESS;
09640 }
09641 
09642 #ifdef HAVE_PRI_VERSION
09643 static int handle_pri_version(int fd, int agc, char *argv[]) {
09644    ast_cli(fd, "libpri version: %s\n", pri_get_version());
09645    return RESULT_SUCCESS;
09646 }
09647 #endif
09648 
09649 static int handle_pri_debug(int fd, int argc, char *argv[])
09650 {
09651    int span;
09652    int x;
09653    if (argc < 4) {
09654       return RESULT_SHOWUSAGE;
09655    }
09656    span = atoi(argv[3]);
09657    if ((span < 1) || (span > NUM_SPANS)) {
09658       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
09659       return RESULT_SUCCESS;
09660    }
09661    if (!pris[span-1].pri) {
09662       ast_cli(fd, "No PRI running on span %d\n", span);
09663       return RESULT_SUCCESS;
09664    }
09665    for (x = 0; x < NUM_DCHANS; x++) {
09666       if (pris[span-1].dchans[x])
09667          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09668                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09669                                                PRI_DEBUG_Q921_STATE);
09670    }
09671    ast_cli(fd, "Enabled debugging on span %d\n", span);
09672    return RESULT_SUCCESS;
09673 }
09674 
09675 
09676 
09677 static int handle_pri_no_debug(int fd, int argc, char *argv[])
09678 {
09679    int span;
09680    int x;
09681    if (argc < 5)
09682       return RESULT_SHOWUSAGE;
09683    span = atoi(argv[4]);
09684    if ((span < 1) || (span > NUM_SPANS)) {
09685       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09686       return RESULT_SUCCESS;
09687    }
09688    if (!pris[span-1].pri) {
09689       ast_cli(fd, "No PRI running on span %d\n", span);
09690       return RESULT_SUCCESS;
09691    }
09692    for (x = 0; x < NUM_DCHANS; x++) {
09693       if (pris[span-1].dchans[x])
09694          pri_set_debug(pris[span-1].dchans[x], 0);
09695    }
09696    ast_cli(fd, "Disabled debugging on span %d\n", span);
09697    return RESULT_SUCCESS;
09698 }
09699 
09700 static int handle_pri_really_debug(int fd, int argc, char *argv[])
09701 {
09702    int span;
09703    int x;
09704    if (argc < 5)
09705       return RESULT_SHOWUSAGE;
09706    span = atoi(argv[4]);
09707    if ((span < 1) || (span > NUM_SPANS)) {
09708       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09709       return RESULT_SUCCESS;
09710    }
09711    if (!pris[span-1].pri) {
09712       ast_cli(fd, "No PRI running on span %d\n", span);
09713       return RESULT_SUCCESS;
09714    }
09715    for (x = 0; x < NUM_DCHANS; x++) {
09716       if (pris[span-1].dchans[x])
09717          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09718                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09719                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
09720    }
09721    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
09722    return RESULT_SUCCESS;
09723 }
09724 
09725 static void build_status(char *s, size_t len, int status, int active)
09726 {
09727    if (!s || len < 1) {
09728       return;
09729    }
09730    s[0] = '\0';
09731    if (status & DCHAN_PROVISIONED)
09732       strncat(s, "Provisioned, ", len - strlen(s) - 1);
09733    if (!(status & DCHAN_NOTINALARM))
09734       strncat(s, "In Alarm, ", len - strlen(s) - 1);
09735    if (status & DCHAN_UP)
09736       strncat(s, "Up", len - strlen(s) - 1);
09737    else
09738       strncat(s, "Down", len - strlen(s) - 1);
09739    if (active)
09740       strncat(s, ", Active", len - strlen(s) - 1);
09741    else
09742       strncat(s, ", Standby", len - strlen(s) - 1);
09743    s[len - 1] = '\0';
09744 }
09745 
09746 static int handle_pri_show_spans(int fd, int argc, char *argv[])
09747 {
09748    int span;
09749    int x;
09750    char status[256];
09751    if (argc != 3)
09752       return RESULT_SHOWUSAGE;
09753 
09754    for (span = 0; span < NUM_SPANS; span++) {
09755       if (pris[span].pri) {
09756          for (x = 0; x < NUM_DCHANS; x++) {
09757             if (pris[span].dchannels[x]) {
09758                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
09759                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
09760             }
09761          }
09762       }
09763    }
09764    return RESULT_SUCCESS;
09765 }
09766 
09767 static int handle_pri_show_span(int fd, int argc, char *argv[])
09768 {
09769    int span;
09770    int x;
09771    char status[256];
09772    if (argc < 4)
09773       return RESULT_SHOWUSAGE;
09774    span = atoi(argv[3]);
09775    if ((span < 1) || (span > NUM_SPANS)) {
09776       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
09777       return RESULT_SUCCESS;
09778    }
09779    if (!pris[span-1].pri) {
09780       ast_cli(fd, "No PRI running on span %d\n", span);
09781       return RESULT_SUCCESS;
09782    }
09783    for (x = 0; x < NUM_DCHANS; x++) {
09784       if (pris[span-1].dchannels[x]) {
09785 #ifdef PRI_DUMP_INFO_STR
09786          char *info_str = NULL;
09787 #endif
09788          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
09789          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
09790          ast_cli(fd, "Status: %s\n", status);
09791 #ifdef PRI_DUMP_INFO_STR
09792          info_str = pri_dump_info_str(pris[span-1].pri);
09793          if (info_str) {
09794             ast_cli(fd, "%s", info_str);
09795             free(info_str);
09796          }
09797 #else
09798          pri_dump_info(pris[span-1].pri);
09799 #endif
09800          ast_cli(fd, "\n");
09801       }
09802    }
09803    return RESULT_SUCCESS;
09804 }
09805 
09806 static int handle_pri_show_debug(int fd, int argc, char *argv[])
09807 {
09808    int x;
09809    int span;
09810    int count=0;
09811    int debug=0;
09812 
09813    for (span = 0; span < NUM_SPANS; span++) {
09814            if (pris[span].pri) {
09815          for (x = 0; x < NUM_DCHANS; x++) {
09816             debug = 0;
09817                if (pris[span].dchans[x]) {
09818                   debug = pri_get_debug(pris[span].dchans[x]);
09819                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" );
09820                count++;
09821             }
09822          }
09823       }
09824 
09825    }
09826    ast_mutex_lock(&pridebugfdlock);
09827    if (pridebugfd >= 0) 
09828       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
09829    ast_mutex_unlock(&pridebugfdlock);
09830        
09831    if (!count) 
09832       ast_cli(fd, "No debug set or no PRI running\n");
09833    return RESULT_SUCCESS;
09834 }
09835 
09836 static const char pri_debug_help[] = 
09837    "Usage: pri debug span <span>\n"
09838    "       Enables debugging on a given PRI span\n";
09839    
09840 static const char pri_no_debug_help[] = 
09841    "Usage: pri no debug span <span>\n"
09842    "       Disables debugging on a given PRI span\n";
09843 
09844 static const char pri_really_debug_help[] = 
09845    "Usage: pri intensive debug span <span>\n"
09846    "       Enables debugging down to the Q.921 level\n";
09847 
09848 static const char pri_show_span_help[] = 
09849    "Usage: pri show span <span>\n"
09850    "       Displays PRI Information on a given PRI span\n";
09851 
09852 static const char pri_show_spans_help[] = 
09853    "Usage: pri show spans\n"
09854    "       Displays PRI Information\n";
09855 
09856 static struct ast_cli_entry zap_pri_cli[] = {
09857    { { "pri", "debug", "span", NULL },
09858    handle_pri_debug, "Enables PRI debugging on a span",
09859    pri_debug_help, complete_span_4 },
09860 
09861    { { "pri", "no", "debug", "span", NULL },
09862    handle_pri_no_debug, "Disables PRI debugging on a span",
09863    pri_no_debug_help, complete_span_5 },
09864 
09865    { { "pri", "intense", "debug", "span", NULL },
09866    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
09867    pri_really_debug_help, complete_span_5 },
09868 
09869    { { "pri", "show", "spans", NULL },
09870    handle_pri_show_spans, "Displays PRI Information",
09871    pri_show_spans_help },
09872 
09873    { { "pri", "show", "span", NULL },
09874    handle_pri_show_span, "Displays PRI Information",
09875    pri_show_span_help, complete_span_4 },
09876 
09877    { { "pri", "show", "debug", NULL },
09878    handle_pri_show_debug, "Displays current PRI debug settings" },
09879 
09880    { { "pri", "set", "debug", "file", NULL },
09881    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
09882 
09883    { { "pri", "unset", "debug", "file", NULL },
09884    handle_pri_set_debug_file, "Ends PRI debug output to file" },
09885 
09886 #ifdef HAVE_PRI_VERSION
09887    { { "pri", "show", "version", NULL },
09888    handle_pri_version, "Displays version of libpri" },
09889 #endif
09890 };
09891 
09892 #endif /* HAVE_PRI */
09893 
09894 static int zap_destroy_channel(int fd, int argc, char **argv)
09895 {
09896    int channel;
09897    
09898    if (argc != 4)
09899       return RESULT_SHOWUSAGE;
09900    
09901    channel = atoi(argv[3]);
09902 
09903    return zap_destroy_channel_bynum(channel);
09904 }
09905 
09906 static int setup_zap(int reload);
09907 static int zap_restart(void)
09908 {
09909    if (option_verbose > 0)
09910       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09911    while (iflist) {
09912       if (option_debug)
09913          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09914       /* Also updates iflist: */
09915       destroy_channel(NULL, iflist, 1);
09916    }
09917    if (option_debug)
09918       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09919    if (setup_zap(0) != 0) {
09920       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09921       return 1;
09922    }
09923    return 0;
09924 }
09925 
09926 static int zap_restart_cmd(int fd, int argc, char **argv)
09927 {
09928    if (argc != 2) {
09929       return RESULT_SHOWUSAGE;
09930    }
09931 
09932    if (zap_restart() != 0)
09933       return RESULT_FAILURE;
09934    return RESULT_SUCCESS;
09935 }
09936 
09937 static int action_zaprestart(struct mansession *s, const struct message *m)
09938 {
09939    if (zap_restart() != 0) {
09940       astman_send_error(s, m, "Failed rereading zaptel configuration");
09941       return 1;
09942    }
09943    astman_send_ack(s, m, "ZapRestart: Success");
09944    return 0;
09945 }
09946 
09947 static int zap_show_channels(int fd, int argc, char **argv)
09948 {
09949 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09950 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09951    struct zt_pvt *tmp = NULL;
09952    char tmps[20] = "";
09953    ast_mutex_t *lock;
09954    struct zt_pvt *start;
09955 #ifdef HAVE_PRI
09956    int trunkgroup;
09957    struct zt_pri *pri = NULL;
09958    int x;
09959 #endif
09960 
09961    lock = &iflock;
09962    start = iflist;
09963 
09964 #ifdef HAVE_PRI
09965    if (argc == 4) {
09966       if ((trunkgroup = atoi(argv[3])) < 1)
09967          return RESULT_SHOWUSAGE;
09968       for (x = 0; x < NUM_SPANS; x++) {
09969          if (pris[x].trunkgroup == trunkgroup) {
09970             pri = pris + x;
09971             break;
09972          }
09973       }
09974       if (pri) {
09975          start = pri->crvs;
09976          lock = &pri->lock;
09977       } else {
09978          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09979          return RESULT_FAILURE;
09980       }
09981    } else
09982 #endif
09983    if (argc != 3)
09984       return RESULT_SHOWUSAGE;
09985 
09986    ast_mutex_lock(lock);
09987 #ifdef HAVE_PRI
09988    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
09989 #else
09990    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
09991 #endif   
09992    
09993    tmp = start;
09994    while (tmp) {
09995       if (tmp->channel > 0) {
09996          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09997       } else
09998          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09999       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
10000       tmp = tmp->next;
10001    }
10002    ast_mutex_unlock(lock);
10003    return RESULT_SUCCESS;
10004 #undef FORMAT
10005 #undef FORMAT2
10006 }
10007 
10008 static int zap_show_channel(int fd, int argc, char **argv)
10009 {
10010    int channel;
10011    struct zt_pvt *tmp = NULL;
10012    ZT_CONFINFO ci;
10013    ZT_PARAMS ps;
10014    int x;
10015    ast_mutex_t *lock;
10016    struct zt_pvt *start;
10017 #ifdef HAVE_PRI
10018    char *c;
10019    int trunkgroup;
10020    struct zt_pri *pri=NULL;
10021 #endif
10022 
10023    lock = &iflock;
10024    start = iflist;
10025 
10026    if (argc != 4)
10027       return RESULT_SHOWUSAGE;
10028 #ifdef HAVE_PRI
10029    if ((c = strchr(argv[3], ':'))) {
10030       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
10031          return RESULT_SHOWUSAGE;
10032       if ((trunkgroup < 1) || (channel < 1))
10033          return RESULT_SHOWUSAGE;
10034       for (x = 0; x < NUM_SPANS; x++) {
10035          if (pris[x].trunkgroup == trunkgroup) {
10036             pri = pris + x;
10037             break;
10038          }
10039       }
10040       if (pri) {
10041          start = pri->crvs;
10042          lock = &pri->lock;
10043       } else {
10044          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
10045          return RESULT_FAILURE;
10046       }
10047    } else
10048 #endif
10049       channel = atoi(argv[3]);
10050 
10051    ast_mutex_lock(lock);
10052    tmp = start;
10053    while (tmp) {
10054       if (tmp->channel == channel) {
10055 #ifdef HAVE_PRI
10056          if (pri) 
10057             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
10058          else
10059 #endif         
10060          ast_cli(fd, "Channel: %d\n", tmp->channel);
10061          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
10062          ast_cli(fd, "Span: %d\n", tmp->span);
10063          ast_cli(fd, "Extension: %s\n", tmp->exten);
10064          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
10065          ast_cli(fd, "Context: %s\n", tmp->context);
10066          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
10067          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
10068          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
10069          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
10070          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
10071          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
10072          ast_cli(fd, "Radio: %d\n", tmp->radio);
10073          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
10074          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)" : "");
10075          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)" : "");
10076          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)" : "");
10077          ast_cli(fd, "Confno: %d\n", tmp->confno);
10078          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
10079          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
10080          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
10081          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
10082          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
10083          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
10084          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
10085          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
10086          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
10087          if (tmp->master)
10088             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
10089          for (x = 0; x < MAX_SLAVES; x++) {
10090             if (tmp->slaves[x])
10091                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
10092          }
10093 #ifdef HAVE_PRI
10094          if (tmp->pri) {
10095             ast_cli(fd, "PRI Flags: ");
10096             if (tmp->resetting)
10097                ast_cli(fd, "Resetting ");
10098             if (tmp->call)
10099                ast_cli(fd, "Call ");
10100             if (tmp->bearer)
10101                ast_cli(fd, "Bearer ");
10102             ast_cli(fd, "\n");
10103             if (tmp->logicalspan) 
10104                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
10105             else
10106                ast_cli(fd, "PRI Logical Span: Implicit\n");
10107          }
10108             
10109 #endif
10110          memset(&ci, 0, sizeof(ci));
10111          ps.channo = tmp->channel;
10112          if (tmp->subs[SUB_REAL].zfd > -1) {
10113             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
10114                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
10115             }
10116 #ifdef ZT_GETCONFMUTE
10117             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
10118                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
10119             }
10120 #endif
10121             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
10122                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
10123             } else {
10124                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
10125             }
10126          }
10127          if (ISTRUNK(tmp)) {
10128             ast_cli(fd, "Call Progress: %s\n", tmp->callprogress ? "yes" : "no");  
10129             if (!ast_strlen_zero(progzone))
10130                ast_cli(fd, "Progress Zone: %s\n", progzone);
10131             ast_cli(fd, "Busy Detect: %s\n", tmp->busydetect ? "yes" : "no");  
10132             if(tmp->busydetect) {
10133                ast_cli(fd, "Busy Count: %d\n", tmp->busycount);
10134                if(tmp->busytonelength > 0) {
10135                   ast_cli(fd, "Busy Pattern:\n");
10136                   ast_cli(fd, " -- Tone Length: %6d ms\n", tmp->busytonelength);
10137                   if (tmp->busyquietlength > 0) 
10138                      ast_cli(fd, " -- Quiet Length: %6d ms\n", tmp->busyquietlength);
10139                   else 
10140                      ast_cli(fd, " -- Detect Tone Only\n");
10141                   if(tmp->busyfuzziness > 0)
10142                      ast_cli(fd, "Busy Pattern Fuziness: %d\n", tmp->busyfuzziness);
10143                }
10144             }
10145          }
10146          ast_mutex_unlock(lock);
10147          return RESULT_SUCCESS;
10148       }
10149       tmp = tmp->next;
10150    }
10151    
10152    ast_cli(fd, "Unable to find given channel %d\n", channel);
10153    ast_mutex_unlock(lock);
10154    return RESULT_FAILURE;
10155 }
10156 
10157 static char zap_show_cadences_help[] =
10158 "Usage: zap show cadences\n"
10159 "       Shows all cadences currently defined\n";
10160 
10161 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
10162 {
10163    int i, j;
10164    for (i = 0; i < num_cadence; i++) {
10165       char output[1024];
10166       char tmp[16], tmp2[64];
10167       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
10168       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
10169 
10170       for (j = 0; j < 16; j++) {
10171          if (cadences[i].ringcadence[j] == 0)
10172             break;
10173          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
10174          if (cidrings[i] * 2 - 1 == j)
10175             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
10176          else
10177             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
10178          if (j != 0)
10179             strncat(output, ",", sizeof(output) - strlen(output) - 1);
10180          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
10181       }
10182       ast_cli(fd,"%s\n",output);
10183    }
10184    return 0;
10185 }
10186 
10187 /* Based on irqmiss.c */
10188 static int zap_show_status(int fd, int argc, char *argv[]) {
10189    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
10190    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
10191 
10192    int span;
10193    int res;
10194    char alarms[50];
10195 
10196    int ctl;
10197    ZT_SPANINFO s;
10198 
10199    ctl = open("/dev/zap/ctl", O_RDWR);
10200    if (ctl < 0) {
10201       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
10202       ast_cli(fd, "No Zaptel interface found.\n");
10203       return RESULT_FAILURE;
10204    }
10205    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10206 
10207    for (span = 1; span < ZT_MAX_SPANS; ++span) {
10208       s.spanno = span;
10209       res = ioctl(ctl, ZT_SPANSTAT, &s);
10210       if (res) {
10211          continue;
10212       }
10213       alarms[0] = '\0';
10214       if (s.alarms > 0) {
10215          if (s.alarms & ZT_ALARM_BLUE)
10216             strcat(alarms, "BLU/");
10217          if (s.alarms & ZT_ALARM_YELLOW)
10218             strcat(alarms, "YEL/");
10219          if (s.alarms & ZT_ALARM_RED)
10220             strcat(alarms, "RED/");
10221          if (s.alarms & ZT_ALARM_LOOPBACK)
10222             strcat(alarms, "LB/");
10223          if (s.alarms & ZT_ALARM_RECOVER)
10224             strcat(alarms, "REC/");
10225          if (s.alarms & ZT_ALARM_NOTOPEN)
10226             strcat(alarms, "NOP/");
10227          if (!strlen(alarms))
10228             strcat(alarms, "UUU/");
10229          if (strlen(alarms)) {
10230             /* Strip trailing / */
10231             alarms[strlen(alarms) - 1] = '\0';
10232          }
10233       } else {
10234          if (s.numchans)
10235             strcpy(alarms, "OK");
10236          else
10237             strcpy(alarms, "UNCONFIGURED");
10238       }
10239 
10240       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
10241    }
10242    close(ctl);
10243 
10244    return RESULT_SUCCESS;
10245 #undef FORMAT
10246 #undef FORMAT2
10247 }
10248 
10249 static char show_channels_usage[] =
10250    "Usage: zap show channels\n"
10251    "  Shows a list of available channels\n";
10252 
10253 static char show_channel_usage[] =
10254    "Usage: zap show channel <chan num>\n"
10255    "  Detailed information about a given channel\n";
10256 
10257 static char zap_show_status_usage[] =
10258    "Usage: zap show status\n"
10259    "       Shows a list of Zaptel cards with status\n";
10260 
10261 static char destroy_channel_usage[] =
10262    "Usage: zap destroy channel <chan num>\n"
10263    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
10264 
10265 static char zap_restart_usage[] =
10266    "Usage: zap restart\n"
10267    "  Restarts the zaptel channels: destroys them all and then\n"
10268    "  re-reads them from zapata.conf.\n"
10269    "  Note that this will STOP any running CALL on zaptel channels.\n"
10270    "";
10271 
10272 static struct ast_cli_entry zap_cli[] = {
10273    { { "zap", "show", "cadences", NULL },
10274    handle_zap_show_cadences, "List cadences",
10275    zap_show_cadences_help },
10276 
10277    { { "zap", "show", "channels", NULL},
10278    zap_show_channels, "Show active zapata channels",
10279    show_channels_usage },
10280 
10281    { { "zap", "show", "channel", NULL},
10282    zap_show_channel, "Show information on a channel",
10283    show_channel_usage },
10284 
10285    { { "zap", "destroy", "channel", NULL},
10286    zap_destroy_channel, "Destroy a channel",
10287    destroy_channel_usage },
10288 
10289    { { "zap", "restart", NULL},
10290    zap_restart_cmd, "Fully restart zaptel channels",
10291    zap_restart_usage },
10292 
10293    { { "zap", "show", "status", NULL},
10294    zap_show_status, "Show all Zaptel cards status",
10295    zap_show_status_usage },
10296 };
10297 
10298 #define TRANSFER  0
10299 #define HANGUP    1
10300 
10301 static int zap_fake_event(struct zt_pvt *p, int mode)
10302 {
10303    if (p) {
10304       switch (mode) {
10305          case TRANSFER:
10306             p->fake_event = ZT_EVENT_WINKFLASH;
10307             break;
10308          case HANGUP:
10309             p->fake_event = ZT_EVENT_ONHOOK;
10310             break;
10311          default:
10312             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10313       }
10314    }
10315    return 0;
10316 }
10317 static struct zt_pvt *find_channel(int channel)
10318 {
10319    struct zt_pvt *p = iflist;
10320    while (p) {
10321       if (p->channel == channel) {
10322          break;
10323       }
10324       p = p->next;
10325    }
10326    return p;
10327 }
10328 
10329 static int action_zapdndon(struct mansession *s, const struct message *m)
10330 {
10331    struct zt_pvt *p = NULL;
10332    const char *channel = astman_get_header(m, "ZapChannel");
10333 
10334    if (ast_strlen_zero(channel)) {
10335       astman_send_error(s, m, "No channel specified");
10336       return 0;
10337    }
10338    p = find_channel(atoi(channel));
10339    if (!p) {
10340       astman_send_error(s, m, "No such channel");
10341       return 0;
10342    }
10343    p->dnd = 1;
10344    astman_send_ack(s, m, "DND Enabled");
10345    return 0;
10346 }
10347 
10348 static int action_zapdndoff(struct mansession *s, const struct message *m)
10349 {
10350    struct zt_pvt *p = NULL;
10351    const char *channel = astman_get_header(m, "ZapChannel");
10352 
10353    if (ast_strlen_zero(channel)) {
10354       astman_send_error(s, m, "No channel specified");
10355       return 0;
10356    }
10357    p = find_channel(atoi(channel));
10358    if (!p) {
10359       astman_send_error(s, m, "No such channel");
10360       return 0;
10361    }
10362    p->dnd = 0;
10363    astman_send_ack(s, m, "DND Disabled");
10364    return 0;
10365 }
10366 
10367 static int action_transfer(struct mansession *s, const struct message *m)
10368 {
10369    struct zt_pvt *p = NULL;
10370    const char *channel = astman_get_header(m, "ZapChannel");
10371 
10372    if (ast_strlen_zero(channel)) {
10373       astman_send_error(s, m, "No channel specified");
10374       return 0;
10375    }
10376    p = find_channel(atoi(channel));
10377    if (!p) {
10378       astman_send_error(s, m, "No such channel");
10379       return 0;
10380    }
10381    zap_fake_event(p,TRANSFER);
10382    astman_send_ack(s, m, "ZapTransfer");
10383    return 0;
10384 }
10385 
10386 static int action_transferhangup(struct mansession *s, const struct message *m)
10387 {
10388    struct zt_pvt *p = NULL;
10389    const char *channel = astman_get_header(m, "ZapChannel");
10390 
10391    if (ast_strlen_zero(channel)) {
10392       astman_send_error(s, m, "No channel specified");
10393       return 0;
10394    }
10395    p = find_channel(atoi(channel));
10396    if (!p) {
10397       astman_send_error(s, m, "No such channel");
10398       return 0;
10399    }
10400    zap_fake_event(p,HANGUP);
10401    astman_send_ack(s, m, "ZapHangup");
10402    return 0;
10403 }
10404 
10405 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
10406 {
10407    struct zt_pvt *p = NULL;
10408    const char *channel = astman_get_header(m, "ZapChannel");
10409    const char *number = astman_get_header(m, "Number");
10410    int i;
10411 
10412    if (ast_strlen_zero(channel)) {
10413       astman_send_error(s, m, "No channel specified");
10414       return 0;
10415    }
10416    if (ast_strlen_zero(number)) {
10417       astman_send_error(s, m, "No number specified");
10418       return 0;
10419    }
10420    p = find_channel(atoi(channel));
10421    if (!p) {
10422       astman_send_error(s, m, "No such channel");
10423       return 0;
10424    }
10425    if (!p->owner) {
10426       astman_send_error(s, m, "Channel does not have it's owner");
10427       return 0;
10428    }
10429    for (i = 0; i < strlen(number); i++) {
10430       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10431       zap_queue_frame(p, &f, NULL); 
10432    }
10433    astman_send_ack(s, m, "ZapDialOffhook");
10434    return 0;
10435 }
10436 
10437 static int action_zapshowchannels(struct mansession *s, const struct message *m)
10438 {
10439    struct zt_pvt *tmp = NULL;
10440    const char *id = astman_get_header(m, "ActionID");
10441    char idText[256] = "";
10442 
10443    astman_send_ack(s, m, "Zapata channel status will follow");
10444    if (!ast_strlen_zero(id))
10445       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10446 
10447    ast_mutex_lock(&iflock);
10448    
10449    tmp = iflist;
10450    while (tmp) {
10451       if (tmp->channel > 0) {
10452          int alarm = get_alarms(tmp);
10453          astman_append(s,
10454             "Event: ZapShowChannels\r\n"
10455             "Channel: %d\r\n"
10456             "Signalling: %s\r\n"
10457             "Context: %s\r\n"
10458             "DND: %s\r\n"
10459             "Alarm: %s\r\n"
10460             "%s"
10461             "\r\n",
10462             tmp->channel, sig2str(tmp->sig), tmp->context, 
10463             tmp->dnd ? "Enabled" : "Disabled",
10464             alarm2str(alarm), idText);
10465       } 
10466 
10467       tmp = tmp->next;
10468    }
10469 
10470    ast_mutex_unlock(&iflock);
10471    
10472    astman_append(s, 
10473       "Event: ZapShowChannelsComplete\r\n"
10474       "%s"
10475       "\r\n", 
10476       idText);
10477    return 0;
10478 }
10479 
10480 static int __unload_module(void)
10481 {
10482    int x;
10483    struct zt_pvt *p, *pl;
10484 
10485 #ifdef HAVE_PRI
10486    int i;
10487    for (i = 0; i < NUM_SPANS; i++) {
10488       if (pris[i].master != AST_PTHREADT_NULL) 
10489          pthread_cancel(pris[i].master);
10490    }
10491    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
10492    ast_unregister_application(zap_send_keypad_facility_app);
10493 #endif
10494    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
10495    ast_manager_unregister( "ZapDialOffhook" );
10496    ast_manager_unregister( "ZapHangup" );
10497    ast_manager_unregister( "ZapTransfer" );
10498    ast_manager_unregister( "ZapDNDoff" );
10499    ast_manager_unregister( "ZapDNDon" );
10500    ast_manager_unregister("ZapShowChannels");
10501    ast_manager_unregister("ZapRestart");
10502    ast_channel_unregister(&zap_tech);
10503    ast_mutex_lock(&iflock);
10504    /* Hangup all interfaces if they have an owner */
10505    p = iflist;
10506    while (p) {
10507       if (p->owner)
10508          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10509       p = p->next;
10510    }
10511    ast_mutex_unlock(&iflock);
10512    ast_mutex_lock(&monlock);
10513    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10514       pthread_cancel(monitor_thread);
10515       pthread_kill(monitor_thread, SIGURG);
10516       pthread_join(monitor_thread, NULL);
10517    }
10518    monitor_thread = AST_PTHREADT_STOP;
10519    ast_mutex_unlock(&monlock);
10520 
10521    ast_mutex_lock(&iflock);
10522    /* Destroy all the interfaces and free their memory */
10523    p = iflist;
10524    while (p) {
10525       /* Free any callerid */
10526       if (p->cidspill)
10527          free(p->cidspill);
10528       /* Close the zapata thingy */
10529       if (p->subs[SUB_REAL].zfd > -1)
10530          zt_close(p->subs[SUB_REAL].zfd);
10531       pl = p;
10532       p = p->next;
10533       x = pl->channel;
10534       /* Free associated memory */
10535       if (pl)
10536          destroy_zt_pvt(&pl);
10537       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10538    }
10539    iflist = NULL;
10540    ifcount = 0;
10541    ast_mutex_unlock(&iflock);
10542 #ifdef HAVE_PRI      
10543    for (i = 0; i < NUM_SPANS; i++) {
10544       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10545          pthread_join(pris[i].master, NULL);
10546       zt_close(pris[i].fds[i]);
10547    }
10548 #endif
10549    return 0;
10550 }
10551 
10552 static int unload_module(void)
10553 {
10554 #ifdef HAVE_PRI      
10555    int y;
10556    for (y = 0; y < NUM_SPANS; y++)
10557       ast_mutex_destroy(&pris[y].lock);
10558 #endif
10559    return __unload_module();
10560 }
10561 
10562 static int build_channels(struct zt_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
10563 {
10564    char *c, *chan;
10565    int x, start, finish;
10566    struct zt_pvt *tmp;
10567 #ifdef HAVE_PRI
10568    struct zt_pri *pri;
10569    int trunkgroup, y;
10570 #endif
10571    
10572    if ((reload == 0) && (conf->chan.sig < 0)) {
10573       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10574       return -1;
10575    }
10576 
10577    c = ast_strdupa(value);
10578 
10579 #ifdef HAVE_PRI
10580    pri = NULL;
10581    if (iscrv) {
10582       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10583          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
10584          return -1;
10585       }
10586       if (trunkgroup < 1) {
10587          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
10588          return -1;
10589       }
10590       c += y;
10591       for (y = 0; y < NUM_SPANS; y++) {
10592          if (pris[y].trunkgroup == trunkgroup) {
10593             pri = pris + y;
10594             break;
10595          }
10596       }
10597       if (!pri) {
10598          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
10599          return -1;
10600       }
10601    }
10602 #endif         
10603 
10604    while ((chan = strsep(&c, ","))) {
10605       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10606          /* Range */
10607       } else if (sscanf(chan, "%d", &start)) {
10608          /* Just one */
10609          finish = start;
10610       } else if (!strcasecmp(chan, "pseudo")) {
10611          finish = start = CHAN_PSEUDO;
10612          if (found_pseudo)
10613             *found_pseudo = 1;
10614       } else {
10615          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
10616          return -1;
10617       }
10618       if (finish < start) {
10619          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10620          x = finish;
10621          finish = start;
10622          start = x;
10623       }
10624 
10625       for (x = start; x <= finish; x++) {
10626 #ifdef HAVE_PRI
10627          tmp = mkintf(x, conf, pri, reload);
10628 #else       
10629          tmp = mkintf(x, conf, NULL, reload);
10630 #endif         
10631 
10632          if (tmp) {
10633             if (option_verbose > 2) {
10634 #ifdef HAVE_PRI
10635                if (pri)
10636                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
10637                else
10638 #endif
10639                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10640             }
10641          } else {
10642             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
10643                (reload == 1) ? "reconfigure" : "register", value);
10644             return -1;
10645          }
10646       }
10647    }
10648 
10649    return 0;
10650 }
10651 
10652 /** The length of the parameters list of 'zapchan'. 
10653  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10654 #define MAX_CHANLIST_LEN 80
10655 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
10656 {
10657    struct zt_pvt *tmp;
10658    char *ringc; /* temporary string for parsing the dring number. */
10659    int y;
10660    int found_pseudo = 0;
10661         char zapchan[MAX_CHANLIST_LEN] = {};
10662 
10663    for (; v; v = v->next) {
10664       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
10665          continue;
10666 
10667       /* Create the interface list */
10668       if (!strcasecmp(v->name, "channel")
10669 #ifdef HAVE_PRI
10670           || !strcasecmp(v->name, "crv")
10671 #endif         
10672          ) {
10673          int iscrv;
10674          if (skipchannels)
10675             continue;
10676          iscrv = !strcasecmp(v->name, "crv");
10677          if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
10678                return -1;
10679       } else if (!strcasecmp(v->name, "zapchan")) {
10680          ast_copy_string(zapchan, v->value, sizeof(zapchan));
10681       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10682          if (ast_true(v->value))
10683             confp->chan.usedistinctiveringdetection = 1;
10684       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
10685          if (ast_true(v->value))
10686             distinctiveringaftercid = 1;
10687       } else if (!strcasecmp(v->name, "dring1context")) {
10688          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
10689       } else if (!strcasecmp(v->name, "dring2context")) {
10690          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
10691       } else if (!strcasecmp(v->name, "dring3context")) {
10692          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
10693       } else if (!strcasecmp(v->name, "dring1")) {
10694          ringc = v->value;
10695          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10696       } else if (!strcasecmp(v->name, "dring2")) {
10697          ringc = v->value;
10698          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10699       } else if (!strcasecmp(v->name, "dring3")) {
10700          ringc = v->value;
10701          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10702       } else if (!strcasecmp(v->name, "usecallerid")) {
10703          confp->chan.use_callerid = ast_true(v->value);
10704       } else if (!strcasecmp(v->name, "cidsignalling")) {
10705          if (!strcasecmp(v->value, "bell"))
10706             confp->chan.cid_signalling = CID_SIG_BELL;
10707          else if (!strcasecmp(v->value, "v23"))
10708             confp->chan.cid_signalling = CID_SIG_V23;
10709          else if (!strcasecmp(v->value, "dtmf"))
10710             confp->chan.cid_signalling = CID_SIG_DTMF;
10711          else if (!strcasecmp(v->value, "smdi"))
10712             confp->chan.cid_signalling = CID_SIG_SMDI;
10713          else if (!strcasecmp(v->value, "v23_jp"))
10714             confp->chan.cid_signalling = CID_SIG_V23_JP;
10715          else if (ast_true(v->value))
10716             confp->chan.cid_signalling = CID_SIG_BELL;
10717       } else if (!strcasecmp(v->name, "cidstart")) {
10718          if (!strcasecmp(v->value, "ring"))
10719             confp->chan.cid_start = CID_START_RING;
10720          else if (!strcasecmp(v->value, "polarity"))
10721             confp->chan.cid_start = CID_START_POLARITY;
10722          else if (ast_true(v->value))
10723             confp->chan.cid_start = CID_START_RING;
10724       } else if (!strcasecmp(v->name, "threewaycalling")) {
10725          confp->chan.threewaycalling = ast_true(v->value);
10726       } else if (!strcasecmp(v->name, "cancallforward")) {
10727          confp->chan.cancallforward = ast_true(v->value);
10728       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10729          if (ast_true(v->value)) 
10730             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
10731          else
10732             confp->chan.dtmfrelax = 0;
10733       } else if (!strcasecmp(v->name, "mailbox")) {
10734          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
10735       } else if (!strcasecmp(v->name, "adsi")) {
10736          confp->chan.adsi = ast_true(v->value);
10737       } else if (!strcasecmp(v->name, "usesmdi")) {
10738          confp->chan.use_smdi = ast_true(v->value);
10739       } else if (!strcasecmp(v->name, "smdiport")) {
10740          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
10741       } else if (!strcasecmp(v->name, "transfer")) {
10742          confp->chan.transfer = ast_true(v->value);
10743       } else if (!strcasecmp(v->name, "canpark")) {
10744          confp->chan.canpark = ast_true(v->value);
10745       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10746          confp->chan.echocanbridged = ast_true(v->value);
10747       } else if (!strcasecmp(v->name, "busydetect")) {
10748          confp->chan.busydetect = ast_true(v->value);
10749       } else if (!strcasecmp(v->name, "busycount")) {
10750          confp->chan.busycount = atoi(v->value);
10751       } else if (!strcasecmp(v->name, "silencethreshold")) {
10752          confp->chan.silencethreshold = atoi(v->value);
10753       } else if (!strcasecmp(v->name, "busycompare")) {
10754          confp->chan.busycompare = ast_true(v->value);
10755       } else if (!strcasecmp(v->name, "busypattern")) {
10756          int count = sscanf(v->value, "%d,%d", &confp->chan.busytonelength, &confp->chan.busyquietlength);
10757          if (count == 1)
10758             confp->chan.busyquietlength = 0;
10759          else if (count < 1)
10760             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength[,quietlength]\n");
10761       } else if (!strcasecmp(v->name, "busyfuzziness")) {
10762          confp->chan.busyfuzziness = atoi(v->value);
10763       } else if (!strcasecmp(v->name, "callprogress")) {
10764          if (ast_true(v->value))
10765             confp->chan.callprogress |= 1;
10766          else
10767             confp->chan.callprogress &= ~1;
10768       } else if (!strcasecmp(v->name, "faxdetect")) {
10769          if (!strcasecmp(v->value, "incoming")) {
10770             confp->chan.callprogress |= 4;
10771             confp->chan.callprogress &= ~2;
10772          } else if (!strcasecmp(v->value, "outgoing")) {
10773             confp->chan.callprogress &= ~4;
10774             confp->chan.callprogress |= 2;
10775          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10776             confp->chan.callprogress |= 6;
10777          else
10778             confp->chan.callprogress &= ~6;
10779       } else if (!strcasecmp(v->name, "echocancel")) {
10780          if (!ast_strlen_zero(v->value)) {
10781             y = atoi(v->value);
10782          } else
10783             y = 0;
10784          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
10785             confp->chan.echocancel = y;
10786          else {
10787             confp->chan.echocancel = ast_true(v->value);
10788             if (confp->chan.echocancel)
10789                confp->chan.echocancel=128;
10790          }
10791       } else if (!strcasecmp(v->name, "echotraining")) {
10792          if (sscanf(v->value, "%d", &y) == 1) {
10793             if ((y < 10) || (y > 4000)) {
10794                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
10795             } else {
10796                confp->chan.echotraining = y;
10797             }
10798          } else if (ast_true(v->value)) {
10799             confp->chan.echotraining = 400;
10800          } else
10801             confp->chan.echotraining = 0;
10802       } else if (!strcasecmp(v->name, "hidecallerid")) {
10803          confp->chan.hidecallerid = ast_true(v->value);
10804       } else if (!strcasecmp(v->name, "hidecalleridname")) {
10805          confp->chan.hidecalleridname = ast_true(v->value);
10806       } else if (!strcasecmp(v->name, "pulsedial")) {
10807          confp->chan.pulse = ast_true(v->value);
10808       } else if (!strcasecmp(v->name, "callreturn")) {
10809          confp->chan.callreturn = ast_true(v->value);
10810       } else if (!strcasecmp(v->name, "callwaiting")) {
10811          confp->chan.callwaiting = ast_true(v->value);
10812       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10813          confp->chan.callwaitingcallerid = ast_true(v->value);
10814       } else if (!strcasecmp(v->name, "context")) {
10815          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
10816       } else if (!strcasecmp(v->name, "language")) {
10817          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
10818       } else if (!strcasecmp(v->name, "progzone")) {
10819          ast_copy_string(progzone, v->value, sizeof(progzone));
10820       } else if (!strcasecmp(v->name, "mohinterpret") 
10821          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
10822          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
10823       } else if (!strcasecmp(v->name, "mohsuggest")) {
10824          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
10825       } else if (!strcasecmp(v->name, "stripmsd")) {
10826          confp->chan.stripmsd = atoi(v->value);
10827       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10828          numbufs = atoi(v->value);
10829       } else if (!strcasecmp(v->name, "group")) {
10830          confp->chan.group = ast_get_group(v->value);
10831       } else if (!strcasecmp(v->name, "callgroup")) {
10832          confp->chan.callgroup = ast_get_group(v->value);
10833       } else if (!strcasecmp(v->name, "pickupgroup")) {
10834          confp->chan.pickupgroup = ast_get_group(v->value);
10835       } else if (!strcasecmp(v->name, "immediate")) {
10836          confp->chan.immediate = ast_true(v->value);
10837       } else if (!strcasecmp(v->name, "transfertobusy")) {
10838          confp->chan.transfertobusy = ast_true(v->value);
10839       } else if (!strcasecmp(v->name, "rxgain")) {
10840          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
10841             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10842          }
10843       } else if (!strcasecmp(v->name, "txgain")) {
10844          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
10845             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10846          }
10847       } else if (!strcasecmp(v->name, "tonezone")) {
10848          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
10849             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10850          }
10851       } else if (!strcasecmp(v->name, "callerid")) {
10852          if (!strcasecmp(v->value, "asreceived")) {
10853             confp->chan.cid_num[0] = '\0';
10854             confp->chan.cid_name[0] = '\0';
10855          } else {
10856             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
10857          } 
10858       } else if (!strcasecmp(v->name, "fullname")) {
10859          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
10860       } else if (!strcasecmp(v->name, "cid_number")) {
10861          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
10862       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10863          confp->chan.zaptrcallerid = ast_true(v->value);
10864       } else if (!strcasecmp(v->name, "restrictcid")) {
10865          confp->chan.restrictcid = ast_true(v->value);
10866       } else if (!strcasecmp(v->name, "usecallingpres")) {
10867          confp->chan.use_callingpres = ast_true(v->value);
10868       } else if (!strcasecmp(v->name, "accountcode")) {
10869          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
10870       } else if (!strcasecmp(v->name, "amaflags")) {
10871          y = ast_cdr_amaflags2int(v->value);
10872          if (y < 0) 
10873             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10874          else
10875             confp->chan.amaflags = y;
10876       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
10877          confp->chan.polarityonanswerdelay = atoi(v->value);
10878       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
10879          confp->chan.answeronpolarityswitch = ast_true(v->value);
10880       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
10881          confp->chan.hanguponpolarityswitch = ast_true(v->value);
10882       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
10883          confp->chan.sendcalleridafter = atoi(v->value);
10884       } else if (!reload){ 
10885           if (!strcasecmp(v->name, "signalling")) {
10886             confp->chan.outsigmod = -1;
10887             if (!strcasecmp(v->value, "em")) {
10888                confp->chan.sig = SIG_EM;
10889             } else if (!strcasecmp(v->value, "em_e1")) {
10890                confp->chan.sig = SIG_EM_E1;
10891             } else if (!strcasecmp(v->value, "em_w")) {
10892                confp->chan.sig = SIG_EMWINK;
10893                confp->chan.radio = 0;
10894             } else if (!strcasecmp(v->value, "fxs_ls")) {
10895                confp->chan.sig = SIG_FXSLS;
10896                confp->chan.radio = 0;
10897             } else if (!strcasecmp(v->value, "fxs_gs")) {
10898                confp->chan.sig = SIG_FXSGS;
10899                confp->chan.radio = 0;
10900             } else if (!strcasecmp(v->value, "fxs_ks")) {
10901                confp->chan.sig = SIG_FXSKS;
10902                confp->chan.radio = 0;
10903             } else if (!strcasecmp(v->value, "fxo_ls")) {
10904                confp->chan.sig = SIG_FXOLS;
10905                confp->chan.radio = 0;
10906             } else if (!strcasecmp(v->value, "fxo_gs")) {
10907                confp->chan.sig = SIG_FXOGS;
10908                confp->chan.radio = 0;
10909             } else if (!strcasecmp(v->value, "fxo_ks")) {
10910                confp->chan.sig = SIG_FXOKS;
10911                confp->chan.radio = 0;
10912             } else if (!strcasecmp(v->value, "fxs_rx")) {
10913                confp->chan.sig = SIG_FXSKS;
10914                confp->chan.radio = 1;
10915             } else if (!strcasecmp(v->value, "fxo_rx")) {
10916                confp->chan.sig = SIG_FXOLS;
10917                confp->chan.radio = 1;
10918             } else if (!strcasecmp(v->value, "fxs_tx")) {
10919                confp->chan.sig = SIG_FXSLS;
10920                confp->chan.radio = 1;
10921             } else if (!strcasecmp(v->value, "fxo_tx")) {
10922                confp->chan.sig = SIG_FXOGS;
10923                confp->chan.radio = 1;
10924             } else if (!strcasecmp(v->value, "em_rx")) {
10925                confp->chan.sig = SIG_EM;
10926                confp->chan.radio = 1;
10927             } else if (!strcasecmp(v->value, "em_tx")) {
10928                confp->chan.sig = SIG_EM;
10929                confp->chan.radio = 1;
10930             } else if (!strcasecmp(v->value, "em_rxtx")) {
10931                confp->chan.sig = SIG_EM;
10932                confp->chan.radio = 2;
10933             } else if (!strcasecmp(v->value, "em_txrx")) {
10934                confp->chan.sig = SIG_EM;
10935                confp->chan.radio = 2;
10936             } else if (!strcasecmp(v->value, "sf")) {
10937                confp->chan.sig = SIG_SF;
10938                confp->chan.radio = 0;
10939             } else if (!strcasecmp(v->value, "sf_w")) {
10940                confp->chan.sig = SIG_SFWINK;
10941                confp->chan.radio = 0;
10942             } else if (!strcasecmp(v->value, "sf_featd")) {
10943                confp->chan.sig = SIG_FEATD;
10944                confp->chan.radio = 0;
10945             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10946                confp->chan.sig = SIG_FEATDMF;
10947                confp->chan.radio = 0;
10948             } else if (!strcasecmp(v->value, "sf_featb")) {
10949                confp->chan.sig = SIG_SF_FEATB;
10950                confp->chan.radio = 0;
10951             } else if (!strcasecmp(v->value, "sf")) {
10952                confp->chan.sig = SIG_SF;
10953                confp->chan.radio = 0;
10954             } else if (!strcasecmp(v->value, "sf_rx")) {
10955                confp->chan.sig = SIG_SF;
10956                confp->chan.radio = 1;
10957             } else if (!strcasecmp(v->value, "sf_tx")) {
10958                confp->chan.sig = SIG_SF;
10959                confp->chan.radio = 1;
10960             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10961                confp->chan.sig = SIG_SF;
10962                confp->chan.radio = 2;
10963             } else if (!strcasecmp(v->value, "sf_txrx")) {
10964                confp->chan.sig = SIG_SF;
10965                confp->chan.radio = 2;
10966             } else if (!strcasecmp(v->value, "featd")) {
10967                confp->chan.sig = SIG_FEATD;
10968                confp->chan.radio = 0;
10969             } else if (!strcasecmp(v->value, "featdmf")) {
10970                confp->chan.sig = SIG_FEATDMF;
10971                confp->chan.radio = 0;
10972             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10973                confp->chan.sig = SIG_FEATDMF_TA;
10974                confp->chan.radio = 0;
10975             } else if (!strcasecmp(v->value, "e911")) {
10976                confp->chan.sig = SIG_E911;
10977                confp->chan.radio = 0;
10978             } else if (!strcasecmp(v->value, "fgccama")) {
10979                confp->chan.sig = SIG_FGC_CAMA;
10980                confp->chan.radio = 0;
10981             } else if (!strcasecmp(v->value, "fgccamamf")) {
10982                confp->chan.sig = SIG_FGC_CAMAMF;
10983                confp->chan.radio = 0;
10984             } else if (!strcasecmp(v->value, "featb")) {
10985                confp->chan.sig = SIG_FEATB;
10986                confp->chan.radio = 0;
10987 #ifdef HAVE_PRI
10988             } else if (!strcasecmp(v->value, "pri_net")) {
10989                confp->chan.radio = 0;
10990                confp->chan.sig = SIG_PRI;
10991                confp->pri.nodetype = PRI_NETWORK;
10992             } else if (!strcasecmp(v->value, "pri_cpe")) {
10993                confp->chan.sig = SIG_PRI;
10994                confp->chan.radio = 0;
10995                confp->pri.nodetype = PRI_CPE;
10996             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10997                confp->chan.sig = SIG_GR303FXOKS;
10998                confp->chan.radio = 0;
10999                confp->pri.nodetype = PRI_NETWORK;
11000             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
11001                confp->chan.sig = SIG_GR303FXSKS;
11002                confp->chan.radio = 0;
11003                confp->pri.nodetype = PRI_CPE;
11004 #endif
11005             } else {
11006                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
11007             }
11008           } else if (!strcasecmp(v->name, "outsignalling")) {
11009             if (!strcasecmp(v->value, "em")) {
11010                confp->chan.outsigmod = SIG_EM;
11011             } else if (!strcasecmp(v->value, "em_e1")) {
11012                confp->chan.outsigmod = SIG_EM_E1;
11013             } else if (!strcasecmp(v->value, "em_w")) {
11014                confp->chan.outsigmod = SIG_EMWINK;
11015             } else if (!strcasecmp(v->value, "sf")) {
11016                confp->chan.outsigmod = SIG_SF;
11017             } else if (!strcasecmp(v->value, "sf_w")) {
11018                confp->chan.outsigmod = SIG_SFWINK;
11019             } else if (!strcasecmp(v->value, "sf_featd")) {
11020                confp->chan.outsigmod = SIG_FEATD;
11021             } else if (!strcasecmp(v->value, "sf_featdmf")) {
11022                confp->chan.outsigmod = SIG_FEATDMF;
11023             } else if (!strcasecmp(v->value, "sf_featb")) {
11024                confp->chan.outsigmod = SIG_SF_FEATB;
11025             } else if (!strcasecmp(v->value, "sf")) {
11026                confp->chan.outsigmod = SIG_SF;
11027             } else if (!strcasecmp(v->value, "featd")) {
11028                confp->chan.outsigmod = SIG_FEATD;
11029             } else if (!strcasecmp(v->value, "featdmf")) {
11030                confp->chan.outsigmod = SIG_FEATDMF;
11031             } else if (!strcasecmp(v->value, "featdmf_ta")) {
11032                confp->chan.outsigmod = SIG_FEATDMF_TA;
11033             } else if (!strcasecmp(v->value, "e911")) {
11034                confp->chan.outsigmod = SIG_E911;
11035             } else if (!strcasecmp(v->value, "fgccama")) {
11036                confp->chan.outsigmod = SIG_FGC_CAMA;
11037             } else if (!strcasecmp(v->value, "fgccamamf")) {
11038                confp->chan.outsigmod = SIG_FGC_CAMAMF;
11039             } else if (!strcasecmp(v->value, "featb")) {
11040                confp->chan.outsigmod = SIG_FEATB;
11041             } else {
11042                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
11043             }
11044 #ifdef HAVE_PRI
11045          } else if (!strcasecmp(v->name, "pridialplan")) {
11046             if (!strcasecmp(v->value, "national")) {
11047                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
11048             } else if (!strcasecmp(v->value, "unknown")) {
11049                confp->pri.dialplan = PRI_UNKNOWN + 1;
11050             } else if (!strcasecmp(v->value, "private")) {
11051                confp->pri.dialplan = PRI_PRIVATE + 1;
11052             } else if (!strcasecmp(v->value, "international")) {
11053                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
11054             } else if (!strcasecmp(v->value, "local")) {
11055                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
11056             } else if (!strcasecmp(v->value, "dynamic")) {
11057                confp->pri.dialplan = -1;
11058             } else {
11059                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
11060             }
11061          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
11062             if (!strcasecmp(v->value, "national")) {
11063                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
11064             } else if (!strcasecmp(v->value, "unknown")) {
11065                confp->pri.localdialplan = PRI_UNKNOWN + 1;
11066             } else if (!strcasecmp(v->value, "private")) {
11067                confp->pri.localdialplan = PRI_PRIVATE + 1;
11068             } else if (!strcasecmp(v->value, "international")) {
11069                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
11070             } else if (!strcasecmp(v->value, "local")) {
11071                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
11072             } else if (!strcasecmp(v->value, "dynamic")) {
11073                confp->pri.localdialplan = -1;
11074             } else {
11075                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
11076             }
11077          } else if (!strcasecmp(v->name, "switchtype")) {
11078             if (!strcasecmp(v->value, "national")) 
11079                confp->pri.switchtype = PRI_SWITCH_NI2;
11080             else if (!strcasecmp(v->value, "ni1"))
11081                confp->pri.switchtype = PRI_SWITCH_NI1;
11082             else if (!strcasecmp(v->value, "dms100"))
11083                confp->pri.switchtype = PRI_SWITCH_DMS100;
11084             else if (!strcasecmp(v->value, "4ess"))
11085                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
11086             else if (!strcasecmp(v->value, "5ess"))
11087                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
11088             else if (!strcasecmp(v->value, "euroisdn"))
11089                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
11090             else if (!strcasecmp(v->value, "qsig"))
11091                confp->pri.switchtype = PRI_SWITCH_QSIG;
11092             else {
11093                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
11094                return -1;
11095             }
11096          } else if (!strcasecmp(v->name, "nsf")) {
11097             if (!strcasecmp(v->value, "sdn"))
11098                confp->pri.nsf = PRI_NSF_SDN;
11099             else if (!strcasecmp(v->value, "megacom"))
11100                confp->pri.nsf = PRI_NSF_MEGACOM;
11101             else if (!strcasecmp(v->value, "tollfreemegacom"))
11102                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
11103             else if (!strcasecmp(v->value, "accunet"))
11104                confp->pri.nsf = PRI_NSF_ACCUNET;
11105             else if (!strcasecmp(v->value, "none"))
11106                confp->pri.nsf = PRI_NSF_NONE;
11107             else {
11108                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
11109                confp->pri.nsf = PRI_NSF_NONE;
11110             }
11111          } else if (!strcasecmp(v->name, "priindication")) {
11112             if (!strcasecmp(v->value, "outofband"))
11113                confp->chan.priindication_oob = 1;
11114             else if (!strcasecmp(v->value, "inband"))
11115                confp->chan.priindication_oob = 0;
11116             else
11117                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
11118                   v->value, v->lineno);
11119          } else if (!strcasecmp(v->name, "priexclusive")) {
11120             confp->chan.priexclusive = ast_true(v->value);
11121          } else if (!strcasecmp(v->name, "internationalprefix")) {
11122             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
11123          } else if (!strcasecmp(v->name, "nationalprefix")) {
11124             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
11125          } else if (!strcasecmp(v->name, "localprefix")) {
11126             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
11127          } else if (!strcasecmp(v->name, "privateprefix")) {
11128             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
11129          } else if (!strcasecmp(v->name, "unknownprefix")) {
11130             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
11131          } else if (!strcasecmp(v->name, "resetinterval")) {
11132             if (!strcasecmp(v->value, "never"))
11133                confp->pri.resetinterval = -1;
11134             else if (atoi(v->value) >= 60)
11135                confp->pri.resetinterval = atoi(v->value);
11136             else
11137                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
11138                   v->value, v->lineno);
11139          } else if (!strcasecmp(v->name, "minunused")) {
11140             confp->pri.minunused = atoi(v->value);
11141          } else if (!strcasecmp(v->name, "minidle")) {
11142             confp->pri.minidle = atoi(v->value); 
11143          } else if (!strcasecmp(v->name, "idleext")) {
11144             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
11145          } else if (!strcasecmp(v->name, "idledial")) {
11146             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
11147          } else if (!strcasecmp(v->name, "overlapdial")) {
11148             confp->pri.overlapdial = ast_true(v->value);
11149          } else if (!strcasecmp(v->name, "pritimer")) {
11150 #ifdef PRI_GETSET_TIMERS
11151             char *timerc, *c;
11152             int timer, timeridx;
11153             c = v->value;
11154             timerc = strsep(&c, ",");
11155             if (timerc) {
11156                timer = atoi(c);
11157                if (!timer)
11158                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
11159                else {
11160                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
11161                      pritimers[timeridx] = timer;
11162                   else
11163                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
11164                }
11165             } else
11166                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
11167 
11168          } else if (!strcasecmp(v->name, "facilityenable")) {
11169             confp->pri.facilityenable = ast_true(v->value);
11170 #endif /* PRI_GETSET_TIMERS */
11171 #endif /* HAVE_PRI */
11172          } else if (!strcasecmp(v->name, "cadence")) {
11173             /* setup to scan our argument */
11174             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
11175             int i;
11176             struct zt_ring_cadence new_cadence;
11177             int cid_location = -1;
11178             int firstcadencepos = 0;
11179             char original_args[80];
11180             int cadence_is_ok = 1;
11181 
11182             ast_copy_string(original_args, v->value, sizeof(original_args));
11183             /* 16 cadences allowed (8 pairs) */
11184             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]);
11185    
11186             /* Cadence must be even (on/off) */
11187             if (element_count % 2 == 1) {
11188                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
11189                cadence_is_ok = 0;
11190             }
11191    
11192             /* Ring cadences cannot be negative */
11193             for (i = 0; i < element_count; i++) {
11194                if (c[i] == 0) {
11195                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
11196                   cadence_is_ok = 0;
11197                   break;
11198                } else if (c[i] < 0) {
11199                   if (i % 2 == 1) {
11200                      /* Silence duration, negative possibly okay */
11201                      if (cid_location == -1) {
11202                         cid_location = i;
11203                         c[i] *= -1;
11204                      } else {
11205                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
11206                         cadence_is_ok = 0;
11207                         break;
11208                      }
11209                   } else {
11210                      if (firstcadencepos == 0) {
11211                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
11212                                  /* duration will be passed negative to the zaptel driver */
11213                      } else {
11214                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
11215                         cadence_is_ok = 0;
11216                         break;
11217                      }
11218                   }
11219                }
11220             }
11221    
11222             /* Substitute our scanned cadence */
11223             for (i = 0; i < 16; i++) {
11224                new_cadence.ringcadence[i] = c[i];
11225             }
11226    
11227             if (cadence_is_ok) {
11228                /* ---we scanned it without getting annoyed; now some sanity checks--- */
11229                if (element_count < 2) {
11230                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
11231                } else {
11232                   if (cid_location == -1) {
11233                      /* user didn't say; default to first pause */
11234                      cid_location = 1;
11235                   } else {
11236                      /* convert element_index to cidrings value */
11237                      cid_location = (cid_location + 1) / 2;
11238                   }
11239                   /* ---we like their cadence; try to install it--- */
11240                   if (!user_has_defined_cadences++)
11241                      /* this is the first user-defined cadence; clear the default user cadences */
11242                      num_cadence = 0;
11243                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
11244                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
11245                   else {
11246                      cadences[num_cadence] = new_cadence;
11247                      cidrings[num_cadence++] = cid_location;
11248                      if (option_verbose > 2)
11249                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
11250                   }
11251                }
11252             }
11253          } else if (!strcasecmp(v->name, "ringtimeout")) {
11254             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
11255          } else if (!strcasecmp(v->name, "prewink")) {
11256             confp->timing.prewinktime = atoi(v->value);
11257          } else if (!strcasecmp(v->name, "preflash")) {
11258             confp->timing.preflashtime = atoi(v->value);
11259          } else if (!strcasecmp(v->name, "wink")) {
11260             confp->timing.winktime = atoi(v->value);
11261          } else if (!strcasecmp(v->name, "flash")) {
11262             confp->timing.flashtime = atoi(v->value);
11263          } else if (!strcasecmp(v->name, "start")) {
11264             confp->timing.starttime = atoi(v->value);
11265          } else if (!strcasecmp(v->name, "rxwink")) {
11266             confp->timing.rxwinktime = atoi(v->value);
11267          } else if (!strcasecmp(v->name, "rxflash")) {
11268             confp->timing.rxflashtime = atoi(v->value);
11269          } else if (!strcasecmp(v->name, "debounce")) {
11270             confp->timing.debouncetime = atoi(v->value);
11271          } else if (!strcasecmp(v->name, "toneduration")) {
11272             int toneduration;
11273             int ctlfd;
11274             int res;
11275             struct zt_dialparams dps;
11276 
11277             ctlfd = open("/dev/zap/ctl", O_RDWR);
11278             if (ctlfd == -1) {
11279                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11280                return -1;
11281             }
11282 
11283             toneduration = atoi(v->value);
11284             if (toneduration > -1) {
11285                memset(&dps, 0, sizeof(dps));
11286 
11287                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11288                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11289                if (res < 0) {
11290                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11291                   return -1;
11292                }
11293             }
11294             close(ctlfd);
11295          } else if (!strcasecmp(v->name, "defaultcic")) {
11296             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11297          } else if (!strcasecmp(v->name, "defaultozz")) {
11298             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11299          } 
11300       } else if (!skipchannels)
11301          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11302    }
11303    if (zapchan[0]) { 
11304       /* The user has set 'zapchan' */
11305       /*< \todo pass proper line number instead of 0 */
11306       if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) {
11307          return -1;
11308       }
11309    }
11310    /*< \todo why check for the pseudo in the per-channel section.
11311     * Any actual use for manual setup of the pseudo channel? */
11312    if (!found_pseudo && reload == 0) {
11313       /* Make sure pseudo isn't a member of any groups if
11314          we're automatically making it. */   
11315       
11316       confp->chan.group = 0;
11317       confp->chan.callgroup = 0;
11318       confp->chan.pickupgroup = 0;
11319 
11320       tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload);
11321 
11322       if (tmp) {
11323          if (option_verbose > 2)
11324             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11325       } else {
11326          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11327       }
11328    }
11329    return 0;
11330 }
11331       
11332 static int setup_zap(int reload)
11333 {
11334    struct ast_config *cfg;
11335    struct ast_variable *v;
11336    struct zt_chan_conf conf = zt_chan_conf_default();
11337    int res;
11338 
11339 #ifdef HAVE_PRI
11340    char *c;
11341    int spanno;
11342    int i, x;
11343    int logicalspan;
11344    int trunkgroup;
11345    int dchannels[NUM_DCHANS];
11346 #endif
11347 
11348    cfg = ast_config_load(config);
11349 
11350    /* Error if we have no config file */
11351    if (!cfg) {
11352       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
11353       return 0;
11354    }
11355 
11356    /* It's a little silly to lock it, but we mind as well just to be sure */
11357    ast_mutex_lock(&iflock);
11358 #ifdef HAVE_PRI
11359    if (!reload) {
11360       /* Process trunkgroups first */
11361       v = ast_variable_browse(cfg, "trunkgroups");
11362       while (v) {
11363          if (!strcasecmp(v->name, "trunkgroup")) {
11364             trunkgroup = atoi(v->value);
11365             if (trunkgroup > 0) {
11366                if ((c = strchr(v->value, ','))) {
11367                   i = 0;
11368                   memset(dchannels, 0, sizeof(dchannels));
11369                   while (c && (i < NUM_DCHANS)) {
11370                      dchannels[i] = atoi(c + 1);
11371                      if (dchannels[i] < 0) {
11372                         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);
11373                      } else
11374                         i++;
11375                      c = strchr(c + 1, ',');
11376                   }
11377                   if (i) {
11378                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
11379                         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);
11380                      } else if (option_verbose > 1)
11381                         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");
11382                   } else
11383                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
11384                } else
11385                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
11386             } else
11387                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
11388          } else if (!strcasecmp(v->name, "spanmap")) {
11389             spanno = atoi(v->value);
11390             if (spanno > 0) {
11391                if ((c = strchr(v->value, ','))) {
11392                   trunkgroup = atoi(c + 1);
11393                   if (trunkgroup > 0) {
11394                      if ((c = strchr(c + 1, ','))) 
11395                         logicalspan = atoi(c + 1);
11396                      else
11397                         logicalspan = 0;
11398                      if (logicalspan >= 0) {
11399                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
11400                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11401                         } else if (option_verbose > 1) 
11402                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11403                      } else
11404                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
11405                   } else
11406                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
11407                } else
11408                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
11409             } else
11410                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
11411          } else {
11412             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
11413          }
11414          v = v->next;
11415       }
11416    }
11417 #endif
11418    
11419    /* Copy the default jb config over global_jbconf */
11420    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
11421 
11422    v = ast_variable_browse(cfg, "channels");
11423    res = process_zap(&conf, v, reload, 0);
11424    ast_mutex_unlock(&iflock);
11425    ast_config_destroy(cfg);
11426    if (res)
11427       return res;
11428    cfg = ast_config_load("users.conf");
11429    if (cfg) {
11430       char *cat;
11431       const char *chans;
11432       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
11433       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
11434          if (!strcasecmp(cat, "general"))
11435             continue;
11436          chans = ast_variable_retrieve(cfg, cat, "zapchan");
11437          if (!ast_strlen_zero(chans)) {
11438             struct zt_chan_conf sect_conf;
11439             memcpy(&sect_conf, &conf, sizeof(sect_conf));
11440 
11441             process_zap(&sect_conf, ast_variable_browse(cfg, cat), reload, 0);
11442          }
11443       }
11444       ast_config_destroy(cfg);
11445    }
11446 #ifdef HAVE_PRI
11447    if (!reload) {
11448       for (x = 0; x < NUM_SPANS; x++) {
11449          if (pris[x].pvts[0]) {
11450             if (start_pri(pris + x)) {
11451                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11452                return -1;
11453             } else if (option_verbose > 1)
11454                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11455          }
11456       }
11457    }
11458 #endif
11459    /* And start the monitor for the first time */
11460    restart_monitor();
11461    return 0;
11462 }
11463 
11464 static int load_module(void)
11465 {
11466    int res;
11467 
11468 #ifdef HAVE_PRI
11469    int y,i;
11470    memset(pris, 0, sizeof(pris));
11471    for (y = 0; y < NUM_SPANS; y++) {
11472       ast_mutex_init(&pris[y].lock);
11473       pris[y].offset = -1;
11474       pris[y].master = AST_PTHREADT_NULL;
11475       for (i = 0; i < NUM_DCHANS; i++)
11476          pris[y].fds[i] = -1;
11477    }
11478    pri_set_error(zt_pri_error);
11479    pri_set_message(zt_pri_message);
11480    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
11481          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
11482 #endif
11483    res = setup_zap(0);
11484    /* Make sure we can register our Zap channel type */
11485    if (res)
11486       return AST_MODULE_LOAD_DECLINE;
11487    if (ast_channel_register(&zap_tech)) {
11488       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
11489       __unload_module();
11490       return -1;
11491    }
11492 #ifdef HAVE_PRI
11493    ast_string_field_init(&inuse, 16);
11494    ast_string_field_set(&inuse, name, "GR-303InUse");
11495    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11496 #endif   
11497    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11498    
11499    memset(round_robin, 0, sizeof(round_robin));
11500    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11501    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11502    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11503    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11504    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11505    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11506    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
11507 
11508    return res;
11509 }
11510 
11511 static int zt_sendtext(struct ast_channel *c, const char *text)
11512 {
11513 #define  END_SILENCE_LEN 400
11514 #define  HEADER_MS 50
11515 #define  TRAILER_MS 5
11516 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11517 #define  ASCII_BYTES_PER_CHAR 80
11518 
11519    unsigned char *buf,*mybuf;
11520    struct zt_pvt *p = c->tech_pvt;
11521    struct pollfd fds[1];
11522    int size,res,fd,len,x;
11523    int bytes=0;
11524    /* Initial carrier (imaginary) */
11525    float cr = 1.0;
11526    float ci = 0.0;
11527    float scont = 0.0;
11528    int index;
11529 
11530    index = zt_get_index(c, p, 0);
11531    if (index < 0) {
11532       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11533       return -1;
11534    }
11535    if (!text[0]) return(0); /* if nothing to send, dont */
11536    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11537    if (p->mate) 
11538       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11539    else
11540       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11541    if (!buf)
11542       return -1;
11543    mybuf = buf;
11544    if (p->mate) {
11545       int codec = AST_LAW(p);
11546       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
11547          PUT_CLID_MARKMS;
11548       }
11549       /* Put actual message */
11550       for (x = 0; text[x]; x++) {
11551          PUT_CLID(text[x]);
11552       }
11553       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
11554          PUT_CLID_MARKMS;
11555       }
11556       len = bytes;
11557       buf = mybuf;
11558    } else {
11559       len = tdd_generate(p->tdd, buf, text);
11560       if (len < 1) {
11561          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
11562          free(mybuf);
11563          return -1;
11564       }
11565    }
11566    memset(buf + len, 0x7f, END_SILENCE_LEN);
11567    len += END_SILENCE_LEN;
11568    fd = p->subs[index].zfd;
11569    while (len) {
11570       if (ast_check_hangup(c)) {
11571          free(mybuf);
11572          return -1;
11573       }
11574       size = len;
11575       if (size > READ_SIZE)
11576          size = READ_SIZE;
11577       fds[0].fd = fd;
11578       fds[0].events = POLLOUT | POLLPRI;
11579       fds[0].revents = 0;
11580       res = poll(fds, 1, -1);
11581       if (!res) {
11582          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11583          continue;
11584       }
11585         /* if got exception */
11586       if (fds[0].revents & POLLPRI) {
11587          ast_free(mybuf);
11588          return -1;
11589       }
11590       if (!(fds[0].revents & POLLOUT)) {
11591          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11592          continue;
11593       }
11594       res = write(fd, buf, size);
11595       if (res != size) {
11596          if (res == -1) {
11597             free(mybuf);
11598             return -1;
11599          }
11600          if (option_debug)
11601             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11602          break;
11603       }
11604       len -= size;
11605       buf += size;
11606    }
11607    free(mybuf);
11608    return(0);
11609 }
11610 
11611 
11612 static int reload(void)
11613 {
11614    int res = 0;
11615 
11616    res = setup_zap(1);
11617    if (res) {
11618       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11619       return -1;
11620    }
11621    return 0;
11622 }
11623 
11624 /* This is a workaround so that menuselect displays a proper description
11625  * AST_MODULE_INFO(, , "Zapata Telephony"
11626  */
11627 
11628 #ifdef ZAPATA_PRI
11629 #define tdesc "Zapata Telephony w/PRI"
11630 #else
11631 #define tdesc "Zapata Telephony"
11632 #endif
11633 
11634 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
11635       .load = load_module,
11636       .unload = unload_module,
11637       .reload = reload,
11638           );
11639 
11640 

Generated on Tue Nov 4 13:20:18 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7