Mon Mar 31 07:38:00 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>zaptel_vldtmf</depend>
00042    <depend>zaptel</depend>
00043    <depend>tonezone</depend>
00044    <depend>res_features</depend>
00045    <use>pri</use>
00046  ***/
00047 
00048 #include "asterisk.h"
00049 
00050 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00051 
00052 #include <stdio.h>
00053 #include <string.h>
00054 #ifdef __NetBSD__
00055 #include <pthread.h>
00056 #include <signal.h>
00057 #else
00058 #include <sys/signal.h>
00059 #endif
00060 #include <errno.h>
00061 #include <stdlib.h>
00062 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00063 #include <stdint.h>
00064 #endif
00065 #include <unistd.h>
00066 #include <sys/ioctl.h>
00067 #include <math.h>
00068 #include <ctype.h>
00069 #include <zaptel/zaptel.h>
00070 #include <zaptel/tonezone.h>
00071 
00072 #ifdef HAVE_PRI
00073 #include <libpri.h>
00074 #endif
00075 
00076 #include "asterisk/lock.h"
00077 #include "asterisk/channel.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/logger.h"
00080 #include "asterisk/module.h"
00081 #include "asterisk/pbx.h"
00082 #include "asterisk/options.h"
00083 #include "asterisk/file.h"
00084 #include "asterisk/ulaw.h"
00085 #include "asterisk/alaw.h"
00086 #include "asterisk/callerid.h"
00087 #include "asterisk/adsi.h"
00088 #include "asterisk/cli.h"
00089 #include "asterisk/cdr.h"
00090 #include "asterisk/features.h"
00091 #include "asterisk/musiconhold.h"
00092 #include "asterisk/say.h"
00093 #include "asterisk/tdd.h"
00094 #include "asterisk/app.h"
00095 #include "asterisk/dsp.h"
00096 #include "asterisk/astdb.h"
00097 #include "asterisk/manager.h"
00098 #include "asterisk/causes.h"
00099 #include "asterisk/term.h"
00100 #include "asterisk/utils.h"
00101 #include "asterisk/transcap.h"
00102 #include "asterisk/stringfields.h"
00103 #include "asterisk/abstract_jb.h"
00104 #include "asterisk/smdi.h"
00105 #include "asterisk/astobj.h"
00106 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00107 
00108 /*! Global jitterbuffer configuration - by default, jb is disabled */
00109 static struct ast_jb_conf default_jbconf =
00110 {
00111    .flags = 0,
00112    .max_size = -1,
00113    .resync_threshold = -1,
00114    .impl = ""
00115 };
00116 static struct ast_jb_conf global_jbconf;
00117 
00118 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00119 #error "Your zaptel is too old.  Please update"
00120 #endif
00121 
00122 #ifndef ZT_TONEDETECT
00123 /* Work around older code with no tone detect */
00124 #define ZT_EVENT_DTMFDOWN 0
00125 #define ZT_EVENT_DTMFUP 0
00126 #endif
00127 
00128 /* define this to send PRI user-user information elements */
00129 #undef SUPPORT_USERUSER
00130 
00131 /*! 
00132  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00133  * the user hangs up to reset the state machine so ring works properly.
00134  * This is used to be able to support kewlstart by putting the zhone in
00135  * groundstart mode since their forward disconnect supervision is entirely
00136  * broken even though their documentation says it isn't and their support
00137  * is entirely unwilling to provide any assistance with their channel banks
00138  * even though their web site says they support their products for life.
00139  */
00140 /* #define ZHONE_HACK */
00141 
00142 /*! \note
00143  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00144  * before dialing on it.  Certain FXO interfaces always think they're out of
00145  * service with this method however.
00146  */
00147 /* #define ZAP_CHECK_HOOKSTATE */
00148 
00149 /*! \brief Typically, how many rings before we should send Caller*ID */
00150 #define DEFAULT_CIDRINGS 1
00151 
00152 #define CHANNEL_PSEUDO -12
00153 
00154 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00155 
00156 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00157 #define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB)) 
00158 
00159 static const char tdesc[] = "Zapata Telephony Driver"
00160 #ifdef HAVE_PRI
00161                " w/PRI"
00162 #endif
00163 ;
00164 
00165 static const char config[] = "zapata.conf";
00166 
00167 #define SIG_EM    ZT_SIG_EM
00168 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00169 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00170 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00171 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00172 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00173 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00174 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00175 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00176 #define SIG_FXSLS ZT_SIG_FXSLS
00177 #define SIG_FXSGS ZT_SIG_FXSGS
00178 #define SIG_FXSKS ZT_SIG_FXSKS
00179 #define SIG_FXOLS ZT_SIG_FXOLS
00180 #define SIG_FXOGS ZT_SIG_FXOGS
00181 #define SIG_FXOKS ZT_SIG_FXOKS
00182 #define SIG_PRI      ZT_SIG_CLEAR
00183 #define  SIG_SF      ZT_SIG_SF
00184 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00185 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00186 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00187 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00188 #define SIG_EM_E1 ZT_SIG_EM_E1
00189 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00190 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00191 
00192 #define NUM_SPANS       32
00193 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00194 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00195 
00196 #define CHAN_PSEUDO  -2
00197 
00198 #define DCHAN_PROVISIONED (1 << 0)
00199 #define DCHAN_NOTINALARM  (1 << 1)
00200 #define DCHAN_UP          (1 << 2)
00201 
00202 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00203 
00204 static char defaultcic[64] = "";
00205 static char defaultozz[64] = "";
00206 
00207 static char progzone[10] = "";
00208 
00209 static int distinctiveringaftercid = 0;
00210 
00211 static int numbufs = 4;
00212 
00213 #ifdef HAVE_PRI
00214 static struct ast_channel inuse;
00215 #ifdef PRI_GETSET_TIMERS
00216 static int pritimers[PRI_MAX_TIMERS];
00217 #endif
00218 static int pridebugfd = -1;
00219 static char pridebugfilename[1024] = "";
00220 #endif
00221 
00222 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00223 static int firstdigittimeout = 16000;
00224 
00225 /*! \brief How long to wait for following digits (FXO logic) */
00226 static int gendigittimeout = 8000;
00227 
00228 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00229 static int matchdigittimeout = 3000;
00230 
00231 /*! \brief Protect the interface list (of zt_pvt's) */
00232 AST_MUTEX_DEFINE_STATIC(iflock);
00233 
00234 
00235 static int ifcount = 0;
00236 
00237 #ifdef HAVE_PRI
00238 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00239 #endif
00240 
00241 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00242    when it's doing something critical. */
00243 AST_MUTEX_DEFINE_STATIC(monlock);
00244 
00245 /*! \brief This is the thread for the monitor which checks for input on the channels
00246    which are not currently in use. */
00247 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00248 
00249 static int restart_monitor(void);
00250 
00251 static enum ast_bridge_result zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
00252 
00253 static int zt_sendtext(struct ast_channel *c, const char *text);
00254 
00255 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00256 static inline int zt_get_event(int fd)
00257 {
00258    int j;
00259    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00260       return -1;
00261    return j;
00262 }
00263 
00264 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00265 static inline int zt_wait_event(int fd)
00266 {
00267    int i, j = 0;
00268    i = ZT_IOMUX_SIGEVENT;
00269    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00270       return -1;
00271    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00272       return -1;
00273    return j;
00274 }
00275 
00276 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00277 #define READ_SIZE 160
00278 
00279 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00280 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00281 
00282 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00283 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 300 ms */
00284 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00285 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00286 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE)
00287 
00288 struct zt_pvt;
00289 
00290 static int ringt_base = DEFAULT_RINGT;
00291 
00292 #ifdef HAVE_PRI
00293 
00294 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00295 #define PRI_CHANNEL(p) ((p) & 0xff)
00296 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00297 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00298 
00299 struct zt_pri {
00300    pthread_t master;                /*!< Thread of master */
00301    ast_mutex_t lock;                /*!< Mutex */
00302    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00303    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00304    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00305    int minunused;                   /*!< Min # of channels to keep empty */
00306    int minidle;                     /*!< Min # of "idling" calls to keep active */
00307    int nodetype;                    /*!< Node type */
00308    int switchtype;                     /*!< Type of switch to emulate */
00309    int nsf;                   /*!< Network-Specific Facilities */
00310    int dialplan;                    /*!< Dialing plan */
00311    int localdialplan;                  /*!< Local dialing plan */
00312    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00313    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00314    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00315    char privateprefix[20];                /*!< for private dialplans */
00316    char unknownprefix[20];                /*!< for unknown dialplans */
00317    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00318    int trunkgroup;                     /*!< What our trunkgroup is */
00319    int mastertrunkgroup;                  /*!< What trunk group is our master */
00320    int prilogicalspan;                 /*!< Logical span number within trunk group */
00321    int numchans;                    /*!< Num of channels we represent */
00322    int overlapdial;                 /*!< In overlap dialing mode */
00323    int facilityenable;                 /*!< Enable facility IEs */
00324    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00325    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00326    struct pri *pri;                 /*!< Currently active D-channel */
00327    int debug;
00328    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00329    int offset;
00330    int span;
00331    int resetting;
00332    int resetpos;
00333    time_t lastreset;                /*!< time when unused channels were last reset */
00334    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00335    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00336    struct zt_pvt *crvs;                /*!< Member CRV structs */
00337    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00338 };
00339 
00340 
00341 static struct zt_pri pris[NUM_SPANS];
00342 
00343 #if 0
00344 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00345 #else
00346 #define DEFAULT_PRI_DEBUG 0
00347 #endif
00348 
00349 static inline void pri_rel(struct zt_pri *pri)
00350 {
00351    ast_mutex_unlock(&pri->lock);
00352 }
00353 
00354 #else
00355 /*! Shut up the compiler */
00356 struct zt_pri;
00357 #endif
00358 
00359 #define SUB_REAL  0        /*!< Active call */
00360 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00361 #define SUB_THREEWAY 2        /*!< Three-way call */
00362 
00363 /* Polarity states */
00364 #define POLARITY_IDLE   0
00365 #define POLARITY_REV    1
00366 
00367 
00368 static struct zt_distRings drings;
00369 
00370 struct distRingData {
00371    int ring[3];
00372 };
00373 struct ringContextData {
00374    char contextData[AST_MAX_CONTEXT];
00375 };
00376 struct zt_distRings {
00377    struct distRingData ringnum[3];
00378    struct ringContextData ringContext[3];
00379 };
00380 
00381 static char *subnames[] = {
00382    "Real",
00383    "Callwait",
00384    "Threeway"
00385 };
00386 
00387 struct zt_subchannel {
00388    int zfd;
00389    struct ast_channel *owner;
00390    int chan;
00391    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00392    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00393    unsigned int needringing:1;
00394    unsigned int needbusy:1;
00395    unsigned int needcongestion:1;
00396    unsigned int needcallerid:1;
00397    unsigned int needanswer:1;
00398    unsigned int needflash:1;
00399    unsigned int needhold:1;
00400    unsigned int needunhold:1;
00401    unsigned int linear:1;
00402    unsigned int inthreeway:1;
00403    ZT_CONFINFO curconf;
00404 };
00405 
00406 #define CONF_USER_REAL     (1 << 0)
00407 #define CONF_USER_THIRDCALL   (1 << 1)
00408 
00409 #define MAX_SLAVES   4
00410 
00411 static struct zt_pvt {
00412    ast_mutex_t lock;
00413    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00414                      /*!< Up to three channels can be associated with this call */
00415       
00416    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00417    struct zt_subchannel subs[3];       /*!< Sub-channels */
00418    struct zt_confinfo saveconf;        /*!< Saved conference info */
00419 
00420    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00421    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00422    int inconference;          /*!< If our real should be in the conference */
00423    
00424    int sig;             /*!< Signalling style */
00425    int radio;              /*!< radio type */
00426    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00427    int oprmode;               /*!< "Operator Services" mode */
00428    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00429    float rxgain;
00430    float txgain;
00431    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00432    struct zt_pvt *next;          /*!< Next channel in list */
00433    struct zt_pvt *prev;          /*!< Prev channel in list */
00434 
00435    /* flags */
00436    unsigned int adsi:1;
00437    unsigned int answeronpolarityswitch:1;
00438    unsigned int busydetect:1;
00439    unsigned int callreturn:1;
00440    unsigned int callwaiting:1;
00441    unsigned int callwaitingcallerid:1;
00442    unsigned int cancallforward:1;
00443    unsigned int canpark:1;
00444    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00445    unsigned int destroy:1;
00446    unsigned int didtdd:1;           /*!< flag to say its done it once */
00447    unsigned int dialednone:1;
00448    unsigned int dialing:1;
00449    unsigned int digital:1;
00450    unsigned int dnd:1;
00451    unsigned int echobreak:1;
00452    unsigned int echocanbridged:1;
00453    unsigned int echocanon:1;
00454    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00455    unsigned int firstradio:1;
00456    unsigned int hanguponpolarityswitch:1;
00457    unsigned int hardwaredtmf:1;
00458    unsigned int hidecallerid:1;
00459    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00460    unsigned int ignoredtmf:1;
00461    unsigned int immediate:1;        /*!< Answer before getting digits? */
00462    unsigned int inalarm:1;
00463    unsigned int unknown_alarm:1;
00464    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00465    unsigned int outgoing:1;
00466    unsigned int overlapdial:1;
00467    unsigned int permcallwaiting:1;
00468    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00469    unsigned int priindication_oob:1;
00470    unsigned int priexclusive:1;
00471    unsigned int pulse:1;
00472    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00473    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00474    unsigned int threewaycalling:1;
00475    unsigned int transfer:1;
00476    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00477    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00478    unsigned int usedistinctiveringdetection:1;
00479    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00480    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00481 #if defined(HAVE_PRI)
00482    unsigned int alerting:1;
00483    unsigned int alreadyhungup:1;
00484    unsigned int isidlecall:1;
00485    unsigned int proceeding:1;
00486    unsigned int progress:1;
00487    unsigned int resetting:1;
00488    unsigned int setup_ack:1;
00489 #endif
00490    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00491    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00492 
00493    struct zt_distRings drings;
00494 
00495    char context[AST_MAX_CONTEXT];
00496    char defcontext[AST_MAX_CONTEXT];
00497    char exten[AST_MAX_EXTENSION];
00498    char language[MAX_LANGUAGE];
00499    char mohinterpret[MAX_MUSICCLASS];
00500    char mohsuggest[MAX_MUSICCLASS];
00501 #ifdef PRI_ANI
00502    char cid_ani[AST_MAX_EXTENSION];
00503 #endif
00504    char cid_num[AST_MAX_EXTENSION];
00505    int cid_ton;               /*!< Type Of Number (TON) */
00506    char cid_name[AST_MAX_EXTENSION];
00507    char lastcid_num[AST_MAX_EXTENSION];
00508    char lastcid_name[AST_MAX_EXTENSION];
00509    char *origcid_num;            /*!< malloced original callerid */
00510    char *origcid_name;           /*!< malloced original callerid */
00511    char callwait_num[AST_MAX_EXTENSION];
00512    char callwait_name[AST_MAX_EXTENSION];
00513    char rdnis[AST_MAX_EXTENSION];
00514    char dnid[AST_MAX_EXTENSION];
00515    ast_group_t group;
00516    int law;
00517    int confno;             /*!< Our conference */
00518    int confusers;             /*!< Who is using our conference */
00519    int propconfno;               /*!< Propagated conference number */
00520    ast_group_t callgroup;
00521    ast_group_t pickupgroup;
00522    int channel;               /*!< Channel Number or CRV */
00523    int span;               /*!< Span number */
00524    time_t guardtime;          /*!< Must wait this much time before using for new call */
00525    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00526    int cid_start;             /*!< CID start indicator, polarity or ring */
00527    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00528    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00529    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00530    unsigned char *cidspill;
00531    int cidpos;
00532    int cidlen;
00533    int ringt;
00534    int ringt_base;
00535    int stripmsd;
00536    int callwaitcas;
00537    int callwaitrings;
00538    int echocancel;
00539    int echotraining;
00540    char echorest[20];
00541    int busycount;
00542    int busy_tonelength;
00543    int busy_quietlength;
00544    int callprogress;
00545    struct timeval flashtime;        /*!< Last flash-hook time */
00546    struct ast_dsp *dsp;
00547    int cref;               /*!< Call reference number */
00548    ZT_DIAL_OPERATION dop;
00549    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00550    char finaldial[64];
00551    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00552    int amaflags;              /*!< AMA Flags */
00553    struct tdd_state *tdd;           /*!< TDD flag */
00554    char call_forward[AST_MAX_EXTENSION];
00555    char mailbox[AST_MAX_EXTENSION];
00556    char dialdest[256];
00557    int onhooktime;
00558    int msgstate;
00559    int distinctivering;          /*!< Which distinctivering to use */
00560    int cidrings;              /*!< Which ring to deliver CID on */
00561    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00562    int fake_event;
00563    int polarityonanswerdelay;
00564    struct timeval polaritydelaytv;
00565    int sendcalleridafter;
00566 #ifdef HAVE_PRI
00567    struct zt_pri *pri;
00568    struct zt_pvt *bearer;
00569    struct zt_pvt *realcall;
00570    q931_call *call;
00571    int prioffset;
00572    int logicalspan;
00573 #endif   
00574    int polarity;
00575    int dsp_features;
00576    char begindigit;
00577 } *iflist = NULL, *ifend = NULL;
00578 
00579 /*! \brief Channel configuration from zapata.conf .
00580  * This struct is used for parsing the [channels] section of zapata.conf.
00581  * Generally there is a field here for every possible configuration item.
00582  *
00583  * The state of fields is saved along the parsing and whenever a 'channel'
00584  * statement is reached, the current zt_chan_conf is used to configure the 
00585  * channel (struct zt_pvt)
00586  *
00587  * @seealso zt_chan_init for the default values.
00588  */
00589 struct zt_chan_conf {
00590    struct zt_pvt chan;
00591 #ifdef HAVE_PRI
00592    struct zt_pri pri;
00593 #endif
00594    ZT_PARAMS timing;
00595 
00596    char smdi_port[SMDI_MAX_FILENAME_LEN];
00597 };
00598 
00599 /** returns a new zt_chan_conf with default values (by-value) */
00600 static struct zt_chan_conf zt_chan_conf_default(void) {
00601    /* recall that if a field is not included here it is initialized
00602     * to 0 or equivalent
00603     */
00604    struct zt_chan_conf conf = {
00605 #ifdef HAVE_PRI
00606       .pri = {
00607          .nsf = PRI_NSF_NONE,
00608          .switchtype = PRI_SWITCH_NI2,
00609          .dialplan = PRI_NATIONAL_ISDN + 1,
00610          .localdialplan = PRI_NATIONAL_ISDN + 1,
00611          .nodetype = PRI_CPE,
00612 
00613          .minunused = 2,
00614          .idleext = "",
00615          .idledial = "",
00616          .internationalprefix = "",
00617          .nationalprefix = "",
00618          .localprefix = "",
00619          .privateprefix = "",
00620          .unknownprefix = "",
00621 
00622          .resetinterval = 3600
00623       },
00624 #endif
00625       .chan = {
00626          .context = "default",
00627          .cid_num = "",
00628          .cid_name = "",
00629          .mohinterpret = "default",
00630          .mohsuggest = "",
00631          .transfertobusy = 1,
00632 
00633          .cid_signalling = CID_SIG_BELL,
00634          .cid_start = CID_START_RING,
00635          .zaptrcallerid = 0,
00636          .use_callerid = 1,
00637          .sig = -1,
00638          .outsigmod = -1,
00639 
00640          .tonezone = -1,
00641 
00642          .echocancel = 1,
00643 
00644          .busycount = 3,
00645 
00646          .accountcode = "",
00647 
00648          .mailbox = "",
00649 
00650 
00651          .polarityonanswerdelay = 600,
00652 
00653          .sendcalleridafter = DEFAULT_CIDRINGS
00654       },
00655       .timing = {
00656          .prewinktime = -1,
00657          .preflashtime = -1,
00658          .winktime = -1,
00659          .flashtime = -1,
00660          .starttime = -1,
00661          .rxwinktime = -1,
00662          .rxflashtime = -1,
00663          .debouncetime = -1
00664       },
00665       .smdi_port = "/dev/ttyS0",
00666    };
00667 
00668    return conf;
00669 }
00670 
00671 
00672 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00673 static int zt_digit_begin(struct ast_channel *ast, char digit);
00674 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00675 static int zt_sendtext(struct ast_channel *c, const char *text);
00676 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00677 static int zt_hangup(struct ast_channel *ast);
00678 static int zt_answer(struct ast_channel *ast);
00679 static struct ast_frame *zt_read(struct ast_channel *ast);
00680 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00681 static struct ast_frame *zt_exception(struct ast_channel *ast);
00682 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00683 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00684 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00685 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00686 
00687 static const struct ast_channel_tech zap_tech = {
00688    .type = "Zap",
00689    .description = tdesc,
00690    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00691    .requester = zt_request,
00692    .send_digit_begin = zt_digit_begin,
00693    .send_digit_end = zt_digit_end,
00694    .send_text = zt_sendtext,
00695    .call = zt_call,
00696    .hangup = zt_hangup,
00697    .answer = zt_answer,
00698    .read = zt_read,
00699    .write = zt_write,
00700    .bridge = zt_bridge,
00701    .exception = zt_exception,
00702    .indicate = zt_indicate,
00703    .fixup = zt_fixup,
00704    .setoption = zt_setoption,
00705    .func_channel_read = zt_func_read,
00706 };
00707 
00708 #ifdef HAVE_PRI
00709 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00710 #else
00711 #define GET_CHANNEL(p) ((p)->channel)
00712 #endif
00713 
00714 struct zt_pvt *round_robin[32];
00715 
00716 #ifdef HAVE_PRI
00717 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00718 {
00719    int res;
00720    /* Grab the lock first */
00721    do {
00722       res = ast_mutex_trylock(&pri->lock);
00723       if (res) {
00724          ast_mutex_unlock(&pvt->lock);
00725          /* Release the lock and try again */
00726          usleep(1);
00727          ast_mutex_lock(&pvt->lock);
00728       }
00729    } while (res);
00730    /* Then break the poll */
00731    pthread_kill(pri->master, SIGURG);
00732    return 0;
00733 }
00734 #endif
00735 
00736 #define NUM_CADENCE_MAX 25
00737 static int num_cadence = 4;
00738 static int user_has_defined_cadences = 0;
00739 
00740 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00741    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00742    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00743    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00744    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00745 };
00746 
00747 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00748  * is 1, the second pause is 2 and so on.
00749  */
00750 
00751 static int cidrings[NUM_CADENCE_MAX] = {
00752    2,                            /*!< Right after first long ring */
00753    4,                            /*!< Right after long part */
00754    3,                            /*!< After third chirp */
00755    2,                            /*!< Second spell */
00756 };
00757 
00758 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00759          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00760 
00761 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00762 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00763 
00764 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00765 {
00766    int res;
00767    if (p->subs[0].owner == ast)
00768       res = 0;
00769    else if (p->subs[1].owner == ast)
00770       res = 1;
00771    else if (p->subs[2].owner == ast)
00772       res = 2;
00773    else {
00774       res = -1;
00775       if (!nullok)
00776          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00777    }
00778    return res;
00779 }
00780 
00781 #ifdef HAVE_PRI
00782 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00783 #else
00784 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00785 #endif
00786 {
00787 #ifdef HAVE_PRI
00788    if (pri)
00789       ast_mutex_unlock(&pri->lock);
00790 #endif         
00791    for (;;) {
00792       if (p->subs[a].owner) {
00793          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00794             ast_mutex_unlock(&p->lock);
00795             usleep(1);
00796             ast_mutex_lock(&p->lock);
00797          } else {
00798             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00799             ast_mutex_unlock(&p->subs[a].owner->lock);
00800             break;
00801          }
00802       } else
00803          break;
00804    }
00805 #ifdef HAVE_PRI
00806    if (pri)
00807       ast_mutex_lock(&pri->lock);
00808 #endif         
00809 }
00810 
00811 #ifdef HAVE_PRI
00812 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00813 #else
00814 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00815 #endif
00816 {
00817    /* We must unlock the PRI to avoid the possibility of a deadlock */
00818 #ifdef HAVE_PRI
00819    if (pri)
00820       ast_mutex_unlock(&pri->lock);
00821 #endif      
00822    for (;;) {
00823       if (p->owner) {
00824          if (ast_mutex_trylock(&p->owner->lock)) {
00825             ast_mutex_unlock(&p->lock);
00826             usleep(1);
00827             ast_mutex_lock(&p->lock);
00828          } else {
00829             ast_queue_frame(p->owner, f);
00830             ast_mutex_unlock(&p->owner->lock);
00831             break;
00832          }
00833       } else
00834          break;
00835    }
00836 #ifdef HAVE_PRI
00837    if (pri)
00838       ast_mutex_lock(&pri->lock);
00839 #endif      
00840 }
00841 
00842 static int restore_gains(struct zt_pvt *p);
00843 
00844 static void swap_subs(struct zt_pvt *p, int a, int b)
00845 {
00846    int tchan;
00847    int tinthreeway;
00848    struct ast_channel *towner;
00849 
00850    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00851 
00852    tchan = p->subs[a].chan;
00853    towner = p->subs[a].owner;
00854    tinthreeway = p->subs[a].inthreeway;
00855 
00856    p->subs[a].chan = p->subs[b].chan;
00857    p->subs[a].owner = p->subs[b].owner;
00858    p->subs[a].inthreeway = p->subs[b].inthreeway;
00859 
00860    p->subs[b].chan = tchan;
00861    p->subs[b].owner = towner;
00862    p->subs[b].inthreeway = tinthreeway;
00863 
00864    if (p->subs[a].owner) 
00865       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00866    if (p->subs[b].owner) 
00867       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00868    wakeup_sub(p, a, NULL);
00869    wakeup_sub(p, b, NULL);
00870 }
00871 
00872 static int zt_open(char *fn)
00873 {
00874    int fd;
00875    int isnum;
00876    int chan = 0;
00877    int bs;
00878    int x;
00879    isnum = 1;
00880    for (x = 0; x < strlen(fn); x++) {
00881       if (!isdigit(fn[x])) {
00882          isnum = 0;
00883          break;
00884       }
00885    }
00886    if (isnum) {
00887       chan = atoi(fn);
00888       if (chan < 1) {
00889          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00890          return -1;
00891       }
00892       fn = "/dev/zap/channel";
00893    }
00894    fd = open(fn, O_RDWR | O_NONBLOCK);
00895    if (fd < 0) {
00896       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00897       return -1;
00898    }
00899    if (chan) {
00900       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00901          x = errno;
00902          close(fd);
00903          errno = x;
00904          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00905          return -1;
00906       }
00907    }
00908    bs = READ_SIZE;
00909    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
00910       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
00911       x = errno;
00912       close(fd);
00913       errno = x;
00914       return -1;
00915    }
00916    return fd;
00917 }
00918 
00919 static void zt_close(int fd)
00920 {
00921    if (fd > 0)
00922       close(fd);
00923 }
00924 
00925 static int zt_setlinear(int zfd, int linear)
00926 {
00927    int res;
00928    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00929    if (res)
00930       return res;
00931    return 0;
00932 }
00933 
00934 
00935 static int alloc_sub(struct zt_pvt *p, int x)
00936 {
00937    ZT_BUFFERINFO bi;
00938    int res;
00939    if (p->subs[x].zfd < 0) {
00940       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00941       if (p->subs[x].zfd > -1) {
00942          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00943          if (!res) {
00944             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00945             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00946             bi.numbufs = numbufs;
00947             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
00948             if (res < 0) {
00949                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
00950             }
00951          } else 
00952             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
00953          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
00954             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
00955             zt_close(p->subs[x].zfd);
00956             p->subs[x].zfd = -1;
00957             return -1;
00958          }
00959          if (option_debug)
00960             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
00961          return 0;
00962       } else
00963          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00964       return -1;
00965    }
00966    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
00967    return -1;
00968 }
00969 
00970 static int unalloc_sub(struct zt_pvt *p, int x)
00971 {
00972    if (!x) {
00973       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
00974       return -1;
00975    }
00976    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
00977    if (p->subs[x].zfd > -1) {
00978       zt_close(p->subs[x].zfd);
00979    }
00980    p->subs[x].zfd = -1;
00981    p->subs[x].linear = 0;
00982    p->subs[x].chan = 0;
00983    p->subs[x].owner = NULL;
00984    p->subs[x].inthreeway = 0;
00985    p->polarity = POLARITY_IDLE;
00986    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
00987    return 0;
00988 }
00989 
00990 static int digit_to_dtmfindex(char digit)
00991 {
00992    if (isdigit(digit))
00993       return ZT_TONE_DTMF_BASE + (digit - '0');
00994    else if (digit >= 'A' && digit <= 'D')
00995       return ZT_TONE_DTMF_A + (digit - 'A');
00996    else if (digit >= 'a' && digit <= 'd')
00997       return ZT_TONE_DTMF_A + (digit - 'a');
00998    else if (digit == '*')
00999       return ZT_TONE_DTMF_s;
01000    else if (digit == '#')
01001       return ZT_TONE_DTMF_p;
01002    else
01003       return -1;
01004 }
01005 
01006 static int zt_digit_begin(struct ast_channel *chan, char digit)
01007 {
01008    struct zt_pvt *pvt;
01009    int index;
01010    int dtmf = -1;
01011    
01012    pvt = chan->tech_pvt;
01013 
01014    ast_mutex_lock(&pvt->lock);
01015 
01016    index = zt_get_index(chan, pvt, 0);
01017 
01018    if ((index != SUB_REAL) || !pvt->owner)
01019       goto out;
01020 
01021 #ifdef HAVE_PRI
01022    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01023       if (pvt->setup_ack) {
01024          if (!pri_grab(pvt, pvt->pri)) {
01025             pri_information(pvt->pri->pri, pvt->call, digit);
01026             pri_rel(pvt->pri);
01027          } else
01028             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01029       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01030          int res;
01031          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01032          res = strlen(pvt->dialdest);
01033          pvt->dialdest[res++] = digit;
01034          pvt->dialdest[res] = '\0';
01035       }
01036       goto out;
01037    }
01038 #endif
01039    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01040       goto out;
01041 
01042    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01043       int res;
01044       ZT_DIAL_OPERATION zo = {
01045          .op = ZT_DIAL_OP_APPEND,
01046          .dialstr[0] = 'T',
01047          .dialstr[1] = digit,
01048          .dialstr[2] = 0,
01049       };
01050       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01051          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01052       else
01053          pvt->dialing = 1;
01054    } else {
01055       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01056       pvt->dialing = 1;
01057       pvt->begindigit = digit;
01058    }
01059 
01060 out:
01061    ast_mutex_unlock(&pvt->lock);
01062 
01063    return 0;
01064 }
01065 
01066 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01067 {
01068    struct zt_pvt *pvt;
01069    int res = 0;
01070    int index;
01071    int x;
01072    
01073    pvt = chan->tech_pvt;
01074 
01075    ast_mutex_lock(&pvt->lock);
01076    
01077    index = zt_get_index(chan, pvt, 0);
01078 
01079    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01080       goto out;
01081 
01082 #ifdef HAVE_PRI
01083    /* This means that the digit was already sent via PRI signalling */
01084    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01085       goto out;
01086 #endif
01087 
01088    if (pvt->begindigit) {
01089       x = -1;
01090       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01091       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01092       pvt->dialing = 0;
01093       pvt->begindigit = 0;
01094    }
01095 
01096 out:
01097    ast_mutex_unlock(&pvt->lock);
01098 
01099    return res;
01100 }
01101 
01102 static char *events[] = {
01103    "No event",
01104    "On hook",
01105    "Ring/Answered",
01106    "Wink/Flash",
01107    "Alarm",
01108    "No more alarm",
01109    "HDLC Abort",
01110    "HDLC Overrun",
01111    "HDLC Bad FCS",
01112    "Dial Complete",
01113    "Ringer On",
01114    "Ringer Off",
01115    "Hook Transition Complete",
01116    "Bits Changed",
01117    "Pulse Start",
01118    "Timer Expired",
01119    "Timer Ping",
01120    "Polarity Reversal",
01121    "Ring Begin",
01122 };
01123 
01124 static struct {
01125    int alarm;
01126    char *name;
01127 } alarms[] = {
01128    { ZT_ALARM_RED, "Red Alarm" },
01129    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01130    { ZT_ALARM_BLUE, "Blue Alarm" },
01131    { ZT_ALARM_RECOVER, "Recovering" },
01132    { ZT_ALARM_LOOPBACK, "Loopback" },
01133    { ZT_ALARM_NOTOPEN, "Not Open" },
01134    { ZT_ALARM_NONE, "None" },
01135 };
01136 
01137 static char *alarm2str(int alarm)
01138 {
01139    int x;
01140    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01141       if (alarms[x].alarm & alarm)
01142          return alarms[x].name;
01143    }
01144    return alarm ? "Unknown Alarm" : "No Alarm";
01145 }
01146 
01147 static char *event2str(int event)
01148 {
01149    static char buf[256];
01150    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01151       return events[event];
01152    sprintf(buf, "Event %d", event); /* safe */
01153    return buf;
01154 }
01155 
01156 #ifdef HAVE_PRI
01157 static char *dialplan2str(int dialplan)
01158 {
01159    if (dialplan == -1) {
01160       return("Dynamically set dialplan in ISDN");
01161    }
01162    return (pri_plan2str(dialplan));
01163 }
01164 #endif
01165 
01166 static char *zap_sig2str(int sig)
01167 {
01168    static char buf[256];
01169    switch (sig) {
01170    case SIG_EM:
01171       return "E & M Immediate";
01172    case SIG_EMWINK:
01173       return "E & M Wink";
01174    case SIG_EM_E1:
01175       return "E & M E1";
01176    case SIG_FEATD:
01177       return "Feature Group D (DTMF)";
01178    case SIG_FEATDMF:
01179       return "Feature Group D (MF)";
01180    case SIG_FEATDMF_TA:
01181       return "Feature Groud D (MF) Tandem Access";
01182    case SIG_FEATB:
01183       return "Feature Group B (MF)";
01184    case SIG_E911:
01185       return "E911 (MF)";
01186    case SIG_FGC_CAMA:
01187       return "FGC/CAMA (Dialpulse)";
01188    case SIG_FGC_CAMAMF:
01189       return "FGC/CAMA (MF)";
01190    case SIG_FXSLS:
01191       return "FXS Loopstart";
01192    case SIG_FXSGS:
01193       return "FXS Groundstart";
01194    case SIG_FXSKS:
01195       return "FXS Kewlstart";
01196    case SIG_FXOLS:
01197       return "FXO Loopstart";
01198    case SIG_FXOGS:
01199       return "FXO Groundstart";
01200    case SIG_FXOKS:
01201       return "FXO Kewlstart";
01202    case SIG_PRI:
01203       return "ISDN PRI";
01204    case SIG_SF:
01205       return "SF (Tone) Immediate";
01206    case SIG_SFWINK:
01207       return "SF (Tone) Wink";
01208    case SIG_SF_FEATD:
01209       return "SF (Tone) with Feature Group D (DTMF)";
01210    case SIG_SF_FEATDMF:
01211       return "SF (Tone) with Feature Group D (MF)";
01212    case SIG_SF_FEATB:
01213       return "SF (Tone) with Feature Group B (MF)";
01214    case SIG_GR303FXOKS:
01215       return "GR-303 with FXOKS";
01216    case SIG_GR303FXSKS:
01217       return "GR-303 with FXSKS";
01218    case 0:
01219       return "Pseudo";
01220    default:
01221       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01222       return buf;
01223    }
01224 }
01225 
01226 #define sig2str zap_sig2str
01227 
01228 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01229 {
01230    /* If the conference already exists, and we're already in it
01231       don't bother doing anything */
01232    ZT_CONFINFO zi;
01233    
01234    memset(&zi, 0, sizeof(zi));
01235    zi.chan = 0;
01236 
01237    if (slavechannel > 0) {
01238       /* If we have only one slave, do a digital mon */
01239       zi.confmode = ZT_CONF_DIGITALMON;
01240       zi.confno = slavechannel;
01241    } else {
01242       if (!index) {
01243          /* Real-side and pseudo-side both participate in conference */
01244          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01245             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01246       } else
01247          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01248       zi.confno = p->confno;
01249    }
01250    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01251       return 0;
01252    if (c->zfd < 0)
01253       return 0;
01254    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01255       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01256       return -1;
01257    }
01258    if (slavechannel < 1) {
01259       p->confno = zi.confno;
01260    }
01261    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01262    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01263    return 0;
01264 }
01265 
01266 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01267 {
01268    /* If they're listening to our channel, they're ours */  
01269    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01270       return 1;
01271    /* If they're a talker on our (allocated) conference, they're ours */
01272    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01273       return 1;
01274    return 0;
01275 }
01276 
01277 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01278 {
01279    ZT_CONFINFO zi;
01280    if (/* Can't delete if there's no zfd */
01281       (c->zfd < 0) ||
01282       /* Don't delete from the conference if it's not our conference */
01283       !isourconf(p, c)
01284       /* Don't delete if we don't think it's conferenced at all (implied) */
01285       ) return 0;
01286    memset(&zi, 0, sizeof(zi));
01287    zi.chan = 0;
01288    zi.confno = 0;
01289    zi.confmode = 0;
01290    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01291       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01292       return -1;
01293    }
01294    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01295    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01296    return 0;
01297 }
01298 
01299 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01300 {
01301    int x;
01302    int useslavenative;
01303    struct zt_pvt *slave = NULL;
01304    /* Start out optimistic */
01305    useslavenative = 1;
01306    /* Update conference state in a stateless fashion */
01307    for (x = 0; x < 3; x++) {
01308       /* Any three-way calling makes slave native mode *definitely* out
01309          of the question */
01310       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01311          useslavenative = 0;
01312    }
01313    /* If we don't have any 3-way calls, check to see if we have
01314       precisely one slave */
01315    if (useslavenative) {
01316       for (x = 0; x < MAX_SLAVES; x++) {
01317          if (p->slaves[x]) {
01318             if (slave) {
01319                /* Whoops already have a slave!  No 
01320                   slave native and stop right away */
01321                slave = NULL;
01322                useslavenative = 0;
01323                break;
01324             } else {
01325                /* We have one slave so far */
01326                slave = p->slaves[x];
01327             }
01328          }
01329       }
01330    }
01331    /* If no slave, slave native definitely out */
01332    if (!slave)
01333       useslavenative = 0;
01334    else if (slave->law != p->law) {
01335       useslavenative = 0;
01336       slave = NULL;
01337    }
01338    if (out)
01339       *out = slave;
01340    return useslavenative;
01341 }
01342 
01343 static int reset_conf(struct zt_pvt *p)
01344 {
01345    ZT_CONFINFO zi;
01346    memset(&zi, 0, sizeof(zi));
01347    p->confno = -1;
01348    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01349    if (p->subs[SUB_REAL].zfd > -1) {
01350       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01351          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01352    }
01353    return 0;
01354 }
01355 
01356 static int update_conf(struct zt_pvt *p)
01357 {
01358    int needconf = 0;
01359    int x;
01360    int useslavenative;
01361    struct zt_pvt *slave = NULL;
01362 
01363    useslavenative = isslavenative(p, &slave);
01364    /* Start with the obvious, general stuff */
01365    for (x = 0; x < 3; x++) {
01366       /* Look for three way calls */
01367       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01368          conf_add(p, &p->subs[x], x, 0);
01369          needconf++;
01370       } else {
01371          conf_del(p, &p->subs[x], x);
01372       }
01373    }
01374    /* If we have a slave, add him to our conference now. or DAX
01375       if this is slave native */
01376    for (x = 0; x < MAX_SLAVES; x++) {
01377       if (p->slaves[x]) {
01378          if (useslavenative)
01379             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01380          else {
01381             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01382             needconf++;
01383          }
01384       }
01385    }
01386    /* If we're supposed to be in there, do so now */
01387    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01388       if (useslavenative)
01389          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01390       else {
01391          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01392          needconf++;
01393       }
01394    }
01395    /* If we have a master, add ourselves to his conference */
01396    if (p->master) {
01397       if (isslavenative(p->master, NULL)) {
01398          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01399       } else {
01400          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01401       }
01402    }
01403    if (!needconf) {
01404       /* Nobody is left (or should be left) in our conference.
01405          Kill it. */
01406       p->confno = -1;
01407    }
01408    if (option_debug)
01409       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01410    return 0;
01411 }
01412 
01413 static void zt_enable_ec(struct zt_pvt *p)
01414 {
01415    int x;
01416    int res;
01417    if (!p)
01418       return;
01419    if (p->echocanon) {
01420       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01421       return;
01422    }
01423    if (p->digital) {
01424       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01425       return;
01426    }
01427    if (p->echocancel) {
01428       if (p->sig == SIG_PRI) {
01429          x = 1;
01430          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01431          if (res)
01432             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
01433       }
01434       x = p->echocancel;
01435       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01436       if (res) 
01437          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
01438       else {
01439          p->echocanon = 1;
01440          if (option_debug)
01441             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01442       }
01443    } else if (option_debug)
01444       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01445 }
01446 
01447 static void zt_train_ec(struct zt_pvt *p)
01448 {
01449    int x;
01450    int res;
01451    if (p && p->echocancel && p->echotraining) {
01452       x = p->echotraining;
01453       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01454       if (res)
01455          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01456       else {
01457          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01458       }
01459    } else
01460       ast_log(LOG_DEBUG, "No echo training requested\n");
01461 }
01462 
01463 static void zt_disable_ec(struct zt_pvt *p)
01464 {
01465    int x;
01466    int res;
01467    if (p->echocancel) {
01468       x = 0;
01469       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01470       if (res)
01471          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01472       else if (option_debug)
01473          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01474    }
01475    p->echocanon = 0;
01476 }
01477 
01478 static void fill_txgain(struct zt_gains *g, float gain, int law)
01479 {
01480    int j;
01481    int k;
01482    float linear_gain = pow(10.0, gain / 20.0);
01483 
01484    switch (law) {
01485    case ZT_LAW_ALAW:
01486       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01487          if (gain) {
01488             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01489             if (k > 32767) k = 32767;
01490             if (k < -32767) k = -32767;
01491             g->txgain[j] = AST_LIN2A(k);
01492          } else {
01493             g->txgain[j] = j;
01494          }
01495       }
01496       break;
01497    case ZT_LAW_MULAW:
01498       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01499          if (gain) {
01500             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01501             if (k > 32767) k = 32767;
01502             if (k < -32767) k = -32767;
01503             g->txgain[j] = AST_LIN2MU(k);
01504          } else {
01505             g->txgain[j] = j;
01506          }
01507       }
01508       break;
01509    }
01510 }
01511 
01512 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01513 {
01514    int j;
01515    int k;
01516    float linear_gain = pow(10.0, gain / 20.0);
01517 
01518    switch (law) {
01519    case ZT_LAW_ALAW:
01520       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01521          if (gain) {
01522             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01523             if (k > 32767) k = 32767;
01524             if (k < -32767) k = -32767;
01525             g->rxgain[j] = AST_LIN2A(k);
01526          } else {
01527             g->rxgain[j] = j;
01528          }
01529       }
01530       break;
01531    case ZT_LAW_MULAW:
01532       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01533          if (gain) {
01534             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01535             if (k > 32767) k = 32767;
01536             if (k < -32767) k = -32767;
01537             g->rxgain[j] = AST_LIN2MU(k);
01538          } else {
01539             g->rxgain[j] = j;
01540          }
01541       }
01542       break;
01543    }
01544 }
01545 
01546 static int set_actual_txgain(int fd, int chan, float gain, int law)
01547 {
01548    struct zt_gains g;
01549    int res;
01550 
01551    memset(&g, 0, sizeof(g));
01552    g.chan = chan;
01553    res = ioctl(fd, ZT_GETGAINS, &g);
01554    if (res) {
01555       if (option_debug)
01556          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01557       return res;
01558    }
01559 
01560    fill_txgain(&g, gain, law);
01561 
01562    return ioctl(fd, ZT_SETGAINS, &g);
01563 }
01564 
01565 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01566 {
01567    struct zt_gains g;
01568    int res;
01569 
01570    memset(&g, 0, sizeof(g));
01571    g.chan = chan;
01572    res = ioctl(fd, ZT_GETGAINS, &g);
01573    if (res) {
01574       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01575       return res;
01576    }
01577 
01578    fill_rxgain(&g, gain, law);
01579 
01580    return ioctl(fd, ZT_SETGAINS, &g);
01581 }
01582 
01583 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01584 {
01585    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01586 }
01587 
01588 static int bump_gains(struct zt_pvt *p)
01589 {
01590    int res;
01591 
01592    /* Bump receive gain by 5.0db */
01593    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01594    if (res) {
01595       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01596       return -1;
01597    }
01598 
01599    return 0;
01600 }
01601 
01602 static int restore_gains(struct zt_pvt *p)
01603 {
01604    int res;
01605 
01606    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01607    if (res) {
01608       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01609       return -1;
01610    }
01611 
01612    return 0;
01613 }
01614 
01615 static inline int zt_set_hook(int fd, int hs)
01616 {
01617    int x, res;
01618 
01619    x = hs;
01620    res = ioctl(fd, ZT_HOOK, &x);
01621 
01622    if (res < 0) {
01623       if (errno == EINPROGRESS)
01624          return 0;
01625       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01626    }
01627 
01628    return res;
01629 }
01630 
01631 static inline int zt_confmute(struct zt_pvt *p, int muted)
01632 {
01633    int x, y, res;
01634    x = muted;
01635    if (p->sig == SIG_PRI) {
01636       y = 1;
01637       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01638       if (res)
01639          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01640    }
01641    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01642    if (res < 0)
01643       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01644    return res;
01645 }
01646 
01647 static int save_conference(struct zt_pvt *p)
01648 {
01649    struct zt_confinfo c;
01650    int res;
01651    if (p->saveconf.confmode) {
01652       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01653       return -1;
01654    }
01655    p->saveconf.chan = 0;
01656    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01657    if (res) {
01658       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01659       p->saveconf.confmode = 0;
01660       return -1;
01661    }
01662    c.chan = 0;
01663    c.confno = 0;
01664    c.confmode = ZT_CONF_NORMAL;
01665    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01666    if (res) {
01667       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01668       return -1;
01669    }
01670    if (option_debug)
01671       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01672    return 0;
01673 }
01674 
01675 static int restore_conference(struct zt_pvt *p)
01676 {
01677    int res;
01678    if (p->saveconf.confmode) {
01679       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01680       p->saveconf.confmode = 0;
01681       if (res) {
01682          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01683          return -1;
01684       }
01685    }
01686    if (option_debug)
01687       ast_log(LOG_DEBUG, "Restored conferencing\n");
01688    return 0;
01689 }
01690 
01691 static int send_callerid(struct zt_pvt *p);
01692 
01693 static int send_cwcidspill(struct zt_pvt *p)
01694 {
01695    p->callwaitcas = 0;
01696    p->cidcwexpire = 0;
01697    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01698       return -1;
01699    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01700    /* Make sure we account for the end */
01701    p->cidlen += READ_SIZE * 4;
01702    p->cidpos = 0;
01703    send_callerid(p);
01704    if (option_verbose > 2)
01705       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01706    return 0;
01707 }
01708 
01709 static int has_voicemail(struct zt_pvt *p)
01710 {
01711 
01712    return ast_app_has_voicemail(p->mailbox, NULL);
01713 }
01714 
01715 static int send_callerid(struct zt_pvt *p)
01716 {
01717    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01718    int res;
01719    /* Take out of linear mode if necessary */
01720    if (p->subs[SUB_REAL].linear) {
01721       p->subs[SUB_REAL].linear = 0;
01722       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01723    }
01724    while (p->cidpos < p->cidlen) {
01725       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01726       if (res < 0) {
01727          if (errno == EAGAIN)
01728             return 0;
01729          else {
01730             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01731             return -1;
01732          }
01733       }
01734       if (!res)
01735          return 0;
01736       p->cidpos += res;
01737    }
01738    free(p->cidspill);
01739    p->cidspill = NULL;
01740    if (p->callwaitcas) {
01741       /* Wait for CID/CW to expire */
01742       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01743    } else
01744       restore_conference(p);
01745    return 0;
01746 }
01747 
01748 static int zt_callwait(struct ast_channel *ast)
01749 {
01750    struct zt_pvt *p = ast->tech_pvt;
01751    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01752    if (p->cidspill) {
01753       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01754       free(p->cidspill);
01755    }
01756    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01757       return -1;
01758    save_conference(p);
01759    /* Silence */
01760    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01761    if (!p->callwaitrings && p->callwaitingcallerid) {
01762       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01763       p->callwaitcas = 1;
01764       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01765    } else {
01766       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01767       p->callwaitcas = 0;
01768       p->cidlen = 2400 + READ_SIZE * 4;
01769    }
01770    p->cidpos = 0;
01771    send_callerid(p);
01772    
01773    return 0;
01774 }
01775 
01776 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01777 {
01778    struct zt_pvt *p = ast->tech_pvt;
01779    int x, res, index,mysig;
01780    char *c, *n, *l;
01781 #ifdef HAVE_PRI
01782    char *s = NULL;
01783 #endif
01784    char dest[256]; /* must be same length as p->dialdest */
01785    ast_mutex_lock(&p->lock);
01786    ast_copy_string(dest, rdest, sizeof(dest));
01787    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01788    if ((ast->_state == AST_STATE_BUSY)) {
01789       p->subs[SUB_REAL].needbusy = 1;
01790       ast_mutex_unlock(&p->lock);
01791       return 0;
01792    }
01793    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01794       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01795       ast_mutex_unlock(&p->lock);
01796       return -1;
01797    }
01798    p->dialednone = 0;
01799    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01800    {
01801       /* Special pseudo -- automatically up */
01802       ast_setstate(ast, AST_STATE_UP); 
01803       ast_mutex_unlock(&p->lock);
01804       return 0;
01805    }
01806    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01807    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01808    if (res)
01809       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01810    p->outgoing = 1;
01811 
01812    set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01813 
01814    mysig = p->sig;
01815    if (p->outsigmod > -1)
01816       mysig = p->outsigmod;
01817 
01818    switch (mysig) {
01819    case SIG_FXOLS:
01820    case SIG_FXOGS:
01821    case SIG_FXOKS:
01822       if (p->owner == ast) {
01823          /* Normal ring, on hook */
01824          
01825          /* Don't send audio while on hook, until the call is answered */
01826          p->dialing = 1;
01827          if (p->use_callerid) {
01828             /* Generate the Caller-ID spill if desired */
01829             if (p->cidspill) {
01830                ast_log(LOG_WARNING, "cidspill already exists??\n");
01831                free(p->cidspill);
01832             }
01833             p->callwaitcas = 0;
01834             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01835                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01836                p->cidpos = 0;
01837                send_callerid(p);
01838             }
01839          }
01840          /* Choose proper cadence */
01841          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01842             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01843                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01844             p->cidrings = cidrings[p->distinctivering - 1];
01845          } else {
01846             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01847                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01848             p->cidrings = p->sendcalleridafter;
01849          }
01850 
01851          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01852          c = strchr(dest, '/');
01853          if (c)
01854             c++;
01855          if (c && (strlen(c) < p->stripmsd)) {
01856             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01857             c = NULL;
01858          }
01859          if (c) {
01860             p->dop.op = ZT_DIAL_OP_REPLACE;
01861             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01862             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01863          } else {
01864             p->dop.dialstr[0] = '\0';
01865          }
01866          x = ZT_RING;
01867          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01868             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01869             ast_mutex_unlock(&p->lock);
01870             return -1;
01871          }
01872          p->dialing = 1;
01873       } else {
01874          /* Call waiting call */
01875          p->callwaitrings = 0;
01876          if (ast->cid.cid_num)
01877             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01878          else
01879             p->callwait_num[0] = '\0';
01880          if (ast->cid.cid_name)
01881             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01882          else
01883             p->callwait_name[0] = '\0';
01884          /* Call waiting tone instead */
01885          if (zt_callwait(ast)) {
01886             ast_mutex_unlock(&p->lock);
01887             return -1;
01888          }
01889          /* Make ring-back */
01890          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01891             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01892             
01893       }
01894       n = ast->cid.cid_name;
01895       l = ast->cid.cid_num;
01896       if (l)
01897          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01898       else
01899          p->lastcid_num[0] = '\0';
01900       if (n)
01901          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01902       else
01903          p->lastcid_name[0] = '\0';
01904       ast_setstate(ast, AST_STATE_RINGING);
01905       index = zt_get_index(ast, p, 0);
01906       if (index > -1) {
01907          p->subs[index].needringing = 1;
01908       }
01909       break;
01910    case SIG_FXSLS:
01911    case SIG_FXSGS:
01912    case SIG_FXSKS:
01913    case SIG_EMWINK:
01914    case SIG_EM:
01915    case SIG_EM_E1:
01916    case SIG_FEATD:
01917    case SIG_FEATDMF:
01918    case SIG_E911:
01919    case SIG_FGC_CAMA:
01920    case SIG_FGC_CAMAMF:
01921    case SIG_FEATB:
01922    case SIG_SFWINK:
01923    case SIG_SF:
01924    case SIG_SF_FEATD:
01925    case SIG_SF_FEATDMF:
01926    case SIG_FEATDMF_TA:
01927    case SIG_SF_FEATB:
01928       c = strchr(dest, '/');
01929       if (c)
01930          c++;
01931       else
01932          c = "";
01933       if (strlen(c) < p->stripmsd) {
01934          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01935          ast_mutex_unlock(&p->lock);
01936          return -1;
01937       }
01938 #ifdef HAVE_PRI
01939       /* Start the trunk, if not GR-303 */
01940       if (!p->pri) {
01941 #endif
01942          x = ZT_START;
01943          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
01944          if (res < 0) {
01945             if (errno != EINPROGRESS) {
01946                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
01947                ast_mutex_unlock(&p->lock);
01948                return -1;
01949             }
01950          }
01951 #ifdef HAVE_PRI
01952       }
01953 #endif
01954       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
01955       p->dop.op = ZT_DIAL_OP_REPLACE;
01956 
01957       c += p->stripmsd;
01958 
01959       switch (mysig) {
01960       case SIG_FEATD:
01961          l = ast->cid.cid_num;
01962          if (l) 
01963             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
01964          else
01965             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
01966          break;
01967       case SIG_FEATDMF:
01968          l = ast->cid.cid_num;
01969          if (l) 
01970             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
01971          else
01972             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
01973          break;
01974       case SIG_FEATDMF_TA:
01975       {
01976          const char *cic, *ozz;
01977 
01978          /* If you have to go through a Tandem Access point you need to use this */
01979          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
01980          if (!ozz)
01981             ozz = defaultozz;
01982          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
01983          if (!cic)
01984             cic = defaultcic;
01985          if (!ozz || !cic) {
01986             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
01987             ast_mutex_unlock(&p->lock);
01988             return -1;
01989          }
01990          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
01991          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
01992          p->whichwink = 0;
01993       }
01994          break;
01995       case SIG_E911:
01996          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
01997          break;
01998       case SIG_FGC_CAMA:
01999          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02000          break;
02001       case SIG_FGC_CAMAMF:
02002       case SIG_FEATB:
02003          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02004          break;
02005       default:
02006          if (p->pulse)
02007             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02008          else
02009             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02010          break;
02011       }
02012 
02013       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02014          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02015          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02016          p->echorest[sizeof(p->echorest) - 1] = '\0';
02017          p->echobreak = 1;
02018          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02019       } else
02020          p->echobreak = 0;
02021       if (!res) {
02022          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02023             x = ZT_ONHOOK;
02024             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02025             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02026             ast_mutex_unlock(&p->lock);
02027             return -1;
02028          }
02029       } else
02030          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02031       p->dialing = 1;
02032       if (ast_strlen_zero(c))
02033          p->dialednone = 1;
02034       ast_setstate(ast, AST_STATE_DIALING);
02035       break;
02036    case 0:
02037       /* Special pseudo -- automatically up*/
02038       ast_setstate(ast, AST_STATE_UP);
02039       break;      
02040    case SIG_PRI:
02041       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02042       p->dialdest[0] = '\0';
02043       break;
02044    default:
02045       ast_log(LOG_DEBUG, "not yet implemented\n");
02046       ast_mutex_unlock(&p->lock);
02047       return -1;
02048    }
02049 #ifdef HAVE_PRI
02050    if (p->pri) {
02051       struct pri_sr *sr;
02052 #ifdef SUPPORT_USERUSER
02053       const char *useruser;
02054 #endif
02055       int pridialplan;
02056       int dp_strip;
02057       int prilocaldialplan;
02058       int ldp_strip;
02059       int exclusive;
02060       const char *rr_str;
02061       int redirect_reason;
02062 
02063       c = strchr(dest, '/');
02064       if (c)
02065          c++;
02066       else
02067          c = dest;
02068 
02069       l = NULL;
02070       n = NULL;
02071 
02072       if (!p->hidecallerid) {
02073          l = ast->cid.cid_num;
02074          if (!p->hidecalleridname) {
02075             n = ast->cid.cid_name;
02076          }
02077       }
02078 
02079 
02080       if (strlen(c) < p->stripmsd) {
02081          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02082          ast_mutex_unlock(&p->lock);
02083          return -1;
02084       }
02085       if (mysig != SIG_FXSKS) {
02086          p->dop.op = ZT_DIAL_OP_REPLACE;
02087          s = strchr(c + p->stripmsd, 'w');
02088          if (s) {
02089             if (strlen(s) > 1)
02090                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02091             else
02092                p->dop.dialstr[0] = '\0';
02093             *s = '\0';
02094          } else {
02095             p->dop.dialstr[0] = '\0';
02096          }
02097       }
02098       if (pri_grab(p, p->pri)) {
02099          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02100          ast_mutex_unlock(&p->lock);
02101          return -1;
02102       }
02103       if (!(p->call = pri_new_call(p->pri->pri))) {
02104          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02105          pri_rel(p->pri);
02106          ast_mutex_unlock(&p->lock);
02107          return -1;
02108       }
02109       if (!(sr = pri_sr_new())) {
02110          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02111          pri_rel(p->pri);
02112          ast_mutex_unlock(&p->lock);
02113       }
02114       if (p->bearer || (mysig == SIG_FXSKS)) {
02115          if (p->bearer) {
02116             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);
02117             p->bearer->call = p->call;
02118          } else
02119             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02120          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02121       }
02122       p->digital = IS_DIGITAL(ast->transfercapability);
02123       /* Add support for exclusive override */
02124       if (p->priexclusive)
02125          exclusive = 1;
02126       else {
02127       /* otherwise, traditional behavior */
02128          if (p->pri->nodetype == PRI_NETWORK)
02129             exclusive = 0;
02130          else
02131             exclusive = 1;
02132       }
02133       
02134       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02135       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02136                (p->digital ? -1 : 
02137                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02138       if (p->pri->facilityenable)
02139          pri_facility_enable(p->pri->pri);
02140 
02141       if (option_verbose > 2)
02142          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02143       dp_strip = 0;
02144       pridialplan = p->pri->dialplan - 1;
02145       if (pridialplan == -2) { /* compute dynamically */
02146          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02147             dp_strip = strlen(p->pri->internationalprefix);
02148             pridialplan = PRI_INTERNATIONAL_ISDN;
02149          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02150             dp_strip = strlen(p->pri->nationalprefix);
02151             pridialplan = PRI_NATIONAL_ISDN;
02152          } else {
02153             pridialplan = PRI_LOCAL_ISDN;
02154          }
02155       }
02156       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02157 
02158       ldp_strip = 0;
02159       prilocaldialplan = p->pri->localdialplan - 1;
02160       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02161          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02162             ldp_strip = strlen(p->pri->internationalprefix);
02163             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02164          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02165             ldp_strip = strlen(p->pri->nationalprefix);
02166             prilocaldialplan = PRI_NATIONAL_ISDN;
02167          } else {
02168             prilocaldialplan = PRI_LOCAL_ISDN;
02169          }
02170       }
02171       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02172          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02173       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02174          if (!strcasecmp(rr_str, "UNKNOWN"))
02175             redirect_reason = 0;
02176          else if (!strcasecmp(rr_str, "BUSY"))
02177             redirect_reason = 1;
02178          else if (!strcasecmp(rr_str, "NO_REPLY"))
02179             redirect_reason = 2;
02180          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02181             redirect_reason = 15;
02182          else
02183             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02184       } else
02185          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02186       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02187 
02188 #ifdef SUPPORT_USERUSER
02189       /* User-user info */
02190       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02191 
02192       if (useruser)
02193          pri_sr_set_useruser(sr, useruser);
02194 #endif
02195 
02196       if (pri_setup(p->pri->pri, p->call, sr)) {
02197          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02198             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02199          pri_rel(p->pri);
02200          ast_mutex_unlock(&p->lock);
02201          pri_sr_free(sr);
02202          return -1;
02203       }
02204       pri_sr_free(sr);
02205       ast_setstate(ast, AST_STATE_DIALING);
02206       pri_rel(p->pri);
02207    }
02208 #endif      
02209    ast_mutex_unlock(&p->lock);
02210    return 0;
02211 }
02212 
02213 static void destroy_zt_pvt(struct zt_pvt **pvt)
02214 {
02215    struct zt_pvt *p = *pvt;
02216    /* Remove channel from the list */
02217    if (p->prev)
02218       p->prev->next = p->next;
02219    if (p->next)
02220       p->next->prev = p->prev;
02221    if (p->use_smdi)
02222       ast_smdi_interface_unref(p->smdi_iface);
02223    ast_mutex_destroy(&p->lock);
02224    free(p);
02225    *pvt = NULL;
02226 }
02227 
02228 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02229 {
02230    int owned = 0;
02231    int i = 0;
02232 
02233    if (!now) {
02234       if (cur->owner) {
02235          owned = 1;
02236       }
02237 
02238       for (i = 0; i < 3; i++) {
02239          if (cur->subs[i].owner) {
02240             owned = 1;
02241          }
02242       }
02243       if (!owned) {
02244          if (prev) {
02245             prev->next = cur->next;
02246             if (prev->next)
02247                prev->next->prev = prev;
02248             else
02249                ifend = prev;
02250          } else {
02251             iflist = cur->next;
02252             if (iflist)
02253                iflist->prev = NULL;
02254             else
02255                ifend = NULL;
02256          }
02257          if (cur->subs[SUB_REAL].zfd > -1) {
02258             zt_close(cur->subs[SUB_REAL].zfd);
02259          }
02260          destroy_zt_pvt(&cur);
02261       }
02262    } else {
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    return 0;
02282 }
02283 
02284 #ifdef HAVE_PRI
02285 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02286 
02287 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02288 
02289 static char *zap_send_keypad_facility_descrip = 
02290 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02291 "  IE over the current channel.\n";
02292 
02293 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02294 {
02295    /* Data will be our digit string */
02296    struct zt_pvt *p;
02297    char *digits = (char *) data;
02298 
02299    if (ast_strlen_zero(digits)) {
02300       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02301       return -1;
02302    }
02303 
02304    p = (struct zt_pvt *)chan->tech_pvt;
02305 
02306    if (!p) {
02307       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02308       return -1;
02309    }
02310 
02311    ast_mutex_lock(&p->lock);
02312 
02313    if (!p->pri || !p->call) {
02314       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02315       ast_mutex_unlock(&p->lock);
02316       return -1;
02317    }
02318 
02319    if (!pri_grab(p, p->pri)) {
02320       pri_keypad_facility(p->pri->pri, p->call, digits);
02321       pri_rel(p->pri);
02322    } else {
02323       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02324       ast_mutex_unlock(&p->lock);
02325       return -1;
02326    }
02327 
02328    ast_mutex_unlock(&p->lock);
02329 
02330    return 0;
02331 }
02332 
02333 static int pri_is_up(struct zt_pri *pri)
02334 {
02335    int x;
02336    for (x = 0; x < NUM_DCHANS; x++) {
02337       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02338          return 1;
02339    }
02340    return 0;
02341 }
02342 
02343 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02344 {
02345    bearer->owner = &inuse;
02346    bearer->realcall = crv;
02347    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02348    if (crv->subs[SUB_REAL].owner)
02349       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02350    crv->bearer = bearer;
02351    crv->call = bearer->call;
02352    crv->pri = pri;
02353    return 0;
02354 }
02355 
02356 static char *pri_order(int level)
02357 {
02358    switch (level) {
02359    case 0:
02360       return "Primary";
02361    case 1:
02362       return "Secondary";
02363    case 2:
02364       return "Tertiary";
02365    case 3:
02366       return "Quaternary";
02367    default:
02368       return "<Unknown>";
02369    }     
02370 }
02371 
02372 /* Returns fd of the active dchan */
02373 static int pri_active_dchan_fd(struct zt_pri *pri)
02374 {
02375    int x = -1;
02376 
02377    for (x = 0; x < NUM_DCHANS; x++) {
02378       if ((pri->dchans[x] == pri->pri))
02379          break;
02380    }
02381 
02382    return pri->fds[x];
02383 }
02384 
02385 static int pri_find_dchan(struct zt_pri *pri)
02386 {
02387    int oldslot = -1;
02388    struct pri *old;
02389    int newslot = -1;
02390    int x;
02391    old = pri->pri;
02392    for (x = 0; x < NUM_DCHANS; x++) {
02393       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02394          newslot = x;
02395       if (pri->dchans[x] == old) {
02396          oldslot = x;
02397       }
02398    }
02399    if (newslot < 0) {
02400       newslot = 0;
02401       ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02402          pri->dchannels[newslot]);
02403    }
02404    if (old && (oldslot != newslot))
02405       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02406          pri->dchannels[oldslot], pri->dchannels[newslot]);
02407    pri->pri = pri->dchans[newslot];
02408    return 0;
02409 }
02410 #endif
02411 
02412 static int zt_hangup(struct ast_channel *ast)
02413 {
02414    int res;
02415    int index,x, law;
02416    /*static int restore_gains(struct zt_pvt *p);*/
02417    struct zt_pvt *p = ast->tech_pvt;
02418    struct zt_pvt *tmp = NULL;
02419    struct zt_pvt *prev = NULL;
02420    ZT_PARAMS par;
02421 
02422    if (option_debug)
02423       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02424    if (!ast->tech_pvt) {
02425       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02426       return 0;
02427    }
02428    
02429    ast_mutex_lock(&p->lock);
02430    
02431    index = zt_get_index(ast, p, 1);
02432 
02433    if (p->sig == SIG_PRI) {
02434       x = 1;
02435       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02436    }
02437 
02438    x = 0;
02439    zt_confmute(p, 0);
02440    restore_gains(p);
02441    if (p->origcid_num) {
02442       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02443       free(p->origcid_num);
02444       p->origcid_num = NULL;
02445    }  
02446    if (p->origcid_name) {
02447       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02448       free(p->origcid_name);
02449       p->origcid_name = NULL;
02450    }  
02451    if (p->dsp)
02452       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02453    if (p->exten)
02454       p->exten[0] = '\0';
02455 
02456    if (option_debug)
02457       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02458       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02459    p->ignoredtmf = 0;
02460    
02461    if (index > -1) {
02462       /* Real channel, do some fixup */
02463       p->subs[index].owner = NULL;
02464       p->subs[index].needanswer = 0;
02465       p->subs[index].needflash = 0;
02466       p->subs[index].needringing = 0;
02467       p->subs[index].needbusy = 0;
02468       p->subs[index].needcongestion = 0;
02469       p->subs[index].linear = 0;
02470       p->subs[index].needcallerid = 0;
02471       p->polarity = POLARITY_IDLE;
02472       zt_setlinear(p->subs[index].zfd, 0);
02473       if (index == SUB_REAL) {
02474          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02475             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02476             if (p->subs[SUB_CALLWAIT].inthreeway) {
02477                /* We had flipped over to answer a callwait and now it's gone */
02478                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02479                /* Move to the call-wait, but un-own us until they flip back. */
02480                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02481                unalloc_sub(p, SUB_CALLWAIT);
02482                p->owner = NULL;
02483             } else {
02484                /* The three way hung up, but we still have a call wait */
02485                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02486                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02487                unalloc_sub(p, SUB_THREEWAY);
02488                if (p->subs[SUB_REAL].inthreeway) {
02489                   /* This was part of a three way call.  Immediately make way for
02490                      another call */
02491                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02492                   p->owner = p->subs[SUB_REAL].owner;
02493                } else {
02494                   /* This call hasn't been completed yet...  Set owner to NULL */
02495                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02496                   p->owner = NULL;
02497                }
02498                p->subs[SUB_REAL].inthreeway = 0;
02499             }
02500          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02501             /* Move to the call-wait and switch back to them. */
02502             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02503             unalloc_sub(p, SUB_CALLWAIT);
02504             p->owner = p->subs[SUB_REAL].owner;
02505             if (p->owner->_state != AST_STATE_UP)
02506                p->subs[SUB_REAL].needanswer = 1;
02507             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02508                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02509          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02510             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02511             unalloc_sub(p, SUB_THREEWAY);
02512             if (p->subs[SUB_REAL].inthreeway) {
02513                /* This was part of a three way call.  Immediately make way for
02514                   another call */
02515                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02516                p->owner = p->subs[SUB_REAL].owner;
02517             } else {
02518                /* This call hasn't been completed yet...  Set owner to NULL */
02519                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02520                p->owner = NULL;
02521             }
02522             p->subs[SUB_REAL].inthreeway = 0;
02523          }
02524       } else if (index == SUB_CALLWAIT) {
02525          /* Ditch the holding callwait call, and immediately make it availabe */
02526          if (p->subs[SUB_CALLWAIT].inthreeway) {
02527             /* This is actually part of a three way, placed on hold.  Place the third part
02528                on music on hold now */
02529             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02530                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02531                   S_OR(p->mohsuggest, NULL),
02532                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02533             }
02534             p->subs[SUB_THREEWAY].inthreeway = 0;
02535             /* Make it the call wait now */
02536             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02537             unalloc_sub(p, SUB_THREEWAY);
02538          } else
02539             unalloc_sub(p, SUB_CALLWAIT);
02540       } else if (index == SUB_THREEWAY) {
02541          if (p->subs[SUB_CALLWAIT].inthreeway) {
02542             /* The other party of the three way call is currently in a call-wait state.
02543                Start music on hold for them, and take the main guy out of the third call */
02544             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02545                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02546                   S_OR(p->mohsuggest, NULL),
02547                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02548             }
02549             p->subs[SUB_CALLWAIT].inthreeway = 0;
02550          }
02551          p->subs[SUB_REAL].inthreeway = 0;
02552          /* If this was part of a three way call index, let us make
02553             another three way call */
02554          unalloc_sub(p, SUB_THREEWAY);
02555       } else {
02556          /* This wasn't any sort of call, but how are we an index? */
02557          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02558       }
02559    }
02560 
02561    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02562       p->owner = NULL;
02563       p->ringt = 0;
02564       p->distinctivering = 0;
02565       p->confirmanswer = 0;
02566       p->cidrings = 1;
02567       p->outgoing = 0;
02568       p->digital = 0;
02569       p->faxhandled = 0;
02570       p->pulsedial = 0;
02571       p->onhooktime = time(NULL);
02572 #ifdef HAVE_PRI
02573       p->proceeding = 0;
02574       p->progress = 0;
02575       p->alerting = 0;
02576       p->setup_ack = 0;
02577 #endif      
02578       if (p->dsp) {
02579          ast_dsp_free(p->dsp);
02580          p->dsp = NULL;
02581       }
02582 
02583       law = ZT_LAW_DEFAULT;
02584       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02585       if (res < 0) 
02586          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02587       /* Perform low level hangup if no owner left */
02588 #ifdef HAVE_PRI
02589       if (p->pri) {
02590 #ifdef SUPPORT_USERUSER
02591          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02592 #endif
02593 
02594          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02595          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02596             if (!pri_grab(p, p->pri)) {
02597                if (p->alreadyhungup) {
02598                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02599 
02600 #ifdef SUPPORT_USERUSER
02601                   pri_call_set_useruser(p->call, useruser);
02602 #endif
02603 
02604                   pri_hangup(p->pri->pri, p->call, -1);
02605                   p->call = NULL;
02606                   if (p->bearer) 
02607                      p->bearer->call = NULL;
02608                } else {
02609                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02610                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02611                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02612 
02613 #ifdef SUPPORT_USERUSER
02614                   pri_call_set_useruser(p->call, useruser);
02615 #endif
02616 
02617                   p->alreadyhungup = 1;
02618                   if (p->bearer)
02619                      p->bearer->alreadyhungup = 1;
02620                   if (cause) {
02621                      if (atoi(cause))
02622                         icause = atoi(cause);
02623                   }
02624                   pri_hangup(p->pri->pri, p->call, icause);
02625                }
02626                if (res < 0) 
02627                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02628                pri_rel(p->pri);        
02629             } else {
02630                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02631                res = -1;
02632             }
02633          } else {
02634             if (p->bearer)
02635                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02636             p->call = NULL;
02637             res = 0;
02638          }
02639       }
02640 #endif
02641       if (p->sig && (p->sig != SIG_PRI))
02642          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02643       if (res < 0) {
02644          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02645       }
02646       switch (p->sig) {
02647       case SIG_FXOGS:
02648       case SIG_FXOLS:
02649       case SIG_FXOKS:
02650          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02651          if (!res) {
02652 #if 0
02653             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02654 #endif
02655             /* If they're off hook, try playing congestion */
02656             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02657                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02658             else
02659                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02660          }
02661          break;
02662       case SIG_FXSGS:
02663       case SIG_FXSLS:
02664       case SIG_FXSKS:
02665          /* Make sure we're not made available for at least two seconds assuming
02666             we were actually used for an inbound or outbound call. */
02667          if (ast->_state != AST_STATE_RESERVED) {
02668             time(&p->guardtime);
02669             p->guardtime += 2;
02670          }
02671          break;
02672       default:
02673          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02674       }
02675       if (p->cidspill)
02676          free(p->cidspill);
02677       if (p->sig)
02678          zt_disable_ec(p);
02679       x = 0;
02680       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02681       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02682       p->didtdd = 0;
02683       p->cidspill = NULL;
02684       p->callwaitcas = 0;
02685       p->callwaiting = p->permcallwaiting;
02686       p->hidecallerid = p->permhidecallerid;
02687       p->dialing = 0;
02688       p->rdnis[0] = '\0';
02689       update_conf(p);
02690       reset_conf(p);
02691       /* Restore data mode */
02692       if (p->sig == SIG_PRI) {
02693          x = 0;
02694          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02695       }
02696 #ifdef HAVE_PRI
02697       if (p->bearer) {
02698          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02699          /* Free up the bearer channel as well, and
02700             don't use its file descriptor anymore */
02701          update_conf(p->bearer);
02702          reset_conf(p->bearer);
02703          p->bearer->owner = NULL;
02704          p->bearer->realcall = NULL;
02705          p->bearer = NULL;
02706          p->subs[SUB_REAL].zfd = -1;
02707          p->pri = NULL;
02708       }
02709 #endif
02710       restart_monitor();
02711    }
02712 
02713    p->callwaitingrepeat = 0;
02714    p->cidcwexpire = 0;
02715    p->oprmode = 0;
02716    ast->tech_pvt = NULL;
02717    ast_mutex_unlock(&p->lock);
02718    ast_module_unref(ast_module_info->self);
02719    if (option_verbose > 2) 
02720       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02721 
02722    ast_mutex_lock(&iflock);
02723    tmp = iflist;
02724    prev = NULL;
02725    if (p->destroy) {
02726       while (tmp) {
02727          if (tmp == p) {
02728             destroy_channel(prev, tmp, 0);
02729             break;
02730          } else {
02731             prev = tmp;
02732             tmp = tmp->next;
02733          }
02734       }
02735    }
02736    ast_mutex_unlock(&iflock);
02737    return 0;
02738 }
02739 
02740 static int zt_answer(struct ast_channel *ast)
02741 {
02742    struct zt_pvt *p = ast->tech_pvt;
02743    int res = 0;
02744    int index;
02745    int oldstate = ast->_state;
02746    ast_setstate(ast, AST_STATE_UP);
02747    ast_mutex_lock(&p->lock);
02748    index = zt_get_index(ast, p, 0);
02749    if (index < 0)
02750       index = SUB_REAL;
02751    /* nothing to do if a radio channel */
02752    if ((p->radio || (p->oprmode < 0))) {
02753       ast_mutex_unlock(&p->lock);
02754       return 0;
02755    }
02756    switch (p->sig) {
02757    case SIG_FXSLS:
02758    case SIG_FXSGS:
02759    case SIG_FXSKS:
02760       p->ringt = 0;
02761       /* Fall through */
02762    case SIG_EM:
02763    case SIG_EM_E1:
02764    case SIG_EMWINK:
02765    case SIG_FEATD:
02766    case SIG_FEATDMF:
02767    case SIG_FEATDMF_TA:
02768    case SIG_E911:
02769    case SIG_FGC_CAMA:
02770    case SIG_FGC_CAMAMF:
02771    case SIG_FEATB:
02772    case SIG_SF:
02773    case SIG_SFWINK:
02774    case SIG_SF_FEATD:
02775    case SIG_SF_FEATDMF:
02776    case SIG_SF_FEATB:
02777    case SIG_FXOLS:
02778    case SIG_FXOGS:
02779    case SIG_FXOKS:
02780       /* Pick up the line */
02781       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02782       if (p->hanguponpolarityswitch) {
02783          gettimeofday(&p->polaritydelaytv, NULL);
02784       }
02785       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02786       tone_zone_play_tone(p->subs[index].zfd, -1);
02787       p->dialing = 0;
02788       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02789          if (oldstate == AST_STATE_RINGING) {
02790             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02791             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02792             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02793             p->owner = p->subs[SUB_REAL].owner;
02794          }
02795       }
02796       if (p->sig & __ZT_SIG_FXS) {
02797          zt_enable_ec(p);
02798          zt_train_ec(p);
02799       }
02800       break;
02801 #ifdef HAVE_PRI
02802    case SIG_PRI:
02803       /* Send a pri acknowledge */
02804       if (!pri_grab(p, p->pri)) {
02805          p->proceeding = 1;
02806          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02807          pri_rel(p->pri);
02808       } else {
02809          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02810          res = -1;
02811       }
02812       break;
02813 #endif
02814    case 0:
02815       ast_mutex_unlock(&p->lock);
02816       return 0;
02817    default:
02818       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02819       res = -1;
02820    }
02821    ast_mutex_unlock(&p->lock);
02822    return res;
02823 }
02824 
02825 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02826 {
02827    char *cp;
02828    signed char *scp;
02829    int x;
02830    int index;
02831    struct zt_pvt *p = chan->tech_pvt, *pp;
02832    struct oprmode *oprmode;
02833    
02834 
02835    /* all supported options require data */
02836    if (!data || (datalen < 1)) {
02837       errno = EINVAL;
02838       return -1;
02839    }
02840 
02841    switch (option) {
02842    case AST_OPTION_TXGAIN:
02843       scp = (signed char *) data;
02844       index = zt_get_index(chan, p, 0);
02845       if (index < 0) {
02846          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02847          return -1;
02848       }
02849       if (option_debug)
02850          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02851       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02852    case AST_OPTION_RXGAIN:
02853       scp = (signed char *) data;
02854       index = zt_get_index(chan, p, 0);
02855       if (index < 0) {
02856          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
02857          return -1;
02858       }
02859       if (option_debug)
02860          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
02861       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
02862    case AST_OPTION_TONE_VERIFY:
02863       if (!p->dsp)
02864          break;
02865       cp = (char *) data;
02866       switch (*cp) {
02867       case 1:
02868          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
02869          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
02870          break;
02871       case 2:
02872          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
02873          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
02874          break;
02875       default:
02876          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
02877          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
02878          break;
02879       }
02880       break;
02881    case AST_OPTION_TDD:
02882       /* turn on or off TDD */
02883       cp = (char *) data;
02884       p->mate = 0;
02885       if (!*cp) { /* turn it off */
02886          if (option_debug)
02887             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
02888          if (p->tdd)
02889             tdd_free(p->tdd);
02890          p->tdd = 0;
02891          break;
02892       }
02893       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
02894          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
02895       zt_disable_ec(p);
02896       /* otherwise, turn it on */
02897       if (!p->didtdd) { /* if havent done it yet */
02898          unsigned char mybuf[41000], *buf;
02899          int size, res, fd, len;
02900          struct pollfd fds[1];
02901 
02902          buf = mybuf;
02903          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
02904          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
02905          len = 40000;
02906          index = zt_get_index(chan, p, 0);
02907          if (index < 0) {
02908             ast_log(LOG_WARNING, "No index in TDD?\n");
02909             return -1;
02910          }
02911          fd = p->subs[index].zfd;
02912          while (len) {
02913             if (ast_check_hangup(chan))
02914                return -1;
02915             size = len;
02916             if (size > READ_SIZE)
02917                size = READ_SIZE;
02918             fds[0].fd = fd;
02919             fds[0].events = POLLPRI | POLLOUT;
02920             fds[0].revents = 0;
02921             res = poll(fds, 1, -1);
02922             if (!res) {
02923                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
02924                continue;
02925             }
02926             /* if got exception */
02927             if (fds[0].revents & POLLPRI)
02928                return -1;
02929             if (!(fds[0].revents & POLLOUT)) {
02930                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
02931                continue;
02932             }
02933             res = write(fd, buf, size);
02934             if (res != size) {
02935                if (res == -1) return -1;
02936                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
02937                break;
02938             }
02939             len -= size;
02940             buf += size;
02941          }
02942          p->didtdd = 1; /* set to have done it now */    
02943       }
02944       if (*cp == 2) { /* Mate mode */
02945          if (p->tdd)
02946             tdd_free(p->tdd);
02947          p->tdd = 0;
02948          p->mate = 1;
02949          break;
02950       }     
02951       if (!p->tdd) { /* if we dont have one yet */
02952          p->tdd = tdd_new(); /* allocate one */
02953       }     
02954       break;
02955    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
02956       if (!p->dsp)
02957          break;
02958       cp = (char *) data;
02959       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
02960          *cp ? "ON" : "OFF", (int) *cp, chan->name);
02961                 p->dtmfrelax = 0;
02962                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
02963                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
02964       break;
02965    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
02966       cp = (char *) data;
02967       if (!*cp) {    
02968          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
02969          x = 0;
02970          zt_disable_ec(p);
02971       } else {    
02972          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
02973          x = 1;
02974       }
02975       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
02976          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
02977       break;
02978    case AST_OPTION_OPRMODE:  /* Operator services mode */
02979       oprmode = (struct oprmode *) data;
02980       pp = oprmode->peer->tech_pvt;
02981       p->oprmode = pp->oprmode = 0;
02982       /* setup peers */
02983       p->oprpeer = pp;
02984       pp->oprpeer = p;
02985       /* setup modes, if any */
02986       if (oprmode->mode) 
02987       {
02988          pp->oprmode = oprmode->mode;
02989          p->oprmode = -oprmode->mode;
02990       }
02991       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
02992          oprmode->mode, chan->name,oprmode->peer->name);;
02993       break;
02994    case AST_OPTION_ECHOCAN:
02995       cp = (char *) data;
02996       if (*cp) {
02997          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
02998          zt_enable_ec(p);
02999       } else {
03000          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
03001          zt_disable_ec(p);
03002       }
03003       break;
03004    }
03005    errno = 0;
03006 
03007    return 0;
03008 }
03009 
03010 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03011 {
03012    struct zt_pvt *p = chan->tech_pvt;
03013    
03014    if (!strcasecmp(data, "rxgain")) {
03015       ast_mutex_lock(&p->lock);
03016       snprintf(buf, len, "%f", p->rxgain);
03017       ast_mutex_unlock(&p->lock);   
03018    } else if (!strcasecmp(data, "txgain")) {
03019       ast_mutex_lock(&p->lock);
03020       snprintf(buf, len, "%f", p->txgain);
03021       ast_mutex_unlock(&p->lock);   
03022    } else {
03023       ast_copy_string(buf, "", len);
03024    }
03025    return 0;
03026 }
03027 
03028 
03029 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03030 {
03031    /* Unlink a specific slave or all slaves/masters from a given master */
03032    int x;
03033    int hasslaves;
03034    if (!master)
03035       return;
03036    if (needlock) {
03037       ast_mutex_lock(&master->lock);
03038       if (slave) {
03039          while (ast_mutex_trylock(&slave->lock)) {
03040             ast_mutex_unlock(&master->lock);
03041             usleep(1);
03042             ast_mutex_lock(&master->lock);
03043          }
03044       }
03045    }
03046    hasslaves = 0;
03047    for (x = 0; x < MAX_SLAVES; x++) {
03048       if (master->slaves[x]) {
03049          if (!slave || (master->slaves[x] == slave)) {
03050             /* Take slave out of the conference */
03051             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03052             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03053             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03054             master->slaves[x]->master = NULL;
03055             master->slaves[x] = NULL;
03056          } else
03057             hasslaves = 1;
03058       }
03059       if (!hasslaves)
03060          master->inconference = 0;
03061    }
03062    if (!slave) {
03063       if (master->master) {
03064          /* Take master out of the conference */
03065          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03066          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03067          hasslaves = 0;
03068          for (x = 0; x < MAX_SLAVES; x++) {
03069             if (master->master->slaves[x] == master)
03070                master->master->slaves[x] = NULL;
03071             else if (master->master->slaves[x])
03072                hasslaves = 1;
03073          }
03074          if (!hasslaves)
03075             master->master->inconference = 0;
03076       }
03077       master->master = NULL;
03078    }
03079    update_conf(master);
03080    if (needlock) {
03081       if (slave)
03082          ast_mutex_unlock(&slave->lock);
03083       ast_mutex_unlock(&master->lock);
03084    }
03085 }
03086 
03087 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03088    int x;
03089    if (!slave || !master) {
03090       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03091       return;
03092    }
03093    for (x = 0; x < MAX_SLAVES; x++) {
03094       if (!master->slaves[x]) {
03095          master->slaves[x] = slave;
03096          break;
03097       }
03098    }
03099    if (x >= MAX_SLAVES) {
03100       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03101       master->slaves[MAX_SLAVES - 1] = slave;
03102    }
03103    if (slave->master) 
03104       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03105    slave->master = master;
03106    
03107    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03108 }
03109 
03110 static void disable_dtmf_detect(struct zt_pvt *p)
03111 {
03112 #ifdef ZT_TONEDETECT
03113    int val;
03114 #endif
03115 
03116    p->ignoredtmf = 1;
03117 
03118 #ifdef ZT_TONEDETECT
03119    val = 0;
03120    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03121 #endif      
03122    if (!p->hardwaredtmf && p->dsp) {
03123       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03124       ast_dsp_set_features(p->dsp, p->dsp_features);
03125    }
03126 }
03127 
03128 static void enable_dtmf_detect(struct zt_pvt *p)
03129 {
03130 #ifdef ZT_TONEDETECT
03131    int val;
03132 #endif
03133 
03134    if (p->channel == CHAN_PSEUDO)
03135       return;
03136 
03137    p->ignoredtmf = 0;
03138 
03139 #ifdef ZT_TONEDETECT
03140    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03141    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03142 #endif      
03143    if (!p->hardwaredtmf && p->dsp) {
03144       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03145       ast_dsp_set_features(p->dsp, p->dsp_features);
03146    }
03147 }
03148 
03149 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)
03150 {
03151    struct ast_channel *who;
03152    struct zt_pvt *p0, *p1, *op0, *op1;
03153    struct zt_pvt *master = NULL, *slave = NULL;
03154    struct ast_frame *f;
03155    int inconf = 0;
03156    int nothingok = 1;
03157    int ofd0, ofd1;
03158    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03159    int os0 = -1, os1 = -1;
03160    int priority = 0;
03161    struct ast_channel *oc0, *oc1;
03162    enum ast_bridge_result res;
03163 
03164 #ifdef PRI_2BCT
03165    int triedtopribridge = 0;
03166    q931_call *q931c0 = NULL, *q931c1 = NULL;
03167 #endif
03168 
03169    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03170       There is code below to handle it properly until DTMF is actually seen,
03171       but due to currently unresolved issues it's ignored...
03172    */
03173 
03174    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03175       return AST_BRIDGE_FAILED_NOWARN;
03176 
03177    ast_mutex_lock(&c0->lock);
03178    while (ast_mutex_trylock(&c1->lock)) {
03179       ast_mutex_unlock(&c0->lock);
03180       usleep(1);
03181       ast_mutex_lock(&c0->lock);
03182    }
03183 
03184    p0 = c0->tech_pvt;
03185    p1 = c1->tech_pvt;
03186    /* cant do pseudo-channels here */
03187    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03188       ast_mutex_unlock(&c0->lock);
03189       ast_mutex_unlock(&c1->lock);
03190       return AST_BRIDGE_FAILED_NOWARN;
03191    }
03192 
03193    oi0 = zt_get_index(c0, p0, 0);
03194    oi1 = zt_get_index(c1, p1, 0);
03195    if ((oi0 < 0) || (oi1 < 0)) {
03196       ast_mutex_unlock(&c0->lock);
03197       ast_mutex_unlock(&c1->lock);
03198       return AST_BRIDGE_FAILED;
03199    }
03200 
03201    op0 = p0 = c0->tech_pvt;
03202    op1 = p1 = c1->tech_pvt;
03203    ofd0 = c0->fds[0];
03204    ofd1 = c1->fds[0];
03205    oc0 = p0->owner;
03206    oc1 = p1->owner;
03207 
03208    if (ast_mutex_trylock(&p0->lock)) {
03209       /* Don't block, due to potential for deadlock */
03210       ast_mutex_unlock(&c0->lock);
03211       ast_mutex_unlock(&c1->lock);
03212       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03213       return AST_BRIDGE_RETRY;
03214    }
03215    if (ast_mutex_trylock(&p1->lock)) {
03216       /* Don't block, due to potential for deadlock */
03217       ast_mutex_unlock(&p0->lock);
03218       ast_mutex_unlock(&c0->lock);
03219       ast_mutex_unlock(&c1->lock);
03220       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03221       return AST_BRIDGE_RETRY;
03222    }
03223 
03224    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03225       if (p0->owner && p1->owner) {
03226          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03227          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03228             master = p0;
03229             slave = p1;
03230             inconf = 1;
03231          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03232             master = p1;
03233             slave = p0;
03234             inconf = 1;
03235          } else {
03236             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03237             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03238                p0->channel,
03239                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03240                p0->subs[SUB_REAL].inthreeway, p0->channel,
03241                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03242                p1->subs[SUB_REAL].inthreeway);
03243          }
03244          nothingok = 0;
03245       }
03246    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03247       if (p1->subs[SUB_THREEWAY].inthreeway) {
03248          master = p1;
03249          slave = p0;
03250          nothingok = 0;
03251       }
03252    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03253       if (p0->subs[SUB_THREEWAY].inthreeway) {
03254          master = p0;
03255          slave = p1;
03256          nothingok = 0;
03257       }
03258    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03259       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03260          don't put us in anything */
03261       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03262          master = p1;
03263          slave = p0;
03264          nothingok = 0;
03265       }
03266    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03267       /* Same as previous */
03268       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03269          master = p0;
03270          slave = p1;
03271          nothingok = 0;
03272       }
03273    }
03274    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03275       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03276    if (master && slave) {
03277       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03278          in an active threeway call with a channel that is ringing, we should
03279          indicate ringing. */
03280       if ((oi1 == SUB_THREEWAY) && 
03281           p1->subs[SUB_THREEWAY].inthreeway && 
03282           p1->subs[SUB_REAL].owner && 
03283           p1->subs[SUB_REAL].inthreeway && 
03284           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03285          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03286          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03287          os1 = p1->subs[SUB_REAL].owner->_state;
03288       } else {
03289          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03290          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03291       }
03292       if ((oi0 == SUB_THREEWAY) && 
03293           p0->subs[SUB_THREEWAY].inthreeway && 
03294           p0->subs[SUB_REAL].owner && 
03295           p0->subs[SUB_REAL].inthreeway && 
03296           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03297          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03298          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03299          os0 = p0->subs[SUB_REAL].owner->_state;
03300       } else {
03301          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03302          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03303       }
03304       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03305          if (!p0->echocanbridged || !p1->echocanbridged) {
03306             /* Disable echo cancellation if appropriate */
03307             zt_disable_ec(p0);
03308             zt_disable_ec(p1);
03309          }
03310       }
03311       zt_link(slave, master);
03312       master->inconference = inconf;
03313    } else if (!nothingok)
03314       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03315 
03316    update_conf(p0);
03317    update_conf(p1);
03318    t0 = p0->subs[SUB_REAL].inthreeway;
03319    t1 = p1->subs[SUB_REAL].inthreeway;
03320 
03321    ast_mutex_unlock(&p0->lock);
03322    ast_mutex_unlock(&p1->lock);
03323 
03324    ast_mutex_unlock(&c0->lock);
03325    ast_mutex_unlock(&c1->lock);
03326 
03327    /* Native bridge failed */
03328    if ((!master || !slave) && !nothingok) {
03329       zt_enable_ec(p0);
03330       zt_enable_ec(p1);
03331       return AST_BRIDGE_FAILED;
03332    }
03333    
03334    if (option_verbose > 2) 
03335       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03336 
03337    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03338       disable_dtmf_detect(op0);
03339 
03340    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03341       disable_dtmf_detect(op1);
03342 
03343    for (;;) {
03344       struct ast_channel *c0_priority[2] = {c0, c1};
03345       struct ast_channel *c1_priority[2] = {c1, c0};
03346 
03347       /* Here's our main loop...  Start by locking things, looking for private parts, 
03348          and then balking if anything is wrong */
03349       ast_mutex_lock(&c0->lock);
03350       while (ast_mutex_trylock(&c1->lock)) {
03351          ast_mutex_unlock(&c0->lock);
03352          usleep(1);
03353          ast_mutex_lock(&c0->lock);
03354       }
03355 
03356       p0 = c0->tech_pvt;
03357       p1 = c1->tech_pvt;
03358 
03359       if (op0 == p0)
03360          i0 = zt_get_index(c0, p0, 1);
03361       if (op1 == p1)
03362          i1 = zt_get_index(c1, p1, 1);
03363       ast_mutex_unlock(&c0->lock);
03364       ast_mutex_unlock(&c1->lock);
03365 
03366       if (!timeoutms || 
03367           (op0 != p0) ||
03368           (op1 != p1) || 
03369           (ofd0 != c0->fds[0]) || 
03370           (ofd1 != c1->fds[0]) ||
03371           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03372           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03373           (oc0 != p0->owner) || 
03374           (oc1 != p1->owner) ||
03375           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03376           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03377           (oi0 != i0) ||
03378           (oi1 != i1)) {
03379          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03380             op0->channel, oi0, op1->channel, oi1);
03381          res = AST_BRIDGE_RETRY;
03382          goto return_from_bridge;
03383       }
03384 
03385 #ifdef PRI_2BCT
03386       q931c0 = p0->call;
03387       q931c1 = p1->call;
03388       if (p0->transfer && p1->transfer 
03389           && q931c0 && q931c1 
03390           && !triedtopribridge) {
03391          pri_channel_bridge(q931c0, q931c1);
03392          triedtopribridge = 1;
03393       }
03394 #endif
03395 
03396       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03397       if (!who) {
03398          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03399          continue;
03400       }
03401       f = ast_read(who);
03402       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03403          *fo = f;
03404          *rc = who;
03405          res = AST_BRIDGE_COMPLETE;
03406          goto return_from_bridge;
03407       }
03408       if (f->frametype == AST_FRAME_DTMF) {
03409          if ((who == c0) && p0->pulsedial) {
03410             ast_write(c1, f);
03411          } else if ((who == c1) && p1->pulsedial) {
03412             ast_write(c0, f);
03413          } else {
03414             *fo = f;
03415             *rc = who;
03416             res = AST_BRIDGE_COMPLETE;
03417             goto return_from_bridge;
03418          }
03419       }
03420       ast_frfree(f);
03421       
03422       /* Swap who gets priority */
03423       priority = !priority;
03424    }
03425 
03426 return_from_bridge:
03427    if (op0 == p0)
03428       zt_enable_ec(p0);
03429 
03430    if (op1 == p1)
03431       zt_enable_ec(p1);
03432 
03433    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03434       enable_dtmf_detect(op0);
03435 
03436    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03437       enable_dtmf_detect(op1);
03438 
03439    zt_unlink(slave, master, 1);
03440 
03441    return res;
03442 }
03443 
03444 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03445 {
03446    struct zt_pvt *p = newchan->tech_pvt;
03447    int x;
03448    ast_mutex_lock(&p->lock);
03449    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03450    if (p->owner == oldchan) {
03451       p->owner = newchan;
03452    }
03453    for (x = 0; x < 3; x++)
03454       if (p->subs[x].owner == oldchan) {
03455          if (!x)
03456             zt_unlink(NULL, p, 0);
03457          p->subs[x].owner = newchan;
03458       }
03459    if (newchan->_state == AST_STATE_RINGING) 
03460       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03461    update_conf(p);
03462    ast_mutex_unlock(&p->lock);
03463    return 0;
03464 }
03465 
03466 static int zt_ring_phone(struct zt_pvt *p)
03467 {
03468    int x;
03469    int res;
03470    /* Make sure our transmit state is on hook */
03471    x = 0;
03472    x = ZT_ONHOOK;
03473    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03474    do {
03475       x = ZT_RING;
03476       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03477       if (res) {
03478          switch (errno) {
03479          case EBUSY:
03480          case EINTR:
03481             /* Wait just in case */
03482             usleep(10000);
03483             continue;
03484          case EINPROGRESS:
03485             res = 0;
03486             break;
03487          default:
03488             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03489             res = 0;
03490          }
03491       }
03492    } while (res);
03493    return res;
03494 }
03495 
03496 static void *ss_thread(void *data);
03497 
03498 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03499 
03500 static int attempt_transfer(struct zt_pvt *p)
03501 {
03502    /* In order to transfer, we need at least one of the channels to
03503       actually be in a call bridge.  We can't conference two applications
03504       together (but then, why would we want to?) */
03505    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03506       /* The three-way person we're about to transfer to could still be in MOH, so
03507          stop if now if appropriate */
03508       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03509          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03510       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03511          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03512       }
03513       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03514          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03515       }
03516       if (p->subs[SUB_REAL].owner->cdr) {
03517          /* Move CDR from second channel to current one */
03518          p->subs[SUB_THREEWAY].owner->cdr =
03519             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03520          p->subs[SUB_REAL].owner->cdr = NULL;
03521       }
03522       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03523          /* Move CDR from second channel's bridge to current one */
03524          p->subs[SUB_THREEWAY].owner->cdr =
03525             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03526          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03527       }
03528        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03529          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03530                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03531          return -1;
03532       }
03533       /* Orphan the channel after releasing the lock */
03534       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03535       unalloc_sub(p, SUB_THREEWAY);
03536    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03537       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03538       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03539          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03540       }
03541       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03542          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03543       }
03544       if (p->subs[SUB_THREEWAY].owner->cdr) {
03545          /* Move CDR from second channel to current one */
03546          p->subs[SUB_REAL].owner->cdr = 
03547             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03548          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03549       }
03550       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03551          /* Move CDR from second channel's bridge to current one */
03552          p->subs[SUB_REAL].owner->cdr = 
03553             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03554          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03555       }
03556       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03557          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03558                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03559          return -1;
03560       }
03561       /* Three-way is now the REAL */
03562       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03563       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03564       unalloc_sub(p, SUB_THREEWAY);
03565       /* Tell the caller not to hangup */
03566       return 1;
03567    } else {
03568       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03569                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03570       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03571       return -1;
03572    }
03573    return 0;
03574 }
03575 
03576 static int check_for_conference(struct zt_pvt *p)
03577 {
03578    ZT_CONFINFO ci;
03579    /* Fine if we already have a master, etc */
03580    if (p->master || (p->confno > -1))
03581       return 0;
03582    memset(&ci, 0, sizeof(ci));
03583    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03584       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03585       return 0;
03586    }
03587    /* If we have no master and don't have a confno, then 
03588       if we're in a conference, it's probably a MeetMe room or
03589       some such, so don't let us 3-way out! */
03590    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03591       if (option_verbose > 2) 
03592          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03593       return 1;
03594    }
03595    return 0;
03596 }
03597 
03598 static int get_alarms(struct zt_pvt *p)
03599 {
03600    int res;
03601    ZT_SPANINFO zi;
03602    memset(&zi, 0, sizeof(zi));
03603    zi.spanno = p->span;
03604    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03605    if (res < 0) {
03606       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03607       return 0;
03608    }
03609    return zi.alarms;
03610 }
03611 
03612 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03613 {
03614    struct zt_pvt *p = ast->tech_pvt;
03615    struct ast_frame *f = *dest;
03616 
03617    if (option_debug)
03618       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03619 
03620    if (p->confirmanswer) {
03621       if (option_debug)
03622          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03623       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03624          of a DTMF digit */
03625       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03626       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03627       *dest = &p->subs[index].f;
03628       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03629       p->confirmanswer = 0;
03630    } else if (p->callwaitcas) {
03631       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03632          if (option_debug)
03633             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03634          if (p->cidspill)
03635             free(p->cidspill);
03636          send_cwcidspill(p);
03637       }
03638       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03639          p->callwaitcas = 0;
03640       p->subs[index].f.frametype = AST_FRAME_NULL;
03641       p->subs[index].f.subclass = 0;
03642       *dest = &p->subs[index].f;
03643    } else if (f->subclass == 'f') {
03644       /* Fax tone -- Handle and return NULL */
03645       if ((p->callprogress & 0x6) && !p->faxhandled) {
03646          p->faxhandled++;
03647          if (strcmp(ast->exten, "fax")) {
03648             const char *target_context = S_OR(ast->macrocontext, ast->context);
03649 
03650             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03651                if (option_verbose > 2)
03652                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03653                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03654                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03655                if (ast_async_goto(ast, target_context, "fax", 1))
03656                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03657             } else
03658                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03659          } else if (option_debug)
03660             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03661       } else if (option_debug)
03662             ast_log(LOG_DEBUG, "Fax already handled\n");
03663       zt_confmute(p, 0);
03664       p->subs[index].f.frametype = AST_FRAME_NULL;
03665       p->subs[index].f.subclass = 0;
03666       *dest = &p->subs[index].f;
03667    } else if (f->subclass == 'm') {
03668       /* Confmute request */
03669       zt_confmute(p, 1);
03670       p->subs[index].f.frametype = AST_FRAME_NULL;
03671       p->subs[index].f.subclass = 0;
03672       *dest = &p->subs[index].f;    
03673    } else if (f->subclass == 'u') {
03674       /* Unmute */
03675       zt_confmute(p, 0);
03676       p->subs[index].f.frametype = AST_FRAME_NULL;
03677       p->subs[index].f.subclass = 0;
03678       *dest = &p->subs[index].f;    
03679    } else
03680       zt_confmute(p, 0);
03681 }
03682          
03683 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03684 {
03685    int res, x;
03686    int index, mysig;
03687    char *c;
03688    struct zt_pvt *p = ast->tech_pvt;
03689    pthread_t threadid;
03690    pthread_attr_t attr;
03691    struct ast_channel *chan;
03692    struct ast_frame *f;
03693 
03694    index = zt_get_index(ast, p, 0);
03695    mysig = p->sig;
03696    if (p->outsigmod > -1)
03697       mysig = p->outsigmod;
03698    p->subs[index].f.frametype = AST_FRAME_NULL;
03699    p->subs[index].f.subclass = 0;
03700    p->subs[index].f.datalen = 0;
03701    p->subs[index].f.samples = 0;
03702    p->subs[index].f.mallocd = 0;
03703    p->subs[index].f.offset = 0;
03704    p->subs[index].f.src = "zt_handle_event";
03705    p->subs[index].f.data = NULL;
03706    f = &p->subs[index].f;
03707 
03708    if (index < 0)
03709       return &p->subs[index].f;
03710    if (p->fake_event) {
03711       res = p->fake_event;
03712       p->fake_event = 0;
03713    } else
03714       res = zt_get_event(p->subs[index].zfd);
03715 
03716    if (option_debug)
03717       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03718 
03719    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03720       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03721 
03722       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03723 #ifdef HAVE_PRI
03724       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03725          /* absorb event */
03726       } else {
03727 #endif
03728          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03729          p->subs[index].f.subclass = res & 0xff;
03730 #ifdef HAVE_PRI
03731       }
03732 #endif
03733       zt_handle_dtmfup(ast, index, &f);
03734       return f;
03735    }
03736 
03737    if (res & ZT_EVENT_DTMFDOWN) {
03738       if (option_debug)
03739          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03740       /* Mute conference */
03741       zt_confmute(p, 1);
03742       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03743       p->subs[index].f.subclass = res & 0xff;
03744       return &p->subs[index].f;
03745    }
03746 
03747    switch (res) {
03748 #ifdef ZT_EVENT_EC_DISABLED
03749       case ZT_EVENT_EC_DISABLED:
03750          if (option_verbose > 2) 
03751             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03752          p->echocanon = 0;
03753          break;
03754 #endif
03755       case ZT_EVENT_BITSCHANGED:
03756          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03757       case ZT_EVENT_PULSE_START:
03758          /* Stop tone if there's a pulse start and the PBX isn't started */
03759          if (!ast->pbx)
03760             tone_zone_play_tone(p->subs[index].zfd, -1);
03761          break;   
03762       case ZT_EVENT_DIALCOMPLETE:
03763          if (p->inalarm) break;
03764          if ((p->radio || (p->oprmode < 0))) break;
03765          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03766             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03767             return NULL;
03768          }
03769          if (!x) { /* if not still dialing in driver */
03770             zt_enable_ec(p);
03771             if (p->echobreak) {
03772                zt_train_ec(p);
03773                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03774                p->dop.op = ZT_DIAL_OP_REPLACE;
03775                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03776                p->echobreak = 0;
03777             } else {
03778                p->dialing = 0;
03779                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03780                   /* if thru with dialing after offhook */
03781                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03782                      ast_setstate(ast, AST_STATE_UP);
03783                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03784                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03785                      break;
03786                   } else { /* if to state wait for offhook to dial rest */
03787                      /* we now wait for off hook */
03788                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03789                   }
03790                }
03791                if (ast->_state == AST_STATE_DIALING) {
03792                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03793                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03794                   } 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)))) {
03795                      ast_setstate(ast, AST_STATE_RINGING);
03796                   } else if (!p->answeronpolarityswitch) {
03797                      ast_setstate(ast, AST_STATE_UP);
03798                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03799                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03800                      /* If aops=0 and hops=1, this is necessary */
03801                      p->polarity = POLARITY_REV;
03802                   } else {
03803                      /* Start clean, so we can catch the change to REV polarity when party answers */
03804                      p->polarity = POLARITY_IDLE;
03805                   }
03806                }
03807             }
03808          }
03809          break;
03810       case ZT_EVENT_ALARM:
03811 #ifdef HAVE_PRI
03812          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03813             /* T309 is not enabled : hangup calls when alarm occurs */
03814             if (p->call) {
03815                if (p->pri && p->pri->pri) {
03816                   if (!pri_grab(p, p->pri)) {
03817                      pri_hangup(p->pri->pri, p->call, -1);
03818                      pri_destroycall(p->pri->pri, p->call);
03819                      p->call = NULL;
03820                      pri_rel(p->pri);
03821                   } else
03822                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03823                } else
03824                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03825             }
03826             if (p->owner)
03827                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03828          }
03829          if (p->bearer)
03830             p->bearer->inalarm = 1;
03831          else
03832 #endif
03833          p->inalarm = 1;
03834          res = get_alarms(p);
03835          do {
03836             const char *alarm_str = alarm2str(res);
03837 
03838             /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
03839              * doesn't know what to do with it.  Don't confuse users with log messages. */
03840             if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
03841                p->unknown_alarm = 1;
03842                break;
03843             } else {
03844                p->unknown_alarm = 0;
03845             }
03846                
03847             ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
03848             manager_event(EVENT_FLAG_SYSTEM, "Alarm",
03849                "Alarm: %s\r\n"
03850                "Channel: %d\r\n",
03851                alarm_str, p->channel);
03852          } while (0);
03853 #ifdef HAVE_LIBPRI
03854          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
03855             /* fall through intentionally */
03856          } else {
03857             break;
03858          }
03859 #endif
03860       case ZT_EVENT_ONHOOK:
03861          if (p->radio) {
03862             p->subs[index].f.frametype = AST_FRAME_CONTROL;
03863             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
03864             break;
03865          }
03866          if (p->oprmode < 0)
03867          {
03868             if (p->oprmode != -1) break;
03869             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03870             {
03871                /* Make sure it starts ringing */
03872                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03873                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
03874                save_conference(p->oprpeer);
03875                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03876             }
03877             break;
03878          }
03879          switch (p->sig) {
03880          case SIG_FXOLS:
03881          case SIG_FXOGS:
03882          case SIG_FXOKS:
03883             p->onhooktime = time(NULL);
03884             p->msgstate = -1;
03885             /* Check for some special conditions regarding call waiting */
03886             if (index == SUB_REAL) {
03887                /* The normal line was hung up */
03888                if (p->subs[SUB_CALLWAIT].owner) {
03889                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
03890                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03891                   if (option_verbose > 2) 
03892                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
03893                   unalloc_sub(p, SUB_CALLWAIT); 
03894 #if 0
03895                   p->subs[index].needanswer = 0;
03896                   p->subs[index].needringing = 0;
03897 #endif                  
03898                   p->callwaitingrepeat = 0;
03899                   p->cidcwexpire = 0;
03900                   p->owner = NULL;
03901                   /* Don't start streaming audio yet if the incoming call isn't up yet */
03902                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
03903                      p->dialing = 1;
03904                   zt_ring_phone(p);
03905                } else if (p->subs[SUB_THREEWAY].owner) {
03906                   unsigned int mssinceflash;
03907                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
03908                      the private structure -- not especially easy or clean */
03909                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
03910                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
03911                      ast_mutex_unlock(&p->lock);
03912                      ast_mutex_unlock(&ast->lock);
03913                      usleep(1);
03914                      /* We can grab ast and p in that order, without worry.  We should make sure
03915                         nothing seriously bad has happened though like some sort of bizarre double
03916                         masquerade! */
03917                      ast_mutex_lock(&ast->lock);
03918                      ast_mutex_lock(&p->lock);
03919                      if (p->owner != ast) {
03920                         ast_log(LOG_WARNING, "This isn't good...\n");
03921                         return NULL;
03922                      }
03923                   }
03924                   if (!p->subs[SUB_THREEWAY].owner) {
03925                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
03926                      return NULL;
03927                   }
03928                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
03929                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
03930                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
03931                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
03932                         hanging up.  Hangup both channels now */
03933                      if (p->subs[SUB_THREEWAY].owner)
03934                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
03935                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03936                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
03937                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03938                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
03939                      if (p->transfer) {
03940                         /* In any case this isn't a threeway call anymore */
03941                         p->subs[SUB_REAL].inthreeway = 0;
03942                         p->subs[SUB_THREEWAY].inthreeway = 0;
03943                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
03944                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
03945                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03946                            /* Swap subs and dis-own channel */
03947                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
03948                            p->owner = NULL;
03949                            /* Ring the phone */
03950                            zt_ring_phone(p);
03951                         } else {
03952                            if ((res = attempt_transfer(p)) < 0) {
03953                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03954                               if (p->subs[SUB_THREEWAY].owner)
03955                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03956                            } else if (res) {
03957                               /* Don't actually hang up at this point */
03958                               if (p->subs[SUB_THREEWAY].owner)
03959                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03960                               break;
03961                            }
03962                         }
03963                      } else {
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                      }
03968                   } else {
03969                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03970                      /* Swap subs and dis-own channel */
03971                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
03972                      p->owner = NULL;
03973                      /* Ring the phone */
03974                      zt_ring_phone(p);
03975                   }
03976                }
03977             } else {
03978                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
03979             }
03980             /* Fall through */
03981          default:
03982             zt_disable_ec(p);
03983             return NULL;
03984          }
03985          break;
03986       case ZT_EVENT_RINGOFFHOOK:
03987          if (p->inalarm) break;
03988          if (p->oprmode < 0)
03989          {
03990             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
03991             {
03992                /* Make sure it stops ringing */
03993                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
03994                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
03995                restore_conference(p->oprpeer);
03996             }
03997             break;
03998          }
03999          if (p->radio)
04000          {
04001             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04002             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04003             break;
04004          }
04005          /* for E911, its supposed to wait for offhook then dial
04006             the second half of the dial string */
04007          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04008             c = strchr(p->dialdest, '/');
04009             if (c)
04010                c++;
04011             else
04012                c = p->dialdest;
04013             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04014             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04015             if (strlen(p->dop.dialstr) > 4) {
04016                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04017                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04018                p->echorest[sizeof(p->echorest) - 1] = '\0';
04019                p->echobreak = 1;
04020                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04021             } else
04022                p->echobreak = 0;
04023             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
04024                x = ZT_ONHOOK;
04025                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
04026                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
04027                return NULL;
04028                }
04029             p->dialing = 1;
04030             return &p->subs[index].f;
04031          }
04032          switch (p->sig) {
04033          case SIG_FXOLS:
04034          case SIG_FXOGS:
04035          case SIG_FXOKS:
04036             switch (ast->_state) {
04037             case AST_STATE_RINGING:
04038                zt_enable_ec(p);
04039                zt_train_ec(p);
04040                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04041                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04042                /* Make sure it stops ringing */
04043                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04044                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04045                if (p->cidspill) {
04046                   /* Cancel any running CallerID spill */
04047                   free(p->cidspill);
04048                   p->cidspill = NULL;
04049                }
04050                p->dialing = 0;
04051                p->callwaitcas = 0;
04052                if (p->confirmanswer) {
04053                   /* Ignore answer if "confirm answer" is enabled */
04054                   p->subs[index].f.frametype = AST_FRAME_NULL;
04055                   p->subs[index].f.subclass = 0;
04056                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04057                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04058                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04059                   if (res < 0) {
04060                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04061                      p->dop.dialstr[0] = '\0';
04062                      return NULL;
04063                   } else {
04064                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04065                      p->subs[index].f.frametype = AST_FRAME_NULL;
04066                      p->subs[index].f.subclass = 0;
04067                      p->dialing = 1;
04068                   }
04069                   p->dop.dialstr[0] = '\0';
04070                   ast_setstate(ast, AST_STATE_DIALING);
04071                } else
04072                   ast_setstate(ast, AST_STATE_UP);
04073                return &p->subs[index].f;
04074             case AST_STATE_DOWN:
04075                ast_setstate(ast, AST_STATE_RING);
04076                ast->rings = 1;
04077                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04078                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04079                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04080                return &p->subs[index].f;
04081             case AST_STATE_UP:
04082                /* Make sure it stops ringing */
04083                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04084                /* Okay -- probably call waiting*/
04085                if (ast_bridged_channel(p->owner))
04086                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04087                p->subs[index].needunhold = 1;
04088                break;
04089             case AST_STATE_RESERVED:
04090                /* Start up dialtone */
04091                if (has_voicemail(p))
04092                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04093                else
04094                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04095                break;
04096             default:
04097                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04098             }
04099             break;
04100          case SIG_FXSLS:
04101          case SIG_FXSGS:
04102          case SIG_FXSKS:
04103             if (ast->_state == AST_STATE_RING) {
04104                p->ringt = p->ringt_base;
04105             }
04106 
04107             /* Fall through */
04108          case SIG_EM:
04109          case SIG_EM_E1:
04110          case SIG_EMWINK:
04111          case SIG_FEATD:
04112          case SIG_FEATDMF:
04113          case SIG_FEATDMF_TA:
04114          case SIG_E911:
04115          case SIG_FGC_CAMA:
04116          case SIG_FGC_CAMAMF:
04117          case SIG_FEATB:
04118          case SIG_SF:
04119          case SIG_SFWINK:
04120          case SIG_SF_FEATD:
04121          case SIG_SF_FEATDMF:
04122          case SIG_SF_FEATB:
04123             if (ast->_state == AST_STATE_PRERING)
04124                ast_setstate(ast, AST_STATE_RING);
04125             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04126                if (option_debug)
04127                   ast_log(LOG_DEBUG, "Ring detected\n");
04128                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04129                p->subs[index].f.subclass = AST_CONTROL_RING;
04130             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04131                if (option_debug)
04132                   ast_log(LOG_DEBUG, "Line answered\n");
04133                if (p->confirmanswer) {
04134                   p->subs[index].f.frametype = AST_FRAME_NULL;
04135                   p->subs[index].f.subclass = 0;
04136                } else {
04137                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04138                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04139                   ast_setstate(ast, AST_STATE_UP);
04140                }
04141             } else if (ast->_state != AST_STATE_RING)
04142                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04143             break;
04144          default:
04145             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04146          }
04147          break;
04148 #ifdef ZT_EVENT_RINGBEGIN
04149       case ZT_EVENT_RINGBEGIN:
04150          switch (p->sig) {
04151          case SIG_FXSLS:
04152          case SIG_FXSGS:
04153          case SIG_FXSKS:
04154             if (ast->_state == AST_STATE_RING) {
04155                p->ringt = p->ringt_base;
04156             }
04157             break;
04158          }
04159          break;
04160 #endif         
04161       case ZT_EVENT_RINGEROFF:
04162          if (p->inalarm) break;
04163          if ((p->radio || (p->oprmode < 0))) break;
04164          ast->rings++;
04165          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04166             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04167             free(p->cidspill);
04168             p->cidspill = NULL;
04169             p->callwaitcas = 0;
04170          }
04171          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04172          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04173          break;
04174       case ZT_EVENT_RINGERON:
04175          break;
04176       case ZT_EVENT_NOALARM:
04177          p->inalarm = 0;
04178 #ifdef HAVE_PRI
04179          /* Extremely unlikely but just in case */
04180          if (p->bearer)
04181             p->bearer->inalarm = 0;
04182 #endif            
04183          if (!p->unknown_alarm) {
04184             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04185             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04186                "Channel: %d\r\n", p->channel);
04187          } else {
04188             p->unknown_alarm = 0;
04189          }
04190          break;
04191       case ZT_EVENT_WINKFLASH:
04192          if (p->inalarm) break;
04193          if (p->radio) break;
04194          if (p->oprmode < 0) break;
04195          if (p->oprmode > 1)
04196          {
04197             struct zt_params par;
04198 
04199             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04200             {
04201                if (!par.rxisoffhook)
04202                {
04203                   /* Make sure it stops ringing */
04204                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04205                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04206                   save_conference(p);
04207                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04208                }
04209             }
04210             break;
04211          }
04212          /* Remember last time we got a flash-hook */
04213          gettimeofday(&p->flashtime, NULL);
04214          switch (mysig) {
04215          case SIG_FXOLS:
04216          case SIG_FXOGS:
04217          case SIG_FXOKS:
04218             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04219                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04220             p->callwaitcas = 0;
04221 
04222             if (index != SUB_REAL) {
04223                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04224                goto winkflashdone;
04225             }
04226             
04227             if (p->subs[SUB_CALLWAIT].owner) {
04228                /* Swap to call-wait */
04229                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04230                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04231                p->owner = p->subs[SUB_REAL].owner;
04232                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04233                if (p->owner->_state == AST_STATE_RINGING) {
04234                   ast_setstate(p->owner, AST_STATE_UP);
04235                   p->subs[SUB_REAL].needanswer = 1;
04236                }
04237                p->callwaitingrepeat = 0;
04238                p->cidcwexpire = 0;
04239                /* Start music on hold if appropriate */
04240                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04241                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04242                      S_OR(p->mohsuggest, NULL),
04243                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04244                }
04245                p->subs[SUB_CALLWAIT].needhold = 1;
04246                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04247                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04248                      S_OR(p->mohsuggest, NULL),
04249                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04250                }
04251                p->subs[SUB_REAL].needunhold = 1;
04252             } else if (!p->subs[SUB_THREEWAY].owner) {
04253                char cid_num[256];
04254                char cid_name[256];
04255 
04256                if (!p->threewaycalling) {
04257                   /* Just send a flash if no 3-way calling */
04258                   p->subs[SUB_REAL].needflash = 1;
04259                   goto winkflashdone;
04260                } else if (!check_for_conference(p)) {
04261                   if (p->zaptrcallerid && p->owner) {
04262                      if (p->owner->cid.cid_num)
04263                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04264                      if (p->owner->cid.cid_name)
04265                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04266                   }
04267                   /* XXX This section needs much more error checking!!! XXX */
04268                   /* Start a 3-way call if feasible */
04269                   if (!((ast->pbx) ||
04270                         (ast->_state == AST_STATE_UP) ||
04271                         (ast->_state == AST_STATE_RING))) {
04272                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04273                         goto winkflashdone;
04274                   }
04275                   if (alloc_sub(p, SUB_THREEWAY)) {
04276                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04277                      goto winkflashdone;
04278                   }
04279                   /* Make new channel */
04280                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04281                   if (p->zaptrcallerid) {
04282                      if (!p->origcid_num)
04283                         p->origcid_num = ast_strdup(p->cid_num);
04284                      if (!p->origcid_name)
04285                         p->origcid_name = ast_strdup(p->cid_name);
04286                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04287                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04288                   }
04289                   /* Swap things around between the three-way and real call */
04290                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04291                   /* Disable echo canceller for better dialing */
04292                   zt_disable_ec(p);
04293                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04294                   if (res)
04295                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04296                   p->owner = chan;
04297                   pthread_attr_init(&attr);
04298                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04299                   if (!chan) {
04300                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04301                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04302                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04303                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04304                      zt_enable_ec(p);
04305                      ast_hangup(chan);
04306                   } else {
04307                      if (option_verbose > 2) 
04308                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04309                      /* Start music on hold if appropriate */
04310                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04311                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04312                            S_OR(p->mohsuggest, NULL),
04313                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04314                      }
04315                      p->subs[SUB_THREEWAY].needhold = 1;
04316                   }
04317                   pthread_attr_destroy(&attr);
04318                }
04319             } else {
04320                /* Already have a 3 way call */
04321                if (p->subs[SUB_THREEWAY].inthreeway) {
04322                   /* Call is already up, drop the last person */
04323                   if (option_debug)
04324                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04325                   /* If the primary call isn't answered yet, use it */
04326                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04327                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04328                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04329                      p->owner = p->subs[SUB_REAL].owner;
04330                   }
04331                   /* Drop the last call and stop the conference */
04332                   if (option_verbose > 2)
04333                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04334                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04335                   p->subs[SUB_REAL].inthreeway = 0;
04336                   p->subs[SUB_THREEWAY].inthreeway = 0;
04337                } else {
04338                   /* Lets see what we're up to */
04339                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04340                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04341                      int otherindex = SUB_THREEWAY;
04342 
04343                      if (option_verbose > 2)
04344                         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);
04345                      /* Put them in the threeway, and flip */
04346                      p->subs[SUB_THREEWAY].inthreeway = 1;
04347                      p->subs[SUB_REAL].inthreeway = 1;
04348                      if (ast->_state == AST_STATE_UP) {
04349                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04350                         otherindex = SUB_REAL;
04351                      }
04352                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04353                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04354                      p->subs[otherindex].needunhold = 1;
04355                      p->owner = p->subs[SUB_REAL].owner;
04356                      if (ast->_state == AST_STATE_RINGING) {
04357                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04358                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04359                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04360                      }
04361                   } else {
04362                      if (option_verbose > 2)
04363                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04364                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04365                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04366                      p->owner = p->subs[SUB_REAL].owner;
04367                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04368                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04369                      p->subs[SUB_REAL].needunhold = 1;
04370                      zt_enable_ec(p);
04371                   }
04372                      
04373                }
04374             }
04375          winkflashdone:              
04376             update_conf(p);
04377             break;
04378          case SIG_EM:
04379          case SIG_EM_E1:
04380          case SIG_EMWINK:
04381          case SIG_FEATD:
04382          case SIG_SF:
04383          case SIG_SFWINK:
04384          case SIG_SF_FEATD:
04385          case SIG_FXSLS:
04386          case SIG_FXSGS:
04387             if (p->dialing)
04388                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04389             else
04390                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04391             break;
04392          case SIG_FEATDMF_TA:
04393             switch (p->whichwink) {
04394             case 0:
04395                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04396                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04397                break;
04398             case 1:
04399                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04400                break;
04401             case 2:
04402                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04403                return NULL;
04404             }
04405             p->whichwink++;
04406             /* Fall through */
04407          case SIG_FEATDMF:
04408          case SIG_E911:
04409          case SIG_FGC_CAMAMF:
04410          case SIG_FGC_CAMA:
04411          case SIG_FEATB:
04412          case SIG_SF_FEATDMF:
04413          case SIG_SF_FEATB:
04414             /* FGD MF *Must* wait for wink */
04415             if (!ast_strlen_zero(p->dop.dialstr))
04416                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04417             else if (res < 0) {
04418                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04419                p->dop.dialstr[0] = '\0';
04420                return NULL;
04421             } else 
04422                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04423             p->dop.dialstr[0] = '\0';
04424             break;
04425          default:
04426             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04427          }
04428          break;
04429       case ZT_EVENT_HOOKCOMPLETE:
04430          if (p->inalarm) break;
04431          if ((p->radio || (p->oprmode < 0))) break;
04432          switch (mysig) {
04433          case SIG_FXSLS:  /* only interesting for FXS */
04434          case SIG_FXSGS:
04435          case SIG_FXSKS:
04436          case SIG_EM:
04437          case SIG_EM_E1:
04438          case SIG_EMWINK:
04439          case SIG_FEATD:
04440          case SIG_SF:
04441          case SIG_SFWINK:
04442          case SIG_SF_FEATD:
04443             if (!ast_strlen_zero(p->dop.dialstr)) 
04444                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04445             else if (res < 0) {
04446                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04447                p->dop.dialstr[0] = '\0';
04448                return NULL;
04449             } else 
04450                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04451             p->dop.dialstr[0] = '\0';
04452             p->dop.op = ZT_DIAL_OP_REPLACE;
04453             break;
04454          case SIG_FEATDMF:
04455          case SIG_FEATDMF_TA:
04456          case SIG_E911:
04457          case SIG_FGC_CAMA:
04458          case SIG_FGC_CAMAMF:
04459          case SIG_FEATB:
04460          case SIG_SF_FEATDMF:
04461          case SIG_SF_FEATB:
04462             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04463             break;
04464          default:
04465             break;
04466          }
04467          break;
04468       case ZT_EVENT_POLARITY:
04469          /*
04470           * If we get a Polarity Switch event, check to see
04471           * if we should change the polarity state and
04472           * mark the channel as UP or if this is an indication
04473           * of remote end disconnect.
04474           */
04475          if (p->polarity == POLARITY_IDLE) {
04476             p->polarity = POLARITY_REV;
04477             if (p->answeronpolarityswitch &&
04478                 ((ast->_state == AST_STATE_DIALING) ||
04479                 (ast->_state == AST_STATE_RINGING))) {
04480                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04481                ast_setstate(p->owner, AST_STATE_UP);
04482                if (p->hanguponpolarityswitch) {
04483                   gettimeofday(&p->polaritydelaytv, NULL);
04484                }
04485             } else
04486                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04487          } 
04488          /* Removed else statement from here as it was preventing hangups from ever happening*/
04489          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04490          if (p->hanguponpolarityswitch &&
04491             (p->polarityonanswerdelay > 0) &&
04492                 (p->polarity == POLARITY_REV) &&
04493             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04494                                 /* Added log_debug information below to provide a better indication of what is going on */
04495             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) );
04496          
04497             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04498                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04499                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04500                p->polarity = POLARITY_IDLE;
04501             } else {
04502                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);
04503             }
04504          } else {
04505             p->polarity = POLARITY_IDLE;
04506             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04507          }
04508                         /* Added more log_debug information below to provide a better indication of what is going on */
04509          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) );
04510          break;
04511       default:
04512          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04513    }
04514    return &p->subs[index].f;
04515 }
04516 
04517 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04518 {
04519    struct zt_pvt *p = ast->tech_pvt;
04520    int res;
04521    int usedindex=-1;
04522    int index;
04523    struct ast_frame *f;
04524 
04525 
04526    index = zt_get_index(ast, p, 1);
04527    
04528    p->subs[index].f.frametype = AST_FRAME_NULL;
04529    p->subs[index].f.datalen = 0;
04530    p->subs[index].f.samples = 0;
04531    p->subs[index].f.mallocd = 0;
04532    p->subs[index].f.offset = 0;
04533    p->subs[index].f.subclass = 0;
04534    p->subs[index].f.delivery = ast_tv(0,0);
04535    p->subs[index].f.src = "zt_exception";
04536    p->subs[index].f.data = NULL;
04537    
04538    
04539    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04540       /* If nobody owns us, absorb the event appropriately, otherwise
04541          we loop indefinitely.  This occurs when, during call waiting, the
04542          other end hangs up our channel so that it no longer exists, but we
04543          have neither FLASH'd nor ONHOOK'd to signify our desire to
04544          change to the other channel. */
04545       if (p->fake_event) {
04546          res = p->fake_event;
04547          p->fake_event = 0;
04548       } else
04549          res = zt_get_event(p->subs[SUB_REAL].zfd);
04550       /* Switch to real if there is one and this isn't something really silly... */
04551       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04552          (res != ZT_EVENT_HOOKCOMPLETE)) {
04553          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04554          p->owner = p->subs[SUB_REAL].owner;
04555          if (p->owner && ast_bridged_channel(p->owner))
04556             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04557          p->subs[SUB_REAL].needunhold = 1;
04558       }
04559       switch (res) {
04560       case ZT_EVENT_ONHOOK:
04561          zt_disable_ec(p);
04562          if (p->owner) {
04563             if (option_verbose > 2) 
04564                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04565             zt_ring_phone(p);
04566             p->callwaitingrepeat = 0;
04567             p->cidcwexpire = 0;
04568          } else
04569             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04570          update_conf(p);
04571          break;
04572       case ZT_EVENT_RINGOFFHOOK:
04573          zt_enable_ec(p);
04574          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04575          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04576             p->subs[SUB_REAL].needanswer = 1;
04577             p->dialing = 0;
04578          }
04579          break;
04580       case ZT_EVENT_HOOKCOMPLETE:
04581       case ZT_EVENT_RINGERON:
04582       case ZT_EVENT_RINGEROFF:
04583          /* Do nothing */
04584          break;
04585       case ZT_EVENT_WINKFLASH:
04586          gettimeofday(&p->flashtime, NULL);
04587          if (p->owner) {
04588             if (option_verbose > 2) 
04589                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04590             if (p->owner->_state != AST_STATE_UP) {
04591                /* Answer if necessary */
04592                usedindex = zt_get_index(p->owner, p, 0);
04593                if (usedindex > -1) {
04594                   p->subs[usedindex].needanswer = 1;
04595                }
04596                ast_setstate(p->owner, AST_STATE_UP);
04597             }
04598             p->callwaitingrepeat = 0;
04599             p->cidcwexpire = 0;
04600             if (ast_bridged_channel(p->owner))
04601                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04602             p->subs[SUB_REAL].needunhold = 1;
04603          } else
04604             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04605          update_conf(p);
04606          break;
04607       default:
04608          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04609       }
04610       f = &p->subs[index].f;
04611       return f;
04612    }
04613    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04614       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04615    /* If it's not us, return NULL immediately */
04616    if (ast != p->owner) {
04617       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04618       f = &p->subs[index].f;
04619       return f;
04620    }
04621    f = zt_handle_event(ast);
04622    return f;
04623 }
04624 
04625 static struct ast_frame *zt_exception(struct ast_channel *ast)
04626 {
04627    struct zt_pvt *p = ast->tech_pvt;
04628    struct ast_frame *f;
04629    ast_mutex_lock(&p->lock);
04630    f = __zt_exception(ast);
04631    ast_mutex_unlock(&p->lock);
04632    return f;
04633 }
04634 
04635 static struct ast_frame  *zt_read(struct ast_channel *ast)
04636 {
04637    struct zt_pvt *p = ast->tech_pvt;
04638    int res;
04639    int index;
04640    void *readbuf;
04641    struct ast_frame *f;
04642    
04643 
04644    ast_mutex_lock(&p->lock);
04645    
04646    index = zt_get_index(ast, p, 0);
04647    
04648    /* Hang up if we don't really exist */
04649    if (index < 0) {
04650       ast_log(LOG_WARNING, "We dont exist?\n");
04651       ast_mutex_unlock(&p->lock);
04652       return NULL;
04653    }
04654    
04655    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04656 
04657    p->subs[index].f.frametype = AST_FRAME_NULL;
04658    p->subs[index].f.datalen = 0;
04659    p->subs[index].f.samples = 0;
04660    p->subs[index].f.mallocd = 0;
04661    p->subs[index].f.offset = 0;
04662    p->subs[index].f.subclass = 0;
04663    p->subs[index].f.delivery = ast_tv(0,0);
04664    p->subs[index].f.src = "zt_read";
04665    p->subs[index].f.data = NULL;
04666    
04667    /* make sure it sends initial key state as first frame */
04668    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04669    {
04670       ZT_PARAMS ps;
04671 
04672       ps.channo = p->channel;
04673       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04674          ast_mutex_unlock(&p->lock);
04675          return NULL;
04676       }
04677       p->firstradio = 1;
04678       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04679       if (ps.rxisoffhook)
04680       {
04681          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04682       }
04683       else
04684       {
04685          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04686       }
04687       ast_mutex_unlock(&p->lock);
04688       return &p->subs[index].f;
04689    }
04690    if (p->ringt == 1) {
04691       ast_mutex_unlock(&p->lock);
04692       return NULL;
04693    }
04694    else if (p->ringt > 0) 
04695       p->ringt--;
04696 
04697    if (p->subs[index].needringing) {
04698       /* Send ringing frame if requested */
04699       p->subs[index].needringing = 0;
04700       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04701       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04702       ast_setstate(ast, AST_STATE_RINGING);
04703       ast_mutex_unlock(&p->lock);
04704       return &p->subs[index].f;
04705    }
04706 
04707    if (p->subs[index].needbusy) {
04708       /* Send busy frame if requested */
04709       p->subs[index].needbusy = 0;
04710       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04711       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04712       ast_mutex_unlock(&p->lock);
04713       return &p->subs[index].f;
04714    }
04715 
04716    if (p->subs[index].needcongestion) {
04717       /* Send congestion frame if requested */
04718       p->subs[index].needcongestion = 0;
04719       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04720       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04721       ast_mutex_unlock(&p->lock);
04722       return &p->subs[index].f;
04723    }
04724 
04725    if (p->subs[index].needcallerid) {
04726       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04727                      S_OR(p->lastcid_name, NULL),
04728                      S_OR(p->lastcid_num, NULL)
04729                      );
04730       p->subs[index].needcallerid = 0;
04731    }
04732    
04733    if (p->subs[index].needanswer) {
04734       /* Send answer frame if requested */
04735       p->subs[index].needanswer = 0;
04736       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04737       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04738       ast_mutex_unlock(&p->lock);
04739       return &p->subs[index].f;
04740    }  
04741    
04742    if (p->subs[index].needflash) {
04743       /* Send answer frame if requested */
04744       p->subs[index].needflash = 0;
04745       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04746       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04747       ast_mutex_unlock(&p->lock);
04748       return &p->subs[index].f;
04749    }  
04750    
04751    if (p->subs[index].needhold) {
04752       /* Send answer frame if requested */
04753       p->subs[index].needhold = 0;
04754       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04755       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04756       ast_mutex_unlock(&p->lock);
04757       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04758       return &p->subs[index].f;
04759    }  
04760    
04761    if (p->subs[index].needunhold) {
04762       /* Send answer frame if requested */
04763       p->subs[index].needunhold = 0;
04764       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04765       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04766       ast_mutex_unlock(&p->lock);
04767       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04768       return &p->subs[index].f;
04769    }  
04770    
04771    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04772       if (!p->subs[index].linear) {
04773          p->subs[index].linear = 1;
04774          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04775          if (res) 
04776             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04777       }
04778    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04779          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04780       if (p->subs[index].linear) {
04781          p->subs[index].linear = 0;
04782          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04783          if (res) 
04784             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04785       }
04786    } else {
04787       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04788       ast_mutex_unlock(&p->lock);
04789       return NULL;
04790    }
04791    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04792    CHECK_BLOCKING(ast);
04793    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04794    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04795    /* Check for hangup */
04796    if (res < 0) {
04797       f = NULL;
04798       if (res == -1)  {
04799          if (errno == EAGAIN) {
04800             /* Return "NULL" frame if there is nobody there */
04801             ast_mutex_unlock(&p->lock);
04802             return &p->subs[index].f;
04803          } else if (errno == ELAST) {
04804             f = __zt_exception(ast);
04805          } else
04806             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04807       }
04808       ast_mutex_unlock(&p->lock);
04809       return f;
04810    }
04811    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04812       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04813       f = __zt_exception(ast);
04814       ast_mutex_unlock(&p->lock);
04815       return f;
04816    }
04817    if (p->tdd) { /* if in TDD mode, see if we receive that */
04818       int c;
04819 
04820       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04821       if (c < 0) {
04822          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04823          ast_mutex_unlock(&p->lock);
04824          return NULL;
04825       }
04826       if (c) { /* if a char to return */
04827          p->subs[index].f.subclass = 0;
04828          p->subs[index].f.frametype = AST_FRAME_TEXT;
04829          p->subs[index].f.mallocd = 0;
04830          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04831          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04832          p->subs[index].f.datalen = 1;
04833          *((char *) p->subs[index].f.data) = c;
04834          ast_mutex_unlock(&p->lock);
04835          return &p->subs[index].f;
04836       }
04837    }
04838    if (p->callwaitingrepeat)
04839       p->callwaitingrepeat--;
04840    if (p->cidcwexpire)
04841       p->cidcwexpire--;
04842    /* Repeat callwaiting */
04843    if (p->callwaitingrepeat == 1) {
04844       p->callwaitrings++;
04845       zt_callwait(ast);
04846    }
04847    /* Expire CID/CW */
04848    if (p->cidcwexpire == 1) {
04849       if (option_verbose > 2)
04850          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
04851       restore_conference(p);
04852    }
04853    if (p->subs[index].linear) {
04854       p->subs[index].f.datalen = READ_SIZE * 2;
04855    } else 
04856       p->subs[index].f.datalen = READ_SIZE;
04857 
04858    /* Handle CallerID Transmission */
04859    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
04860       send_callerid(p);
04861    }
04862 
04863    p->subs[index].f.frametype = AST_FRAME_VOICE;
04864    p->subs[index].f.subclass = ast->rawreadformat;
04865    p->subs[index].f.samples = READ_SIZE;
04866    p->subs[index].f.mallocd = 0;
04867    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04868    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
04869 #if 0
04870    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
04871 #endif   
04872    if (p->dialing || /* Transmitting something */
04873       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
04874       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
04875       ) {
04876       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
04877          don't send anything */
04878       p->subs[index].f.frametype = AST_FRAME_NULL;
04879       p->subs[index].f.subclass = 0;
04880       p->subs[index].f.samples = 0;
04881       p->subs[index].f.mallocd = 0;
04882       p->subs[index].f.offset = 0;
04883       p->subs[index].f.data = NULL;
04884       p->subs[index].f.datalen= 0;
04885    }
04886    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
04887       /* Perform busy detection. etc on the zap line */
04888       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
04889       if (f) {
04890          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
04891             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
04892                /* Treat this as a "hangup" instead of a "busy" on the assumption that
04893                   a busy  */
04894                f = NULL;
04895             }
04896          } else if (f->frametype == AST_FRAME_DTMF) {
04897 #ifdef HAVE_PRI
04898             if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
04899                /* Don't accept in-band DTMF when in overlap dial mode */
04900                f->frametype = AST_FRAME_NULL;
04901                f->subclass = 0;
04902             }
04903 #endif            
04904             /* DSP clears us of being pulse */
04905             p->pulsedial = 0;
04906          }
04907       }
04908    } else 
04909       f = &p->subs[index].f; 
04910 
04911    if (f && (f->frametype == AST_FRAME_DTMF))
04912       zt_handle_dtmfup(ast, index, &f);
04913 
04914    /* If we have a fake_event, trigger exception to handle it */
04915    if (p->fake_event)
04916       ast_set_flag(ast, AST_FLAG_EXCEPTION);
04917 
04918    ast_mutex_unlock(&p->lock);
04919    return f;
04920 }
04921 
04922 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
04923 {
04924    int sent=0;
04925    int size;
04926    int res;
04927    int fd;
04928    fd = p->subs[index].zfd;
04929    while (len) {
04930       size = len;
04931       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
04932          size = (linear ? READ_SIZE * 2 : READ_SIZE);
04933       res = write(fd, buf, size);
04934       if (res != size) {
04935          if (option_debug)
04936             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
04937          return sent;
04938       }
04939       len -= size;
04940       buf += size;
04941    }
04942    return sent;
04943 }
04944 
04945 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
04946 {
04947    struct zt_pvt *p = ast->tech_pvt;
04948    int res;
04949    int index;
04950    index = zt_get_index(ast, p, 0);
04951    if (index < 0) {
04952       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
04953       return -1;
04954    }
04955 
04956 #if 0
04957 #ifdef HAVE_PRI
04958    ast_mutex_lock(&p->lock);
04959    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
04960       if (p->pri->pri) {      
04961          if (!pri_grab(p, p->pri)) {
04962                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
04963                pri_rel(p->pri);
04964          } else
04965                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
04966       }
04967       p->proceeding=1;
04968    }
04969    ast_mutex_unlock(&p->lock);
04970 #endif
04971 #endif
04972    /* Write a frame of (presumably voice) data */
04973    if (frame->frametype != AST_FRAME_VOICE) {
04974       if (frame->frametype != AST_FRAME_IMAGE)
04975          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
04976       return 0;
04977    }
04978    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
04979        (frame->subclass != AST_FORMAT_ULAW) &&
04980        (frame->subclass != AST_FORMAT_ALAW)) {
04981       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
04982       return -1;
04983    }
04984    if (p->dialing) {
04985       if (option_debug)
04986          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
04987       return 0;
04988    }
04989    if (!p->owner) {
04990       if (option_debug)
04991          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
04992       return 0;
04993    }
04994    if (p->cidspill) {
04995       if (option_debug)
04996          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
04997       return 0;
04998    }
04999    /* Return if it's not valid data */
05000    if (!frame->data || !frame->datalen)
05001       return 0;
05002 
05003    if (frame->subclass == AST_FORMAT_SLINEAR) {
05004       if (!p->subs[index].linear) {
05005          p->subs[index].linear = 1;
05006          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05007          if (res)
05008             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05009       }
05010       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05011    } else {
05012       /* x-law already */
05013       if (p->subs[index].linear) {
05014          p->subs[index].linear = 0;
05015          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05016          if (res)
05017             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05018       }
05019       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05020    }
05021    if (res < 0) {
05022       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05023       return -1;
05024    } 
05025    return 0;
05026 }
05027 
05028 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05029 {
05030    struct zt_pvt *p = chan->tech_pvt;
05031    int res=-1;
05032    int index;
05033    int func = ZT_FLASH;
05034    ast_mutex_lock(&p->lock);
05035    index = zt_get_index(chan, p, 0);
05036    if (option_debug)
05037       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05038    if (index == SUB_REAL) {
05039       switch (condition) {
05040       case AST_CONTROL_BUSY:
05041 #ifdef HAVE_PRI
05042          if (p->priindication_oob && p->sig == SIG_PRI) {
05043             chan->hangupcause = AST_CAUSE_USER_BUSY;
05044             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05045             res = 0;
05046          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05047             if (p->pri->pri) {      
05048                if (!pri_grab(p, p->pri)) {
05049                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05050                   pri_rel(p->pri);
05051                }
05052                else
05053                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05054             }
05055             p->progress = 1;
05056             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05057          } else
05058 #endif
05059             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05060          break;
05061       case AST_CONTROL_RINGING:
05062 #ifdef HAVE_PRI
05063          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05064             if (p->pri->pri) {      
05065                if (!pri_grab(p, p->pri)) {
05066                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05067                   pri_rel(p->pri);
05068                }
05069                else
05070                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05071             }
05072             p->alerting = 1;
05073          }
05074 #endif
05075          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05076          if (chan->_state != AST_STATE_UP) {
05077             if ((chan->_state != AST_STATE_RING) ||
05078                ((p->sig != SIG_FXSKS) &&
05079                 (p->sig != SIG_FXSLS) &&
05080                 (p->sig != SIG_FXSGS)))
05081                ast_setstate(chan, AST_STATE_RINGING);
05082          }
05083          break;
05084       case AST_CONTROL_PROCEEDING:
05085          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05086 #ifdef HAVE_PRI
05087          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05088             if (p->pri->pri) {      
05089                if (!pri_grab(p, p->pri)) {
05090                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05091                   pri_rel(p->pri);
05092                }
05093                else
05094                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05095             }
05096             p->proceeding = 1;
05097          }
05098 #endif
05099          /* don't continue in ast_indicate */
05100          res = 0;
05101          break;
05102       case AST_CONTROL_PROGRESS:
05103          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05104 #ifdef HAVE_PRI
05105          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05106          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05107             if (p->pri->pri) {      
05108                if (!pri_grab(p, p->pri)) {
05109                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05110                   pri_rel(p->pri);
05111                }
05112                else
05113                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05114             }
05115             p->progress = 1;
05116          }
05117 #endif
05118          /* don't continue in ast_indicate */
05119          res = 0;
05120          break;
05121       case AST_CONTROL_CONGESTION:
05122          chan->hangupcause = AST_CAUSE_CONGESTION;
05123 #ifdef HAVE_PRI
05124          if (p->priindication_oob && p->sig == SIG_PRI) {
05125             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05126             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05127             res = 0;
05128          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05129             if (p->pri) {     
05130                if (!pri_grab(p, p->pri)) {
05131                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05132                   pri_rel(p->pri);
05133                } else
05134                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05135             }
05136             p->progress = 1;
05137             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05138          } else
05139 #endif
05140             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05141          break;
05142       case AST_CONTROL_HOLD:
05143 #ifdef HAVE_PRI
05144          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05145             if (!pri_grab(p, p->pri)) {
05146                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05147                pri_rel(p->pri);
05148             } else
05149                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05150          } else
05151 #endif
05152             ast_moh_start(chan, data, p->mohinterpret);
05153          break;
05154       case AST_CONTROL_UNHOLD:
05155 #ifdef HAVE_PRI
05156          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05157             if (!pri_grab(p, p->pri)) {
05158                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05159                pri_rel(p->pri);
05160             } else
05161                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05162          } else
05163 #endif
05164             ast_moh_stop(chan);
05165          break;
05166       case AST_CONTROL_RADIO_KEY:
05167          if (p->radio) 
05168              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05169          res = 0;
05170          break;
05171       case AST_CONTROL_RADIO_UNKEY:
05172          if (p->radio)
05173              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05174          res = 0;
05175          break;
05176       case AST_CONTROL_FLASH:
05177          /* flash hookswitch */
05178          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05179             /* Clear out the dial buffer */
05180             p->dop.dialstr[0] = '\0';
05181             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05182                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05183                   chan->name, strerror(errno));
05184             } else
05185                res = 0;
05186          } else
05187             res = 0;
05188          break;
05189       case AST_CONTROL_SRCUPDATE:
05190          res = 0;
05191          break;
05192       case -1:
05193          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05194          break;
05195       }
05196    } else
05197       res = 0;
05198    ast_mutex_unlock(&p->lock);
05199    return res;
05200 }
05201 
05202 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05203 {
05204    struct ast_channel *tmp;
05205    int deflaw;
05206    int res;
05207    int x,y;
05208    int features;
05209    char *b2 = NULL;
05210    ZT_PARAMS ps;
05211    if (i->subs[index].owner) {
05212       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05213       return NULL;
05214    }
05215    y = 1;
05216    do {
05217       if (b2)
05218          free(b2);
05219 #ifdef HAVE_PRI
05220       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05221          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05222       else
05223 #endif
05224       if (i->channel == CHAN_PSEUDO)
05225          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05226       else  
05227          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05228       for (x = 0; x < 3; x++) {
05229          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05230             break;
05231       }
05232       y++;
05233    } while (x < 3);
05234    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05235    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05236       free(b2);
05237    if (!tmp)
05238       return NULL;
05239    tmp->tech = &zap_tech;
05240    ps.channo = i->channel;
05241    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05242    if (res) {
05243       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05244       ps.curlaw = ZT_LAW_MULAW;
05245    }
05246    if (ps.curlaw == ZT_LAW_ALAW)
05247       deflaw = AST_FORMAT_ALAW;
05248    else
05249       deflaw = AST_FORMAT_ULAW;
05250    if (law) {
05251       if (law == ZT_LAW_ALAW)
05252          deflaw = AST_FORMAT_ALAW;
05253       else
05254          deflaw = AST_FORMAT_ULAW;
05255    }
05256    tmp->fds[0] = i->subs[index].zfd;
05257    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05258    /* Start out assuming ulaw since it's smaller :) */
05259    tmp->rawreadformat = deflaw;
05260    tmp->readformat = deflaw;
05261    tmp->rawwriteformat = deflaw;
05262    tmp->writeformat = deflaw;
05263    i->subs[index].linear = 0;
05264    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05265    features = 0;
05266    if (index == SUB_REAL) {
05267       if (i->busydetect && CANBUSYDETECT(i))
05268          features |= DSP_FEATURE_BUSY_DETECT;
05269       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05270          features |= DSP_FEATURE_CALL_PROGRESS;
05271       if ((!i->outgoing && (i->callprogress & 4)) || 
05272           (i->outgoing && (i->callprogress & 2))) {
05273          features |= DSP_FEATURE_FAX_DETECT;
05274       }
05275 #ifdef ZT_TONEDETECT
05276       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05277       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05278 #endif      
05279          i->hardwaredtmf = 0;
05280          features |= DSP_FEATURE_DTMF_DETECT;
05281 #ifdef ZT_TONEDETECT
05282       } else if (NEED_MFDETECT(i)) {
05283          i->hardwaredtmf = 1;
05284          features |= DSP_FEATURE_DTMF_DETECT;
05285       }
05286 #endif
05287    }
05288    if (features) {
05289       if (i->dsp) {
05290          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05291       } else {
05292          if (i->channel != CHAN_PSEUDO)
05293             i->dsp = ast_dsp_new();
05294          else
05295             i->dsp = NULL;
05296          if (i->dsp) {
05297             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05298 #ifdef HAVE_PRI
05299             /* We cannot do progress detection until receives PROGRESS message */
05300             if (i->outgoing && (i->sig == SIG_PRI)) {
05301                /* Remember requested DSP features, don't treat
05302                   talking as ANSWER */
05303                features = 0;
05304             }
05305 #endif
05306             ast_dsp_set_features(i->dsp, features);
05307             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05308             if (!ast_strlen_zero(progzone))
05309                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05310             if (i->busydetect && CANBUSYDETECT(i)) {
05311                ast_dsp_set_busy_count(i->dsp, i->busycount);
05312                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05313             }
05314          }
05315       }
05316    }
05317       
05318    if (state == AST_STATE_RING)
05319       tmp->rings = 1;
05320    tmp->tech_pvt = i;
05321    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05322       /* Only FXO signalled stuff can be picked up */
05323       tmp->callgroup = i->callgroup;
05324       tmp->pickupgroup = i->pickupgroup;
05325    }
05326    if (!ast_strlen_zero(i->language))
05327       ast_string_field_set(tmp, language, i->language);
05328    if (!i->owner)
05329       i->owner = tmp;
05330    if (!ast_strlen_zero(i->accountcode))
05331       ast_string_field_set(tmp, accountcode, i->accountcode);
05332    if (i->amaflags)
05333       tmp->amaflags = i->amaflags;
05334    i->subs[index].owner = tmp;
05335    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05336    ast_string_field_set(tmp, call_forward, i->call_forward);
05337    /* If we've been told "no ADSI" then enforce it */
05338    if (!i->adsi)
05339       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05340    if (!ast_strlen_zero(i->exten))
05341       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05342    if (!ast_strlen_zero(i->rdnis))
05343       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05344    if (!ast_strlen_zero(i->dnid))
05345       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05346 
05347    /* Don't use ast_set_callerid() here because it will
05348     * generate a needless NewCallerID event */
05349 #ifdef PRI_ANI
05350    if (!ast_strlen_zero(i->cid_ani))
05351       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05352    else  
05353       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05354 #else
05355    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05356 #endif
05357    tmp->cid.cid_pres = i->callingpres;
05358    tmp->cid.cid_ton = i->cid_ton;
05359 #ifdef HAVE_PRI
05360    tmp->transfercapability = transfercapability;
05361    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05362    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05363       i->digital = 1;
05364    /* Assume calls are not idle calls unless we're told differently */
05365    i->isidlecall = 0;
05366    i->alreadyhungup = 0;
05367 #endif
05368    /* clear the fake event in case we posted one before we had ast_channel */
05369    i->fake_event = 0;
05370    /* Assure there is no confmute on this channel */
05371    zt_confmute(i, 0);
05372    /* Configure the new channel jb */
05373    ast_jb_configure(tmp, &global_jbconf);
05374    if (startpbx) {
05375       if (ast_pbx_start(tmp)) {
05376          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05377          ast_hangup(tmp);
05378          i->owner = NULL;
05379          return NULL;
05380       }
05381    }
05382 
05383    ast_module_ref(ast_module_info->self);
05384    
05385    return tmp;
05386 }
05387 
05388 
05389 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05390 {
05391    char c;
05392 
05393    *str = 0; /* start with empty output buffer */
05394    for (;;)
05395    {
05396       /* Wait for the first digit (up to specified ms). */
05397       c = ast_waitfordigit(chan, ms);
05398       /* if timeout, hangup or error, return as such */
05399       if (c < 1)
05400          return c;
05401       *str++ = c;
05402       *str = 0;
05403       if (strchr(term, c))
05404          return 1;
05405    }
05406 }
05407 
05408 static int zt_wink(struct zt_pvt *p, int index)
05409 {
05410    int j;
05411    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05412    for (;;)
05413    {
05414          /* set bits of interest */
05415       j = ZT_IOMUX_SIGEVENT;
05416           /* wait for some happening */
05417       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05418          /* exit loop if we have it */
05419       if (j & ZT_IOMUX_SIGEVENT) break;
05420    }
05421      /* get the event info */
05422    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05423    return 0;
05424 }
05425 
05426 static void *ss_thread(void *data)
05427 {
05428    struct ast_channel *chan = data;
05429    struct zt_pvt *p = chan->tech_pvt;
05430    char exten[AST_MAX_EXTENSION] = "";
05431    char exten2[AST_MAX_EXTENSION] = "";
05432    unsigned char buf[256];
05433    char dtmfcid[300];
05434    char dtmfbuf[300];
05435    struct callerid_state *cs = NULL;
05436    char *name = NULL, *number = NULL;
05437    int distMatches;
05438    int curRingData[3];
05439    int receivedRingT;
05440    int counter1;
05441    int counter;
05442    int samples = 0;
05443    struct ast_smdi_md_message *smdi_msg = NULL;
05444    int flags;
05445    int i;
05446    int timeout;
05447    int getforward = 0;
05448    char *s1, *s2;
05449    int len = 0;
05450    int res;
05451    int index;
05452 
05453    /* in the bizarre case where the channel has become a zombie before we
05454       even get started here, abort safely
05455    */
05456    if (!p) {
05457       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05458       ast_hangup(chan);
05459       return NULL;
05460    }
05461 
05462    if (option_verbose > 2) 
05463       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05464    index = zt_get_index(chan, p, 1);
05465    if (index < 0) {
05466       ast_log(LOG_WARNING, "Huh?\n");
05467       ast_hangup(chan);
05468       return NULL;
05469    }
05470    if (p->dsp)
05471       ast_dsp_digitreset(p->dsp);
05472    switch (p->sig) {
05473 #ifdef HAVE_PRI
05474    case SIG_PRI:
05475       /* Now loop looking for an extension */
05476       ast_copy_string(exten, p->exten, sizeof(exten));
05477       len = strlen(exten);
05478       res = 0;
05479       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05480          if (len && !ast_ignore_pattern(chan->context, exten))
05481             tone_zone_play_tone(p->subs[index].zfd, -1);
05482          else
05483             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05484          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05485             timeout = matchdigittimeout;
05486          else
05487             timeout = gendigittimeout;
05488          res = ast_waitfordigit(chan, timeout);
05489          if (res < 0) {
05490             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05491             ast_hangup(chan);
05492             return NULL;
05493          } else if (res) {
05494             exten[len++] = res;
05495             exten[len] = '\0';
05496          } else
05497             break;
05498       }
05499       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05500       if (ast_strlen_zero(exten)) {
05501          if (option_verbose > 2)
05502             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05503          exten[0] = 's';
05504          exten[1] = '\0';
05505       }
05506       tone_zone_play_tone(p->subs[index].zfd, -1);
05507       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05508          /* Start the real PBX */
05509          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05510          if (p->dsp) ast_dsp_digitreset(p->dsp);
05511          zt_enable_ec(p);
05512          ast_setstate(chan, AST_STATE_RING);
05513          res = ast_pbx_run(chan);
05514          if (res) {
05515             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05516          }
05517       } else {
05518          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05519          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05520          ast_hangup(chan);
05521          p->exten[0] = '\0';
05522          /* Since we send release complete here, we won't get one */
05523          p->call = NULL;
05524       }
05525       return NULL;
05526       break;
05527 #endif
05528    case SIG_FEATD:
05529    case SIG_FEATDMF:
05530    case SIG_FEATDMF_TA:
05531    case SIG_E911:
05532    case SIG_FGC_CAMAMF:
05533    case SIG_FEATB:
05534    case SIG_EMWINK:
05535    case SIG_SF_FEATD:
05536    case SIG_SF_FEATDMF:
05537    case SIG_SF_FEATB:
05538    case SIG_SFWINK:
05539       if (zt_wink(p, index))  
05540          return NULL;
05541       /* Fall through */
05542    case SIG_EM:
05543    case SIG_EM_E1:
05544    case SIG_SF:
05545    case SIG_FGC_CAMA:
05546       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05547       if (p->dsp)
05548          ast_dsp_digitreset(p->dsp);
05549       /* set digit mode appropriately */
05550       if (p->dsp) {
05551          if (NEED_MFDETECT(p))
05552             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05553          else 
05554             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05555       }
05556       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05557       /* Wait for the first digit only if immediate=no */
05558       if (!p->immediate)
05559          /* Wait for the first digit (up to 5 seconds). */
05560          res = ast_waitfordigit(chan, 5000);
05561       else
05562          res = 0;
05563       if (res > 0) {
05564          /* save first char */
05565          dtmfbuf[0] = res;
05566          switch (p->sig) {
05567          case SIG_FEATD:
05568          case SIG_SF_FEATD:
05569             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05570             if (res > 0)
05571                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05572             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05573             break;
05574          case SIG_FEATDMF_TA:
05575             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05576             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05577             if (zt_wink(p, index)) return NULL;
05578             dtmfbuf[0] = 0;
05579             /* Wait for the first digit (up to 5 seconds). */
05580             res = ast_waitfordigit(chan, 5000);
05581             if (res <= 0) break;
05582             dtmfbuf[0] = res;
05583             /* fall through intentionally */
05584          case SIG_FEATDMF:
05585          case SIG_E911:
05586          case SIG_FGC_CAMAMF:
05587          case SIG_SF_FEATDMF:
05588             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05589             /* if international caca, do it again to get real ANO */
05590             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05591             {
05592                if (zt_wink(p, index)) return NULL;
05593                dtmfbuf[0] = 0;
05594                /* Wait for the first digit (up to 5 seconds). */
05595                res = ast_waitfordigit(chan, 5000);
05596                if (res <= 0) break;
05597                dtmfbuf[0] = res;
05598                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05599             }
05600             if (res > 0) {
05601                /* if E911, take off hook */
05602                if (p->sig == SIG_E911)
05603                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05604                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05605             }
05606             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05607             break;
05608          case SIG_FEATB:
05609          case SIG_SF_FEATB:
05610             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05611             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05612             break;
05613          case SIG_EMWINK:
05614             /* if we received a '*', we are actually receiving Feature Group D
05615                dial syntax, so use that mode; otherwise, fall through to normal
05616                mode
05617             */
05618             if (res == '*') {
05619                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05620                if (res > 0)
05621                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05622                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05623                break;
05624             }
05625          default:
05626             /* If we got the first digit, get the rest */
05627             len = 1;
05628             dtmfbuf[len] = '\0';
05629             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05630                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05631                   timeout = matchdigittimeout;
05632                } else {
05633                   timeout = gendigittimeout;
05634                }
05635                res = ast_waitfordigit(chan, timeout);
05636                if (res < 0) {
05637                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05638                   ast_hangup(chan);
05639                   return NULL;
05640                } else if (res) {
05641                   dtmfbuf[len++] = res;
05642                   dtmfbuf[len] = '\0';
05643                } else {
05644                   break;
05645                }
05646             }
05647             break;
05648          }
05649       }
05650       if (res == -1) {
05651          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05652          ast_hangup(chan);
05653          return NULL;
05654       } else if (res < 0) {
05655          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05656          ast_hangup(chan);
05657          return NULL;
05658       }
05659 
05660       if (p->sig == SIG_FGC_CAMA) {
05661          char anibuf[100];
05662 
05663          if (ast_safe_sleep(chan,1000) == -1) {
05664                            ast_hangup(chan);
05665                            return NULL;
05666          }
05667                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05668                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05669                         res = my_getsigstr(chan, anibuf, "#", 10000);
05670                         if ((res > 0) && (strlen(anibuf) > 2)) {
05671             if (anibuf[strlen(anibuf) - 1] == '#')
05672                anibuf[strlen(anibuf) - 1] = 0;
05673             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05674          }
05675                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05676       }
05677 
05678       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05679       if (ast_strlen_zero(exten))
05680          ast_copy_string(exten, "s", sizeof(exten));
05681       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05682          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05683          if (exten[0] == '*') {
05684             char *stringp=NULL;
05685             ast_copy_string(exten2, exten, sizeof(exten2));
05686             /* Parse out extension and callerid */
05687             stringp=exten2 +1;
05688             s1 = strsep(&stringp, "*");
05689             s2 = strsep(&stringp, "*");
05690             if (s2) {
05691                if (!ast_strlen_zero(p->cid_num))
05692                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05693                else
05694                   ast_set_callerid(chan, s1, NULL, s1);
05695                ast_copy_string(exten, s2, sizeof(exten));
05696             } else
05697                ast_copy_string(exten, s1, sizeof(exten));
05698          } else if (p->sig == SIG_FEATD)
05699             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05700       }
05701       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05702          if (exten[0] == '*') {
05703             char *stringp=NULL;
05704             ast_copy_string(exten2, exten, sizeof(exten2));
05705             /* Parse out extension and callerid */
05706             stringp=exten2 +1;
05707             s1 = strsep(&stringp, "#");
05708             s2 = strsep(&stringp, "#");
05709             if (s2) {
05710                if (!ast_strlen_zero(p->cid_num))
05711                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05712                else
05713                   if (*(s1 + 2))
05714                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05715                ast_copy_string(exten, s2 + 1, sizeof(exten));
05716             } else
05717                ast_copy_string(exten, s1 + 2, sizeof(exten));
05718          } else
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_E911) || (p->sig == SIG_FGC_CAMAMF)) {
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 && (*(s2 + 1) == '0')) {
05730                if (*(s2 + 2))
05731                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05732             }
05733             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05734             else ast_copy_string(exten, "911", sizeof(exten));
05735          } else
05736             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05737       }
05738       if (p->sig == SIG_FEATB) {
05739          if (exten[0] == '*') {
05740             char *stringp=NULL;
05741             ast_copy_string(exten2, exten, sizeof(exten2));
05742             /* Parse out extension and callerid */
05743             stringp=exten2 +1;
05744             s1 = strsep(&stringp, "#");
05745             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05746          } else
05747             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05748       }
05749       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05750          zt_wink(p, index);
05751                         /* some switches require a minimum guard time between
05752                            the last FGD wink and something that answers
05753                            immediately. This ensures it */
05754                         if (ast_safe_sleep(chan,100)) return NULL;
05755       }
05756       zt_enable_ec(p);
05757       if (NEED_MFDETECT(p)) {
05758          if (p->dsp) {
05759             if (!p->hardwaredtmf)
05760                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05761             else {
05762                ast_dsp_free(p->dsp);
05763                p->dsp = NULL;
05764             }
05765          }
05766       }
05767 
05768       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05769          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05770          if (p->dsp) ast_dsp_digitreset(p->dsp);
05771          res = ast_pbx_run(chan);
05772          if (res) {
05773             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05774             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05775          }
05776          return NULL;
05777       } else {
05778          if (option_verbose > 2)
05779             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05780          sleep(2);
05781          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05782          if (res < 0)
05783             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05784          else
05785             sleep(1);
05786          res = ast_streamfile(chan, "ss-noservice", chan->language);
05787          if (res >= 0)
05788             ast_waitstream(chan, "");
05789          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05790          ast_hangup(chan);
05791          return NULL;
05792       }
05793       break;
05794    case SIG_FXOLS:
05795    case SIG_FXOGS:
05796    case SIG_FXOKS:
05797       /* Read the first digit */
05798       timeout = firstdigittimeout;
05799       /* If starting a threeway call, never timeout on the first digit so someone
05800          can use flash-hook as a "hold" feature */
05801       if (p->subs[SUB_THREEWAY].owner) 
05802          timeout = 999999;
05803       while (len < AST_MAX_EXTENSION-1) {
05804          /* Read digit unless it's supposed to be immediate, in which case the
05805             only answer is 's' */
05806          if (p->immediate) 
05807             res = 's';
05808          else
05809             res = ast_waitfordigit(chan, timeout);
05810          timeout = 0;
05811          if (res < 0) {
05812             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05813             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05814             ast_hangup(chan);
05815             return NULL;
05816          } else if (res)  {
05817             exten[len++]=res;
05818             exten[len] = '\0';
05819          }
05820          if (!ast_ignore_pattern(chan->context, exten))
05821             tone_zone_play_tone(p->subs[index].zfd, -1);
05822          else
05823             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05824          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05825             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05826                if (getforward) {
05827                   /* Record this as the forwarding extension */
05828                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05829                   if (option_verbose > 2)
05830                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
05831                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05832                   if (res)
05833                      break;
05834                   usleep(500000);
05835                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05836                   sleep(1);
05837                   memset(exten, 0, sizeof(exten));
05838                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05839                   len = 0;
05840                   getforward = 0;
05841                } else  {
05842                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
05843                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05844                   if (!ast_strlen_zero(p->cid_num)) {
05845                      if (!p->hidecallerid)
05846                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
05847                      else
05848                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
05849                   }
05850                   if (!ast_strlen_zero(p->cid_name)) {
05851                      if (!p->hidecallerid)
05852                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
05853                   }
05854                   ast_setstate(chan, AST_STATE_RING);
05855                   zt_enable_ec(p);
05856                   res = ast_pbx_run(chan);
05857                   if (res) {
05858                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
05859                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05860                   }
05861                   return NULL;
05862                }
05863             } else {
05864                /* It's a match, but they just typed a digit, and there is an ambiguous match,
05865                   so just set the timeout to matchdigittimeout and wait some more */
05866                timeout = matchdigittimeout;
05867             }
05868          } else if (res == 0) {
05869             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
05870             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05871             zt_wait_event(p->subs[index].zfd);
05872             ast_hangup(chan);
05873             return NULL;
05874          } else if (p->callwaiting && !strcmp(exten, "*70")) {
05875             if (option_verbose > 2) 
05876                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
05877             /* Disable call waiting if enabled */
05878             p->callwaiting = 0;
05879             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05880             if (res) {
05881                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05882                   chan->name, strerror(errno));
05883             }
05884             len = 0;
05885             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
05886             memset(exten, 0, sizeof(exten));
05887             timeout = firstdigittimeout;
05888                
05889          } else if (!strcmp(exten,ast_pickup_ext())) {
05890             /* Scan all channels and see if there are any
05891              * ringing channels that have call groups
05892              * that equal this channels pickup group  
05893              */
05894             if (index == SUB_REAL) {
05895                /* Switch us from Third call to Call Wait */
05896                if (p->subs[SUB_THREEWAY].owner) {
05897                   /* If you make a threeway call and the *8# a call, it should actually 
05898                      look like a callwait */
05899                   alloc_sub(p, SUB_CALLWAIT);   
05900                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
05901                   unalloc_sub(p, SUB_THREEWAY);
05902                }
05903                zt_enable_ec(p);
05904                if (ast_pickup_call(chan)) {
05905                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
05906                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05907                   zt_wait_event(p->subs[index].zfd);
05908                }
05909                ast_hangup(chan);
05910                return NULL;
05911             } else {
05912                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
05913                ast_hangup(chan);
05914                return NULL;
05915             }
05916             
05917          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
05918             if (option_verbose > 2) 
05919                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
05920             /* Disable Caller*ID if enabled */
05921             p->hidecallerid = 1;
05922             if (chan->cid.cid_num)
05923                free(chan->cid.cid_num);
05924             chan->cid.cid_num = NULL;
05925             if (chan->cid.cid_name)
05926                free(chan->cid.cid_name);
05927             chan->cid.cid_name = NULL;
05928             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05929             if (res) {
05930                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
05931                   chan->name, strerror(errno));
05932             }
05933             len = 0;
05934             memset(exten, 0, sizeof(exten));
05935             timeout = firstdigittimeout;
05936          } else if (p->callreturn && !strcmp(exten, "*69")) {
05937             res = 0;
05938             if (!ast_strlen_zero(p->lastcid_num)) {
05939                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
05940             }
05941             if (!res)
05942                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05943             break;
05944          } else if (!strcmp(exten, "*78")) {
05945             /* Do not disturb */
05946             if (option_verbose > 2)
05947                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
05948             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05949                      "Channel: Zap/%d\r\n"
05950                      "Status: enabled\r\n", p->channel);
05951             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05952             p->dnd = 1;
05953             getforward = 0;
05954             memset(exten, 0, sizeof(exten));
05955             len = 0;
05956          } else if (!strcmp(exten, "*79")) {
05957             /* Do not disturb */
05958             if (option_verbose > 2)
05959                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
05960             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
05961                      "Channel: Zap/%d\r\n"
05962                      "Status: disabled\r\n", p->channel);
05963             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05964             p->dnd = 0;
05965             getforward = 0;
05966             memset(exten, 0, sizeof(exten));
05967             len = 0;
05968          } else if (p->cancallforward && !strcmp(exten, "*72")) {
05969             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05970             getforward = 1;
05971             memset(exten, 0, sizeof(exten));
05972             len = 0;
05973          } else if (p->cancallforward && !strcmp(exten, "*73")) {
05974             if (option_verbose > 2)
05975                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
05976             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05977             memset(p->call_forward, 0, sizeof(p->call_forward));
05978             getforward = 0;
05979             memset(exten, 0, sizeof(exten));
05980             len = 0;
05981          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
05982                   p->subs[SUB_THREEWAY].owner &&
05983                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05984             /* This is a three way call, the main call being a real channel, 
05985                and we're parking the first call. */
05986             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
05987             if (option_verbose > 2)
05988                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
05989             break;
05990          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
05991             if (option_verbose > 2)
05992                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
05993             res = ast_db_put("blacklist", p->lastcid_num, "1");
05994             if (!res) {
05995                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
05996                memset(exten, 0, sizeof(exten));
05997                len = 0;
05998             }
05999          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
06000             if (option_verbose > 2) 
06001                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
06002             /* Enable Caller*ID if enabled */
06003             p->hidecallerid = 0;
06004             if (chan->cid.cid_num)
06005                free(chan->cid.cid_num);
06006             chan->cid.cid_num = NULL;
06007             if (chan->cid.cid_name)
06008                free(chan->cid.cid_name);
06009             chan->cid.cid_name = NULL;
06010             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
06011             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06012             if (res) {
06013                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06014                   chan->name, strerror(errno));
06015             }
06016             len = 0;
06017             memset(exten, 0, sizeof(exten));
06018             timeout = firstdigittimeout;
06019          } else if (!strcmp(exten, "*0")) {
06020             struct ast_channel *nbridge = 
06021                p->subs[SUB_THREEWAY].owner;
06022             struct zt_pvt *pbridge = NULL;
06023               /* set up the private struct of the bridged one, if any */
06024             if (nbridge && ast_bridged_channel(nbridge)) 
06025                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06026             if (nbridge && pbridge && 
06027                 (nbridge->tech == &zap_tech) && 
06028                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06029                 ISTRUNK(pbridge)) {
06030                int func = ZT_FLASH;
06031                /* Clear out the dial buffer */
06032                p->dop.dialstr[0] = '\0';
06033                /* flash hookswitch */
06034                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06035                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06036                      nbridge->name, strerror(errno));
06037                }
06038                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06039                unalloc_sub(p, SUB_THREEWAY);
06040                p->owner = p->subs[SUB_REAL].owner;
06041                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06042                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06043                ast_hangup(chan);
06044                return NULL;
06045             } else {
06046                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06047                zt_wait_event(p->subs[index].zfd);
06048                tone_zone_play_tone(p->subs[index].zfd, -1);
06049                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06050                unalloc_sub(p, SUB_THREEWAY);
06051                p->owner = p->subs[SUB_REAL].owner;
06052                ast_hangup(chan);
06053                return NULL;
06054             }              
06055          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06056                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06057             if (option_debug)
06058                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);
06059             break;
06060          }
06061          if (!timeout)
06062             timeout = gendigittimeout;
06063          if (len && !ast_ignore_pattern(chan->context, exten))
06064             tone_zone_play_tone(p->subs[index].zfd, -1);
06065       }
06066       break;
06067    case SIG_FXSLS:
06068    case SIG_FXSGS:
06069    case SIG_FXSKS:
06070 #ifdef HAVE_PRI
06071       if (p->pri) {
06072          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06073          struct ast_frame *f;
06074          int res;
06075          time_t start;
06076 
06077          time(&start);
06078          ast_setstate(chan, AST_STATE_RING);
06079          while (time(NULL) < start + 3) {
06080             res = ast_waitfor(chan, 1000);
06081             if (res) {
06082                f = ast_read(chan);
06083                if (!f) {
06084                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06085                   ast_hangup(chan);
06086                   return NULL;
06087                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06088                   res = 1;
06089                } else
06090                   res = 0;
06091                ast_frfree(f);
06092                if (res) {
06093                   ast_log(LOG_DEBUG, "Got ring!\n");
06094                   res = 0;
06095                   break;
06096                }
06097             }
06098          }
06099       }
06100 #endif
06101       /* check for SMDI messages */
06102       if (p->use_smdi && p->smdi_iface) {
06103          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06104 
06105          if (smdi_msg != NULL) {
06106             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06107 
06108             if (smdi_msg->type == 'B')
06109                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06110             else if (smdi_msg->type == 'N')
06111                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06112 
06113             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06114          } else {
06115             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06116          }
06117       }
06118 
06119       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06120             number = smdi_msg->calling_st;
06121 
06122       /* If we want caller id, we're in a prering state due to a polarity reversal
06123        * and we're set to use a polarity reversal to trigger the start of caller id,
06124        * grab the caller id and wait for ringing to start... */
06125       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06126          /* If set to use DTMF CID signalling, listen for DTMF */
06127          if (p->cid_signalling == CID_SIG_DTMF) {
06128             int i = 0;
06129             cs = NULL;
06130             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06131                "channel %s\n", chan->name);
06132             zt_setlinear(p->subs[index].zfd, 0);
06133             res = 2000;
06134             for (;;) {
06135                struct ast_frame *f;
06136                res = ast_waitfor(chan, res);
06137                if (res <= 0) {
06138                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06139                      "Exiting simple switch\n");
06140                   ast_hangup(chan);
06141                   return NULL;
06142                } 
06143                f = ast_read(chan);
06144                if (!f)
06145                   break;
06146                if (f->frametype == AST_FRAME_DTMF) {
06147                   dtmfbuf[i++] = f->subclass;
06148                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06149                   res = 2000;
06150                }
06151                ast_frfree(f);
06152                if (chan->_state == AST_STATE_RING ||
06153                    chan->_state == AST_STATE_RINGING) 
06154                   break; /* Got ring */
06155             }
06156             dtmfbuf[i] = '\0';
06157             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06158             /* Got cid and ring. */
06159             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06160             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06161             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06162                dtmfcid, flags);
06163             /* If first byte is NULL, we have no cid */
06164             if (!ast_strlen_zero(dtmfcid)) 
06165                number = dtmfcid;
06166             else
06167                number = NULL;
06168          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06169          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06170             cs = callerid_new(p->cid_signalling);
06171             if (cs) {
06172                samples = 0;
06173 #if 1
06174                bump_gains(p);
06175 #endif            
06176                /* Take out of linear mode for Caller*ID processing */
06177                zt_setlinear(p->subs[index].zfd, 0);
06178                
06179                /* First we wait and listen for the Caller*ID */
06180                for (;;) {  
06181                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06182                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06183                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06184                      callerid_free(cs);
06185                      ast_hangup(chan);
06186                      return NULL;
06187                   }
06188                   if (i & ZT_IOMUX_SIGEVENT) {
06189                      res = zt_get_event(p->subs[index].zfd);
06190                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06191 
06192                      if (p->cid_signalling == CID_SIG_V23_JP) {
06193 #ifdef ZT_EVENT_RINGBEGIN
06194                         if (res == ZT_EVENT_RINGBEGIN) {
06195                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06196                            usleep(1);
06197                         }
06198 #endif
06199                      } else {
06200                         res = 0;
06201                         break;
06202                      }
06203                   } else if (i & ZT_IOMUX_READ) {
06204                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06205                      if (res < 0) {
06206                         if (errno != ELAST) {
06207                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06208                            callerid_free(cs);
06209                            ast_hangup(chan);
06210                            return NULL;
06211                         }
06212                         break;
06213                      }
06214                      samples += res;
06215 
06216                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06217                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06218                      } else {
06219                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06220                      }
06221 
06222                      if (res < 0) {
06223                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06224                         break;
06225                      } else if (res)
06226                         break;
06227                      else if (samples > (8000 * 10))
06228                         break;
06229                   }
06230                }
06231                if (res == 1) {
06232                   callerid_get(cs, &name, &number, &flags);
06233                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06234                }
06235                if (res < 0) {
06236                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06237                }
06238 
06239                if (p->cid_signalling == CID_SIG_V23_JP) {
06240                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06241                   usleep(1);
06242                   res = 4000;
06243                } else {
06244 
06245                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06246                   res = 2000;
06247                }
06248 
06249                for (;;) {
06250                   struct ast_frame *f;
06251                   res = ast_waitfor(chan, res);
06252                   if (res <= 0) {
06253                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06254                         "Exiting simple switch\n");
06255                      ast_hangup(chan);
06256                      return NULL;
06257                   } 
06258                   f = ast_read(chan);
06259                   ast_frfree(f);
06260                   if (chan->_state == AST_STATE_RING ||
06261                       chan->_state == AST_STATE_RINGING) 
06262                      break; /* Got ring */
06263                }
06264    
06265                /* We must have a ring by now, so, if configured, lets try to listen for
06266                 * distinctive ringing */ 
06267                if (p->usedistinctiveringdetection == 1) {
06268                   len = 0;
06269                   distMatches = 0;
06270                   /* Clear the current ring data array so we dont have old data in it. */
06271                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06272                      curRingData[receivedRingT] = 0;
06273                   receivedRingT = 0;
06274                   counter = 0;
06275                   counter1 = 0;
06276                   /* Check to see if context is what it should be, if not set to be. */
06277                   if (strcmp(p->context,p->defcontext) != 0) {
06278                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06279                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06280                   }
06281       
06282                   for (;;) {  
06283                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06284                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06285                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06286                         callerid_free(cs);
06287                         ast_hangup(chan);
06288                         return NULL;
06289                      }
06290                      if (i & ZT_IOMUX_SIGEVENT) {
06291                         res = zt_get_event(p->subs[index].zfd);
06292                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06293                         res = 0;
06294                         /* Let us detect distinctive ring */
06295       
06296                         curRingData[receivedRingT] = p->ringt;
06297       
06298                         if (p->ringt < p->ringt_base/2)
06299                            break;
06300                         /* Increment the ringT counter so we can match it against
06301                            values in zapata.conf for distinctive ring */
06302                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06303                            break;
06304                      } else if (i & ZT_IOMUX_READ) {
06305                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06306                         if (res < 0) {
06307                            if (errno != ELAST) {
06308                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06309                               callerid_free(cs);
06310                               ast_hangup(chan);
06311                               return NULL;
06312                            }
06313                            break;
06314                         }
06315                         if (p->ringt) 
06316                            p->ringt--;
06317                         if (p->ringt == 1) {
06318                            res = -1;
06319                            break;
06320                         }
06321                      }
06322                   }
06323                   if (option_verbose > 2)
06324                      /* this only shows up if you have n of the dring patterns filled in */
06325                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06326    
06327                   for (counter = 0; counter < 3; counter++) {
06328                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06329                      channel */
06330                      distMatches = 0;
06331                      for (counter1 = 0; counter1 < 3; counter1++) {
06332                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06333                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06334                            distMatches++;
06335                         }
06336                      }
06337                      if (distMatches == 3) {
06338                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06339                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06340                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06341                         if (option_verbose > 2)
06342                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06343                         break;
06344                      }
06345                   }
06346                }
06347                /* Restore linear mode (if appropriate) for Caller*ID processing */
06348                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06349 #if 1
06350                restore_gains(p);
06351 #endif            
06352             } else
06353                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06354          } else {
06355             ast_log(LOG_WARNING, "Channel %s in prering "
06356                "state, but I have nothing to do. "
06357                "Terminating simple switch, should be "
06358                "restarted by the actual ring.\n", 
06359                chan->name);
06360             ast_hangup(chan);
06361             return NULL;
06362          }
06363       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06364          /* FSK Bell202 callerID */
06365          cs = callerid_new(p->cid_signalling);
06366          if (cs) {
06367 #if 1
06368             bump_gains(p);
06369 #endif            
06370             samples = 0;
06371             len = 0;
06372             distMatches = 0;
06373             /* Clear the current ring data array so we dont have old data in it. */
06374             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06375                curRingData[receivedRingT] = 0;
06376             receivedRingT = 0;
06377             counter = 0;
06378             counter1 = 0;
06379             /* Check to see if context is what it should be, if not set to be. */
06380             if (strcmp(p->context,p->defcontext) != 0) {
06381                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06382                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06383             }
06384 
06385             /* Take out of linear mode for Caller*ID processing */
06386             zt_setlinear(p->subs[index].zfd, 0);
06387             for (;;) {  
06388                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06389                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06390                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06391                   callerid_free(cs);
06392                   ast_hangup(chan);
06393                   return NULL;
06394                }
06395                if (i & ZT_IOMUX_SIGEVENT) {
06396                   res = zt_get_event(p->subs[index].zfd);
06397                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06398                   /* If we get a PR event, they hung up while processing calerid */
06399                   if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
06400                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
06401                      p->polarity = POLARITY_IDLE;
06402                      callerid_free(cs);
06403                      ast_hangup(chan);
06404                      return NULL;
06405                   }
06406                   res = 0;
06407                   /* Let us detect callerid when the telco uses distinctive ring */
06408 
06409                   curRingData[receivedRingT] = p->ringt;
06410 
06411                   if (p->ringt < p->ringt_base/2)
06412                      break;
06413                   /* Increment the ringT counter so we can match it against
06414                      values in zapata.conf for distinctive ring */
06415                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06416                      break;
06417                } else if (i & ZT_IOMUX_READ) {
06418                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06419                   if (res < 0) {
06420                      if (errno != ELAST) {
06421                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06422                         callerid_free(cs);
06423                         ast_hangup(chan);
06424                         return NULL;
06425                      }
06426                      break;
06427                   }
06428                   if (p->ringt) 
06429                      p->ringt--;
06430                   if (p->ringt == 1) {
06431                      res = -1;
06432                      break;
06433                   }
06434                   samples += res;
06435                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06436                   if (res < 0) {
06437                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06438                      break;
06439                   } else if (res)
06440                      break;
06441                   else if (samples > (8000 * 10))
06442                      break;
06443                }
06444             }
06445             if (res == 1) {
06446                callerid_get(cs, &name, &number, &flags);
06447                if (option_debug)
06448                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06449             }
06450             if (distinctiveringaftercid == 1) {
06451                /* Clear the current ring data array so we dont have old data in it. */
06452                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06453                   curRingData[receivedRingT] = 0;
06454                }
06455                receivedRingT = 0;
06456                if (option_verbose > 2)
06457                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06458                for (;;) {
06459                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06460                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06461                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06462                      callerid_free(cs);
06463                      ast_hangup(chan);
06464                      return NULL;
06465                   }
06466                   if (i & ZT_IOMUX_SIGEVENT) {
06467                      res = zt_get_event(p->subs[index].zfd);
06468                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06469                      res = 0;
06470                      /* Let us detect callerid when the telco uses distinctive ring */
06471 
06472                      curRingData[receivedRingT] = p->ringt;
06473 
06474                      if (p->ringt < p->ringt_base/2)
06475                         break;
06476                      /* Increment the ringT counter so we can match it against
06477                         values in zapata.conf for distinctive ring */
06478                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06479                         break;
06480                   } else if (i & ZT_IOMUX_READ) {
06481                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06482                      if (res < 0) {
06483                         if (errno != ELAST) {
06484                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06485                            callerid_free(cs);
06486                            ast_hangup(chan);
06487                            return NULL;
06488                         }
06489                         break;
06490                      }
06491                   if (p->ringt)
06492                      p->ringt--;
06493                      if (p->ringt == 1) {
06494                         res = -1;
06495                         break;
06496                      }
06497                   }
06498                }
06499             }
06500             if (p->usedistinctiveringdetection == 1) {
06501                if (option_verbose > 2)
06502                   /* this only shows up if you have n of the dring patterns filled in */
06503                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06504 
06505                for (counter = 0; counter < 3; counter++) {
06506                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06507                   channel */
06508                   if (option_verbose > 2)
06509                      /* this only shows up if you have n of the dring patterns filled in */
06510                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06511                         p->drings.ringnum[counter].ring[0],
06512                         p->drings.ringnum[counter].ring[1],
06513                         p->drings.ringnum[counter].ring[2]);
06514                   distMatches = 0;
06515                   for (counter1 = 0; counter1 < 3; counter1++) {
06516                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06517                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06518                         distMatches++;
06519                      }
06520                   }
06521                   if (distMatches == 3) {
06522                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06523                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06524                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06525                      if (option_verbose > 2)
06526                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06527                      break;
06528                   }
06529                }
06530             }
06531             /* Restore linear mode (if appropriate) for Caller*ID processing */
06532             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06533 #if 1
06534             restore_gains(p);
06535 #endif            
06536             if (res < 0) {
06537                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06538             }
06539          } else
06540             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06541       }
06542       else
06543          cs = NULL;
06544 
06545       if (number)
06546          ast_shrink_phone_number(number);
06547       ast_set_callerid(chan, number, name, number);
06548 
06549       if (smdi_msg)
06550          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06551 
06552       if (cs)
06553          callerid_free(cs);
06554 
06555       ast_setstate(chan, AST_STATE_RING);
06556       chan->rings = 1;
06557       p->ringt = p->ringt_base;
06558       res = ast_pbx_run(chan);
06559       if (res) {
06560          ast_hangup(chan);
06561          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06562       }
06563       return NULL;
06564    default:
06565       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06566       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06567       if (res < 0)
06568             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06569    }
06570    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06571    if (res < 0)
06572          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06573    ast_hangup(chan);
06574    return NULL;
06575 }
06576 
06577 /* destroy a zaptel channel, identified by its number */
06578 static int zap_destroy_channel_bynum(int channel)
06579 {
06580    struct zt_pvt *tmp = NULL;
06581    struct zt_pvt *prev = NULL;
06582 
06583    tmp = iflist;
06584    while (tmp) {
06585       if (tmp->channel == channel) {
06586          destroy_channel(prev, tmp, 1);
06587          return RESULT_SUCCESS;
06588       }
06589       prev = tmp;
06590       tmp = tmp->next;
06591    }
06592    return RESULT_FAILURE;
06593 }
06594 
06595 static int handle_init_event(struct zt_pvt *i, int event)
06596 {
06597    int res;
06598    pthread_t threadid;
06599    pthread_attr_t attr;
06600    struct ast_channel *chan;
06601    pthread_attr_init(&attr);
06602    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06603    /* Handle an event on a given channel for the monitor thread. */
06604    switch (event) {
06605    case ZT_EVENT_NONE:
06606    case ZT_EVENT_BITSCHANGED:
06607       break;
06608    case ZT_EVENT_WINKFLASH:
06609    case ZT_EVENT_RINGOFFHOOK:
06610       if (i->inalarm) break;
06611       if (i->radio) break;
06612       /* Got a ring/answer.  What kind of channel are we? */
06613       switch (i->sig) {
06614       case SIG_FXOLS:
06615       case SIG_FXOGS:
06616       case SIG_FXOKS:
06617          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06618          if (res && (errno == EBUSY))
06619             break;
06620          if (i->cidspill) {
06621             /* Cancel VMWI spill */
06622             free(i->cidspill);
06623             i->cidspill = NULL;
06624          }
06625          if (i->immediate) {
06626             zt_enable_ec(i);
06627             /* The channel is immediately up.  Start right away */
06628             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06629             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06630             if (!chan) {
06631                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06632                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06633                if (res < 0)
06634                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06635             }
06636          } else {
06637             /* Check for callerid, digits, etc */
06638             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06639             if (chan) {
06640                if (has_voicemail(i))
06641                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06642                else
06643                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06644                if (res < 0) 
06645                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06646                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06647                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06648                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06649                   if (res < 0)
06650                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06651                   ast_hangup(chan);
06652                }
06653             } else
06654                ast_log(LOG_WARNING, "Unable to create channel\n");
06655          }
06656          break;
06657       case SIG_FXSLS:
06658       case SIG_FXSGS:
06659       case SIG_FXSKS:
06660             i->ringt = i->ringt_base;
06661             /* Fall through */
06662       case SIG_EMWINK:
06663       case SIG_FEATD:
06664       case SIG_FEATDMF:
06665       case SIG_FEATDMF_TA:
06666       case SIG_E911:
06667       case SIG_FGC_CAMA:
06668       case SIG_FGC_CAMAMF:
06669       case SIG_FEATB:
06670       case SIG_EM:
06671       case SIG_EM_E1:
06672       case SIG_SFWINK:
06673       case SIG_SF_FEATD:
06674       case SIG_SF_FEATDMF:
06675       case SIG_SF_FEATB:
06676       case SIG_SF:
06677             /* Check for callerid, digits, etc */
06678             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06679             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06680                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06681                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06682                if (res < 0)
06683                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06684                ast_hangup(chan);
06685             } else if (!chan) {
06686                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06687             }
06688             break;
06689       default:
06690          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06691          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06692          if (res < 0)
06693                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06694          return -1;
06695       }
06696       break;
06697    case ZT_EVENT_NOALARM:
06698       i->inalarm = 0;
06699       if (!i->unknown_alarm) {
06700          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06701          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06702             "Channel: %d\r\n", i->channel);
06703       } else {
06704          i->unknown_alarm = 0;
06705       }
06706       break;
06707    case ZT_EVENT_ALARM:
06708       i->inalarm = 1;
06709       res = get_alarms(i);
06710       do {
06711          const char *alarm_str = alarm2str(res);
06712 
06713          /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
06714           * doesn't know what to do with it.  Don't confuse users with log messages. */
06715          if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
06716             i->unknown_alarm = 1;
06717             break;
06718          } else {
06719             i->unknown_alarm = 0;
06720          }
06721 
06722          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str);
06723          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06724             "Alarm: %s\r\n"
06725             "Channel: %d\r\n",
06726             alarm_str, i->channel);
06727       } while (0);
06728       /* fall thru intentionally */
06729    case ZT_EVENT_ONHOOK:
06730       if (i->radio)
06731          break;
06732       /* Back on hook.  Hang up. */
06733       switch (i->sig) {
06734       case SIG_FXOLS:
06735       case SIG_FXOGS:
06736       case SIG_FEATD:
06737       case SIG_FEATDMF:
06738       case SIG_FEATDMF_TA:
06739       case SIG_E911:
06740       case SIG_FGC_CAMA:
06741       case SIG_FGC_CAMAMF:
06742       case SIG_FEATB:
06743       case SIG_EM:
06744       case SIG_EM_E1:
06745       case SIG_EMWINK:
06746       case SIG_SF_FEATD:
06747       case SIG_SF_FEATDMF:
06748       case SIG_SF_FEATB:
06749       case SIG_SF:
06750       case SIG_SFWINK:
06751       case SIG_FXSLS:
06752       case SIG_FXSGS:
06753       case SIG_FXSKS:
06754       case SIG_GR303FXSKS:
06755          zt_disable_ec(i);
06756          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06757          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06758          break;
06759       case SIG_GR303FXOKS:
06760       case SIG_FXOKS:
06761          zt_disable_ec(i);
06762          /* Diddle the battery for the zhone */
06763 #ifdef ZHONE_HACK
06764          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06765          usleep(1);
06766 #endif         
06767          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06768          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06769          break;
06770       case SIG_PRI:
06771          zt_disable_ec(i);
06772          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06773          break;
06774       default:
06775          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06776          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06777          return -1;
06778       }
06779       break;
06780    case ZT_EVENT_POLARITY:
06781       switch (i->sig) {
06782       case SIG_FXSLS:
06783       case SIG_FXSKS:
06784       case SIG_FXSGS:
06785          /* We have already got a PR before the channel was 
06786             created, but it wasn't handled. We need polarity 
06787             to be REV for remote hangup detection to work. 
06788             At least in Spain */
06789          if (i->hanguponpolarityswitch)
06790             i->polarity = POLARITY_REV;
06791 
06792          if (i->cid_start == CID_START_POLARITY) {
06793             i->polarity = POLARITY_REV;
06794             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06795                    "CID detection on channel %d\n",
06796                    i->channel);
06797             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06798             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06799                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06800             }
06801          }
06802          break;
06803       default:
06804          ast_log(LOG_WARNING, "handle_init_event detected "
06805             "polarity reversal on non-FXO (SIG_FXS) "
06806             "interface %d\n", i->channel);
06807       }
06808       break;
06809    case ZT_EVENT_REMOVED: /* destroy channel */
06810       ast_log(LOG_NOTICE, 
06811             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
06812             i->channel);
06813       zap_destroy_channel_bynum(i->channel);
06814       break;
06815    }
06816    pthread_attr_destroy(&attr);
06817    return 0;
06818 }
06819 
06820 static void *do_monitor(void *data)
06821 {
06822    int count, res, res2, spoint, pollres=0;
06823    struct zt_pvt *i;
06824    struct zt_pvt *last = NULL;
06825    time_t thispass = 0, lastpass = 0;
06826    int found;
06827    char buf[1024];
06828    struct pollfd *pfds=NULL;
06829    int lastalloc = -1;
06830    /* This thread monitors all the frame relay interfaces which are not yet in use
06831       (and thus do not have a separate thread) indefinitely */
06832    /* From here on out, we die whenever asked */
06833 #if 0
06834    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
06835       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
06836       return NULL;
06837    }
06838    ast_log(LOG_DEBUG, "Monitor starting...\n");
06839 #endif
06840    for (;;) {
06841       /* Lock the interface list */
06842       ast_mutex_lock(&iflock);
06843       if (!pfds || (lastalloc != ifcount)) {
06844          if (pfds) {
06845             free(pfds);
06846             pfds = NULL;
06847          }
06848          if (ifcount) {
06849             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
06850                ast_mutex_unlock(&iflock);
06851                return NULL;
06852             }
06853          }
06854          lastalloc = ifcount;
06855       }
06856       /* Build the stuff we're going to poll on, that is the socket of every
06857          zt_pvt that does not have an associated owner channel */
06858       count = 0;
06859       i = iflist;
06860       while (i) {
06861          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
06862             if (!i->owner && !i->subs[SUB_REAL].owner) {
06863                /* This needs to be watched, as it lacks an owner */
06864                pfds[count].fd = i->subs[SUB_REAL].zfd;
06865                pfds[count].events = POLLPRI;
06866                pfds[count].revents = 0;
06867                /* Message waiting or r2 channels also get watched for reading */
06868                if (i->cidspill)
06869                   pfds[count].events |= POLLIN;
06870                count++;
06871             }
06872          }
06873          i = i->next;
06874       }
06875       /* Okay, now that we know what to do, release the interface lock */
06876       ast_mutex_unlock(&iflock);
06877       
06878       pthread_testcancel();
06879       /* Wait at least a second for something to happen */
06880       res = poll(pfds, count, 1000);
06881       pthread_testcancel();
06882       /* Okay, poll has finished.  Let's see what happened.  */
06883       if (res < 0) {
06884          if ((errno != EAGAIN) && (errno != EINTR))
06885             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
06886          continue;
06887       }
06888       /* Alright, lock the interface list again, and let's look and see what has
06889          happened */
06890       ast_mutex_lock(&iflock);
06891       found = 0;
06892       spoint = 0;
06893       lastpass = thispass;
06894       thispass = time(NULL);
06895       i = iflist;
06896       while (i) {
06897          if (thispass != lastpass) {
06898             if (!found && ((i == last) || ((i == iflist) && !last))) {
06899                last = i;
06900                if (last) {
06901                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
06902                      (last->sig & __ZT_SIG_FXO)) {
06903                      res = ast_app_has_voicemail(last->mailbox, NULL);
06904                      if (last->msgstate != res) {
06905                         int x;
06906                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
06907                         x = ZT_FLUSH_BOTH;
06908                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
06909                         if (res2)
06910                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
06911                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
06912                            /* Turn on on hook transfer for 4 seconds */
06913                            x = 4000;
06914                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
06915                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
06916                            last->cidpos = 0;
06917                            last->msgstate = res;
06918                            last->onhooktime = thispass;
06919                         }
06920                         found ++;
06921                      }
06922                   }
06923                   last = last->next;
06924                }
06925             }
06926          }
06927          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
06928             if (i->radio && !i->owner)
06929             {
06930                res = zt_get_event(i->subs[SUB_REAL].zfd);
06931                if (res)
06932                {
06933                   if (option_debug)
06934                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
06935                   /* Don't hold iflock while handling init events */
06936                   ast_mutex_unlock(&iflock);
06937                   handle_init_event(i, res);
06938                   ast_mutex_lock(&iflock);   
06939                }
06940                i = i->next;
06941                continue;
06942             }              
06943             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
06944             if (pollres & POLLIN) {
06945                if (i->owner || i->subs[SUB_REAL].owner) {
06946 #ifdef HAVE_PRI
06947                   if (!i->pri)
06948 #endif                  
06949                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
06950                   i = i->next;
06951                   continue;
06952                }
06953                if (!i->cidspill) {
06954                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
06955                   i = i->next;
06956                   continue;
06957                }
06958                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
06959                if (res > 0) {
06960                   /* We read some number of bytes.  Write an equal amount of data */
06961                   if (res > i->cidlen - i->cidpos) 
06962                      res = i->cidlen - i->cidpos;
06963                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
06964                   if (res2 > 0) {
06965                      i->cidpos += res2;
06966                      if (i->cidpos >= i->cidlen) {
06967                         free(i->cidspill);
06968                         i->cidspill = 0;
06969                         i->cidpos = 0;
06970                         i->cidlen = 0;
06971                      }
06972                   } else {
06973                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
06974                      i->msgstate = -1;
06975                   }
06976                } else {
06977                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
06978                }
06979             }
06980             if (pollres & POLLPRI) {
06981                if (i->owner || i->subs[SUB_REAL].owner) {
06982 #ifdef HAVE_PRI
06983                   if (!i->pri)
06984 #endif                  
06985                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
06986                   i = i->next;
06987                   continue;
06988                }
06989                res = zt_get_event(i->subs[SUB_REAL].zfd);
06990                if (option_debug)
06991                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
06992                /* Don't hold iflock while handling init events */
06993                ast_mutex_unlock(&iflock);
06994                handle_init_event(i, res);
06995                ast_mutex_lock(&iflock);   
06996             }
06997          }
06998          i=i->next;
06999       }
07000       ast_mutex_unlock(&iflock);
07001    }
07002    /* Never reached */
07003    return NULL;
07004    
07005 }
07006 
07007 static int restart_monitor(void)
07008 {
07009    pthread_attr_t attr;
07010    pthread_attr_init(&attr);
07011    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07012    /* If we're supposed to be stopped -- stay stopped */
07013    if (monitor_thread == AST_PTHREADT_STOP)
07014       return 0;
07015    ast_mutex_lock(&monlock);
07016    if (monitor_thread == pthread_self()) {
07017       ast_mutex_unlock(&monlock);
07018       ast_log(LOG_WARNING, "Cannot kill myself\n");
07019       return -1;
07020    }
07021    if (monitor_thread != AST_PTHREADT_NULL) {
07022       /* Wake up the thread */
07023       pthread_kill(monitor_thread, SIGURG);
07024    } else {
07025       /* Start a new monitor */
07026       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
07027          ast_mutex_unlock(&monlock);
07028          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
07029          pthread_attr_destroy(&attr);
07030          return -1;
07031       }
07032    }
07033    ast_mutex_unlock(&monlock);
07034    pthread_attr_destroy(&attr);
07035    return 0;
07036 }
07037 
07038 #ifdef HAVE_PRI
07039 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
07040 {
07041    int x;
07042    int trunkgroup;
07043    /* Get appropriate trunk group if there is one */
07044    trunkgroup = pris[*span].mastertrunkgroup;
07045    if (trunkgroup) {
07046       /* Select a specific trunk group */
07047       for (x = 0; x < NUM_SPANS; x++) {
07048          if (pris[x].trunkgroup == trunkgroup) {
07049             *span = x;
07050             return 0;
07051          }
07052       }
07053       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
07054       *span = -1;
07055    } else {
07056       if (pris[*span].trunkgroup) {
07057          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07058          *span = -1;
07059       } else if (pris[*span].mastertrunkgroup) {
07060          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07061          *span = -1;
07062       } else {
07063          if (si->totalchans == 31) { /* if it's an E1 */
07064             pris[*span].dchannels[0] = 16 + offset;
07065          } else {
07066             pris[*span].dchannels[0] = 24 + offset;
07067          }
07068          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07069          pris[*span].offset = offset;
07070          pris[*span].span = *span + 1;
07071       }
07072    }
07073    return 0;
07074 }
07075 
07076 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07077 {
07078    struct zt_spaninfo si;
07079    ZT_PARAMS p;
07080    int fd;
07081    int span;
07082    int ospan=0;
07083    int x,y;
07084    for (x = 0; x < NUM_SPANS; x++) {
07085       if (pris[x].trunkgroup == trunkgroup) {
07086          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07087          return -1;
07088       }
07089    }
07090    for (y = 0; y < NUM_DCHANS; y++) {
07091       if (!channels[y]) 
07092          break;
07093       memset(&si, 0, sizeof(si));
07094       memset(&p, 0, sizeof(p));
07095       fd = open("/dev/zap/channel", O_RDWR);
07096       if (fd < 0) {
07097          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07098          return -1;
07099       }
07100       x = channels[y];
07101       if (ioctl(fd, ZT_SPECIFY, &x)) {
07102          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07103          zt_close(fd);
07104          return -1;
07105       }
07106       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07107          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07108          return -1;
07109       }
07110       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07111          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07112          zt_close(fd);
07113          return -1;
07114       }
07115       span = p.spanno - 1;
07116       if (pris[span].trunkgroup) {
07117          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07118          zt_close(fd);
07119          return -1;
07120       }
07121       if (pris[span].pvts[0]) {
07122          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07123          zt_close(fd);
07124          return -1;
07125       }
07126       if (!y) {
07127          pris[span].trunkgroup = trunkgroup;
07128          pris[span].offset = channels[y] - p.chanpos;
07129          ospan = span;
07130       }
07131       pris[ospan].dchannels[y] = channels[y];
07132       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07133       pris[span].span = span + 1;
07134       zt_close(fd);
07135    }
07136    return 0;   
07137 }
07138 
07139 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07140 {
07141    if (pris[span].mastertrunkgroup) {
07142       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);
07143       return -1;
07144    }
07145    pris[span].mastertrunkgroup = trunkgroup;
07146    pris[span].prilogicalspan = logicalspan;
07147    return 0;
07148 }
07149 
07150 #endif
07151 
07152 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
07153 {
07154    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07155    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07156    char fn[80];
07157 #if 1
07158    struct zt_bufferinfo bi;
07159 #endif
07160    struct zt_spaninfo si;
07161    int res;
07162    int span=0;
07163    int here = 0;
07164    int x;
07165    struct zt_pvt **wlist;
07166    struct zt_pvt **wend;
07167    ZT_PARAMS p;
07168 
07169    wlist = &iflist;
07170    wend = &ifend;
07171 
07172 #ifdef HAVE_PRI
07173    if (pri) {
07174       wlist = &pri->crvs;
07175       wend = &pri->crvend;
07176    }
07177 #endif
07178 
07179    tmp2 = *wlist;
07180    prev = NULL;
07181 
07182    while (tmp2) {
07183       if (!tmp2->destroy) {
07184          if (tmp2->channel == channel) {
07185             tmp = tmp2;
07186             here = 1;
07187             break;
07188          }
07189          if (tmp2->channel > channel) {
07190             break;
07191          }
07192       }
07193       prev = tmp2;
07194       tmp2 = tmp2->next;
07195    }
07196 
07197    if (!here && !reloading) {
07198       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07199          destroy_zt_pvt(&tmp);
07200          return NULL;
07201       }
07202       ast_mutex_init(&tmp->lock);
07203       ifcount++;
07204       for (x = 0; x < 3; x++)
07205          tmp->subs[x].zfd = -1;
07206       tmp->channel = channel;
07207    }
07208 
07209    if (tmp) {
07210       if (!here) {
07211          if ((channel != CHAN_PSEUDO) && !pri) {
07212             snprintf(fn, sizeof(fn), "%d", channel);
07213             /* Open non-blocking */
07214             if (!here)
07215                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07216             /* Allocate a zapata structure */
07217             if (tmp->subs[SUB_REAL].zfd < 0) {
07218                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);
07219                destroy_zt_pvt(&tmp);
07220                return NULL;
07221             }
07222             memset(&p, 0, sizeof(p));
07223             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07224             if (res < 0) {
07225                ast_log(LOG_ERROR, "Unable to get parameters\n");
07226                destroy_zt_pvt(&tmp);
07227                return NULL;
07228             }
07229             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07230                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));
07231                destroy_zt_pvt(&tmp);
07232                return NULL;
07233             }
07234             tmp->law = p.curlaw;
07235             tmp->span = p.spanno;
07236             span = p.spanno - 1;
07237          } else {
07238             if (channel == CHAN_PSEUDO)
07239                conf.chan.sig = 0;
07240             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07241                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07242                return NULL;
07243             }
07244          }
07245 #ifdef HAVE_PRI
07246          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07247             int offset;
07248             int myswitchtype;
07249             int matchesdchan;
07250             int x,y;
07251             offset = 0;
07252             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07253                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07254                destroy_zt_pvt(&tmp);
07255                return NULL;
07256             }
07257             if (span >= NUM_SPANS) {
07258                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07259                destroy_zt_pvt(&tmp);
07260                return NULL;
07261             } else {
07262                si.spanno = 0;
07263                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07264                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07265                   destroy_zt_pvt(&tmp);
07266                   return NULL;
07267                }
07268                /* Store the logical span first based upon the real span */
07269                tmp->logicalspan = pris[span].prilogicalspan;
07270                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07271                if (span < 0) {
07272                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07273                   destroy_zt_pvt(&tmp);
07274                   return NULL;
07275                }
07276                if (conf.chan.sig == SIG_PRI)
07277                   myswitchtype = conf.pri.switchtype;
07278                else
07279                   myswitchtype = PRI_SWITCH_GR303_TMC;
07280                /* Make sure this isn't a d-channel */
07281                matchesdchan=0;
07282                for (x = 0; x < NUM_SPANS; x++) {
07283                   for (y = 0; y < NUM_DCHANS; y++) {
07284                      if (pris[x].dchannels[y] == tmp->channel) {
07285                         matchesdchan = 1;
07286                         break;
07287                      }
07288                   }
07289                }
07290                offset = p.chanpos;
07291                if (!matchesdchan) {
07292                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07293                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07294                      destroy_zt_pvt(&tmp);
07295                      return NULL;
07296                   }
07297                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07298                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07299                      destroy_zt_pvt(&tmp);
07300                      return NULL;
07301                   }
07302                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07303                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07304                      destroy_zt_pvt(&tmp);
07305                      return NULL;
07306                   }
07307                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07308                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07309                      destroy_zt_pvt(&tmp);
07310                      return NULL;
07311                   }
07312                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07313                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07314                      destroy_zt_pvt(&tmp);
07315                      return NULL;
07316                   }
07317                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07318                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07319                      destroy_zt_pvt(&tmp);
07320                      return NULL;
07321                   }
07322                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07323                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07324                      destroy_zt_pvt(&tmp);
07325                      return NULL;
07326                   }
07327                   if (pris[span].numchans >= MAX_CHANNELS) {
07328                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07329                         pris[span].trunkgroup);
07330                      destroy_zt_pvt(&tmp);
07331                      return NULL;
07332                   }
07333                   pris[span].nodetype = conf.pri.nodetype;
07334                   pris[span].switchtype = myswitchtype;
07335                   pris[span].nsf = conf.pri.nsf;
07336                   pris[span].dialplan = conf.pri.dialplan;
07337                   pris[span].localdialplan = conf.pri.localdialplan;
07338                   pris[span].pvts[pris[span].numchans++] = tmp;
07339                   pris[span].minunused = conf.pri.minunused;
07340                   pris[span].minidle = conf.pri.minidle;
07341                   pris[span].overlapdial = conf.pri.overlapdial;
07342                   pris[span].facilityenable = conf.pri.facilityenable;
07343                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07344                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07345                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07346                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07347                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07348                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07349                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07350                   pris[span].resetinterval = conf.pri.resetinterval;
07351                   
07352                   tmp->pri = &pris[span];
07353                   tmp->prioffset = offset;
07354                   tmp->call = NULL;
07355                } else {
07356                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07357                   destroy_zt_pvt(&tmp);
07358                   return NULL;
07359                }
07360             }
07361          } else {
07362             tmp->prioffset = 0;
07363          }
07364 #endif
07365       } else {
07366          conf.chan.sig = tmp->sig;
07367          conf.chan.radio = tmp->radio;
07368          memset(&p, 0, sizeof(p));
07369          if (tmp->subs[SUB_REAL].zfd > -1)
07370             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07371       }
07372       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07373       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07374           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07375          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07376            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07377           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07378          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07379            (conf.chan.sig == SIG_SF_FEATB)) {
07380          p.starttime = 250;
07381       }
07382       if (conf.chan.radio) {
07383          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07384          p.channo = channel;
07385          p.rxwinktime = 1;
07386          p.rxflashtime = 1;
07387          p.starttime = 1;
07388          p.debouncetime = 5;
07389       }
07390       if (!conf.chan.radio) {
07391          p.channo = channel;
07392          /* Override timing settings based on config file */
07393          if (conf.timing.prewinktime >= 0)
07394             p.prewinktime = conf.timing.prewinktime;
07395          if (conf.timing.preflashtime >= 0)
07396             p.preflashtime = conf.timing.preflashtime;
07397          if (conf.timing.winktime >= 0)
07398             p.winktime = conf.timing.winktime;
07399          if (conf.timing.flashtime >= 0)
07400             p.flashtime = conf.timing.flashtime;
07401          if (conf.timing.starttime >= 0)
07402             p.starttime = conf.timing.starttime;
07403          if (conf.timing.rxwinktime >= 0)
07404             p.rxwinktime = conf.timing.rxwinktime;
07405          if (conf.timing.rxflashtime >= 0)
07406             p.rxflashtime = conf.timing.rxflashtime;
07407          if (conf.timing.debouncetime >= 0)
07408             p.debouncetime = conf.timing.debouncetime;
07409       }
07410       
07411       /* dont set parms on a pseudo-channel (or CRV) */
07412       if (tmp->subs[SUB_REAL].zfd >= 0)
07413       {
07414          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07415          if (res < 0) {
07416             ast_log(LOG_ERROR, "Unable to set parameters\n");
07417             destroy_zt_pvt(&tmp);
07418             return NULL;
07419          }
07420       }
07421 #if 1
07422       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07423          memset(&bi, 0, sizeof(bi));
07424          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07425          if (!res) {
07426             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07427             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07428             bi.numbufs = numbufs;
07429             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07430             if (res < 0) {
07431                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07432             }
07433          } else
07434             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07435       }
07436 #endif
07437       tmp->immediate = conf.chan.immediate;
07438       tmp->transfertobusy = conf.chan.transfertobusy;
07439       tmp->sig = conf.chan.sig;
07440       tmp->outsigmod = conf.chan.outsigmod;
07441       tmp->radio = conf.chan.radio;
07442       tmp->ringt_base = ringt_base;
07443       tmp->firstradio = 0;
07444       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07445          tmp->permcallwaiting = conf.chan.callwaiting;
07446       else
07447          tmp->permcallwaiting = 0;
07448       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07449       tmp->destroy = 0;
07450       tmp->drings = drings;
07451       tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection;
07452       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07453       tmp->threewaycalling = conf.chan.threewaycalling;
07454       tmp->adsi = conf.chan.adsi;
07455       tmp->use_smdi = conf.chan.use_smdi;
07456       tmp->permhidecallerid = conf.chan.hidecallerid;
07457       tmp->callreturn = conf.chan.callreturn;
07458       tmp->echocancel = conf.chan.echocancel;
07459       tmp->echotraining = conf.chan.echotraining;
07460       tmp->pulse = conf.chan.pulse;
07461       if (tmp->echocancel)
07462          tmp->echocanbridged = conf.chan.echocanbridged;
07463       else {
07464          if (conf.chan.echocanbridged)
07465             ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
07466          tmp->echocanbridged = 0;
07467       }
07468       tmp->busydetect = conf.chan.busydetect;
07469       tmp->busycount = conf.chan.busycount;
07470       tmp->busy_tonelength = conf.chan.busy_tonelength;
07471       tmp->busy_quietlength = conf.chan.busy_quietlength;
07472       tmp->callprogress = conf.chan.callprogress;
07473       tmp->cancallforward = conf.chan.cancallforward;
07474       tmp->dtmfrelax = conf.chan.dtmfrelax;
07475       tmp->callwaiting = tmp->permcallwaiting;
07476       tmp->hidecallerid = tmp->permhidecallerid;
07477       tmp->channel = channel;
07478       tmp->stripmsd = conf.chan.stripmsd;
07479       tmp->use_callerid = conf.chan.use_callerid;
07480       tmp->cid_signalling = conf.chan.cid_signalling;
07481       tmp->cid_start = conf.chan.cid_start;
07482       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07483       tmp->restrictcid = conf.chan.restrictcid;
07484       tmp->use_callingpres = conf.chan.use_callingpres;
07485       tmp->priindication_oob = conf.chan.priindication_oob;
07486       tmp->priexclusive = conf.chan.priexclusive;
07487       if (tmp->usedistinctiveringdetection) {
07488          if (!tmp->use_callerid) {
07489             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07490             tmp->use_callerid = 1;
07491          }
07492       }
07493 
07494       if (tmp->cid_signalling == CID_SIG_SMDI) {
07495          if (!tmp->use_smdi) {
07496             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07497             tmp->use_smdi = 1;
07498          }
07499       }
07500       if (tmp->use_smdi) {
07501          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07502          if (!(tmp->smdi_iface)) {
07503             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07504             tmp->use_smdi = 0;
07505          }
07506       }
07507 
07508       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07509       tmp->amaflags = conf.chan.amaflags;
07510       if (!here) {
07511          tmp->confno = -1;
07512          tmp->propconfno = -1;
07513       }
07514       tmp->canpark = conf.chan.canpark;
07515       tmp->transfer = conf.chan.transfer;
07516       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07517       ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
07518       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07519       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07520       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07521       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07522       tmp->cid_ton = 0;
07523       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07524       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07525       tmp->msgstate = -1;
07526       tmp->group = conf.chan.group;
07527       tmp->callgroup = conf.chan.callgroup;
07528       tmp->pickupgroup= conf.chan.pickupgroup;
07529       tmp->rxgain = conf.chan.rxgain;
07530       tmp->txgain = conf.chan.txgain;
07531       tmp->tonezone = conf.chan.tonezone;
07532       tmp->onhooktime = time(NULL);
07533       if (tmp->subs[SUB_REAL].zfd > -1) {
07534          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07535          if (tmp->dsp)
07536             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07537          update_conf(tmp);
07538          if (!here) {
07539             if (conf.chan.sig != SIG_PRI)
07540                /* Hang it up to be sure it's good */
07541                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07542          }
07543          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07544 #ifdef HAVE_PRI
07545          /* the dchannel is down so put the channel in alarm */
07546          if (tmp->pri && !pri_is_up(tmp->pri))
07547             tmp->inalarm = 1;
07548          else
07549             tmp->inalarm = 0;
07550 #endif            
07551          memset(&si, 0, sizeof(si));
07552          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07553             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07554             destroy_zt_pvt(&tmp);
07555             return NULL;
07556          }
07557          if (si.alarms) tmp->inalarm = 1;
07558       }
07559 
07560       tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
07561       tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
07562       tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
07563       tmp->sendcalleridafter = conf.chan.sendcalleridafter;
07564 
07565    }
07566    if (tmp && !here) {
07567       /* nothing on the iflist */
07568       if (!*wlist) {
07569          *wlist = tmp;
07570          tmp->prev = NULL;
07571          tmp->next = NULL;
07572          *wend = tmp;
07573       } else {
07574          /* at least one member on the iflist */
07575          struct zt_pvt *working = *wlist;
07576 
07577          /* check if we maybe have to put it on the begining */
07578          if (working->channel > tmp->channel) {
07579             tmp->next = *wlist;
07580             tmp->prev = NULL;
07581             (*wlist)->prev = tmp;
07582             *wlist = tmp;
07583          } else {
07584          /* go through all the members and put the member in the right place */
07585             while (working) {
07586                /* in the middle */
07587                if (working->next) {
07588                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07589                      tmp->next = working->next;
07590                      tmp->prev = working;
07591                      working->next->prev = tmp;
07592                      working->next = tmp;
07593                      break;
07594                   }
07595                } else {
07596                /* the last */
07597                   if (working->channel < tmp->channel) {
07598                      working->next = tmp;
07599                      tmp->next = NULL;
07600                      tmp->prev = working;
07601                      *wend = tmp;
07602                      break;
07603                   }
07604                }
07605                working = working->next;
07606             }
07607          }
07608       }
07609    }
07610    return tmp;
07611 }
07612 
07613 static inline int available(struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
07614 {
07615    int res;
07616    ZT_PARAMS par;
07617 
07618    /* First, check group matching */
07619    if (groupmatch) {
07620       if ((p->group & groupmatch) != groupmatch)
07621          return 0;
07622       *groupmatched = 1;
07623    }
07624    /* Check to see if we have a channel match */
07625    if (channelmatch != -1) {
07626       if (p->channel != channelmatch)
07627          return 0;
07628       *channelmatched = 1;
07629    }
07630    /* We're at least busy at this point */
07631    if (busy) {
07632       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07633          *busy = 1;
07634    }
07635    /* If do not disturb, definitely not */
07636    if (p->dnd)
07637       return 0;
07638    /* If guard time, definitely not */
07639    if (p->guardtime && (time(NULL) < p->guardtime)) 
07640       return 0;
07641       
07642    /* If no owner definitely available */
07643    if (!p->owner) {
07644 #ifdef HAVE_PRI
07645       /* Trust PRI */
07646       if (p->pri) {
07647          if (p->resetting || p->call)
07648             return 0;
07649          else
07650             return 1;
07651       }
07652 #endif
07653       if (!(p->radio || (p->oprmode < 0)))
07654       {
07655          if (!p->sig || (p->sig == SIG_FXSLS))
07656             return 1;
07657          /* Check hook state */
07658          if (p->subs[SUB_REAL].zfd > -1)
07659             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07660          else {
07661             /* Assume not off hook on CVRS */
07662             res = 0;
07663             par.rxisoffhook = 0;
07664          }
07665          if (res) {
07666             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07667          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07668             /* When "onhook" that means no battery on the line, and thus
07669               it is out of service..., if it's on a TDM card... If it's a channel
07670               bank, there is no telling... */
07671             if (par.rxbits > -1)
07672                return 1;
07673             if (par.rxisoffhook)
07674                return 1;
07675             else
07676 #ifdef ZAP_CHECK_HOOKSTATE
07677                return 0;
07678 #else
07679                return 1;
07680 #endif
07681          } else if (par.rxisoffhook) {
07682             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07683             /* Not available when the other end is off hook */
07684             return 0;
07685          }
07686       }
07687       return 1;
07688    }
07689 
07690    /* If it's not an FXO, forget about call wait */
07691    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07692       return 0;
07693 
07694    if (!p->callwaiting) {
07695       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07696       return 0;
07697    }
07698 
07699    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07700       /* If there is already a call waiting call, then we can't take a second one */
07701       return 0;
07702    }
07703    
07704    if ((p->owner->_state != AST_STATE_UP) &&
07705        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07706       /* If the current call is not up, then don't allow the call */
07707       return 0;
07708    }
07709    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07710       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07711       return 0;
07712    }
07713    /* We're cool */
07714    return 1;
07715 }
07716 
07717 static struct zt_pvt *chandup(struct zt_pvt *src)
07718 {
07719    struct zt_pvt *p;
07720    ZT_BUFFERINFO bi;
07721    int res;
07722    
07723    if ((p = ast_malloc(sizeof(*p)))) {
07724       memcpy(p, src, sizeof(struct zt_pvt));
07725       ast_mutex_init(&p->lock);
07726       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07727       /* Allocate a zapata structure */
07728       if (p->subs[SUB_REAL].zfd < 0) {
07729          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07730          destroy_zt_pvt(&p);
07731          return NULL;
07732       }
07733       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07734       if (!res) {
07735          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07736          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07737          bi.numbufs = numbufs;
07738          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07739          if (res < 0) {
07740             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
07741          }
07742       } else
07743          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
07744    }
07745    p->destroy = 1;
07746    p->next = iflist;
07747    p->prev = NULL;
07748    iflist = p;
07749    if (iflist->next)
07750       iflist->next->prev = p;
07751    return p;
07752 }
07753    
07754 
07755 #ifdef HAVE_PRI
07756 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
07757 {
07758    int x;
07759    if (backwards)
07760       x = pri->numchans;
07761    else
07762       x = 0;
07763    for (;;) {
07764       if (backwards && (x < 0))
07765          break;
07766       if (!backwards && (x >= pri->numchans))
07767          break;
07768       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
07769          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
07770             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
07771          return x;
07772       }
07773       if (backwards)
07774          x--;
07775       else
07776          x++;
07777    }
07778    return -1;
07779 }
07780 #endif
07781 
07782 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
07783 {
07784    ast_group_t groupmatch = 0;
07785    int channelmatch = -1;
07786    int roundrobin = 0;
07787    int callwait = 0;
07788    int busy = 0;
07789    struct zt_pvt *p;
07790    struct ast_channel *tmp = NULL;
07791    char *dest=NULL;
07792    int x;
07793    char *s;
07794    char opt=0;
07795    int res=0, y=0;
07796    int backwards = 0;
07797 #ifdef HAVE_PRI
07798    int crv;
07799    int bearer = -1;
07800    int trunkgroup;
07801    struct zt_pri *pri=NULL;
07802 #endif   
07803    struct zt_pvt *exit, *start, *end;
07804    ast_mutex_t *lock;
07805    int channelmatched = 0;
07806    int groupmatched = 0;
07807    
07808    /* Assume we're locking the iflock */
07809    lock = &iflock;
07810    start = iflist;
07811    end = ifend;
07812    if (data) {
07813       dest = ast_strdupa((char *)data);
07814    } else {
07815       ast_log(LOG_WARNING, "Channel requested with no data\n");
07816       return NULL;
07817    }
07818    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
07819       /* Retrieve the group number */
07820       char *stringp=NULL;
07821       stringp=dest + 1;
07822       s = strsep(&stringp, "/");
07823       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07824          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
07825          return NULL;
07826       }
07827       groupmatch = ((ast_group_t) 1 << x);
07828       if (toupper(dest[0]) == 'G') {
07829          if (dest[0] == 'G') {
07830             backwards = 1;
07831             p = ifend;
07832          } else
07833             p = iflist;
07834       } else {
07835          if (dest[0] == 'R') {
07836             backwards = 1;
07837             p = round_robin[x]?round_robin[x]->prev:ifend;
07838             if (!p)
07839                p = ifend;
07840          } else {
07841             p = round_robin[x]?round_robin[x]->next:iflist;
07842             if (!p)
07843                p = iflist;
07844          }
07845          roundrobin = 1;
07846       }
07847    } else {
07848       char *stringp=NULL;
07849       stringp=dest;
07850       s = strsep(&stringp, "/");
07851       p = iflist;
07852       if (!strcasecmp(s, "pseudo")) {
07853          /* Special case for pseudo */
07854          x = CHAN_PSEUDO;
07855          channelmatch = x;
07856       } 
07857 #ifdef HAVE_PRI
07858       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
07859          if ((trunkgroup < 1) || (crv < 1)) {
07860             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
07861             return NULL;
07862          }
07863          res--;
07864          for (x = 0; x < NUM_SPANS; x++) {
07865             if (pris[x].trunkgroup == trunkgroup) {
07866                pri = pris + x;
07867                lock = &pri->lock;
07868                start = pri->crvs;
07869                end = pri->crvend;
07870                break;
07871             }
07872          }
07873          if (!pri) {
07874             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
07875             return NULL;
07876          }
07877          channelmatch = crv;
07878          p = pris[x].crvs;
07879       }
07880 #endif   
07881       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
07882          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
07883          return NULL;
07884       } else {
07885          channelmatch = x;
07886       }
07887    }
07888    /* Search for an unowned channel */
07889    ast_mutex_lock(lock);
07890    exit = p;
07891    while (p && !tmp) {
07892       if (roundrobin)
07893          round_robin[x] = p;
07894 #if 0
07895       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
07896 #endif
07897 
07898       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
07899          if (option_debug)
07900             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
07901             if (p->inalarm) 
07902                goto next;
07903 
07904          callwait = (p->owner != NULL);
07905 #ifdef HAVE_PRI
07906          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
07907             if (p->sig != SIG_FXSKS) {
07908                /* Gotta find an actual channel to use for this
07909                   CRV if this isn't a callwait */
07910                bearer = pri_find_empty_chan(pri, 0);
07911                if (bearer < 0) {
07912                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
07913                   p = NULL;
07914                   break;
07915                }
07916                pri_assign_bearer(p, pri, pri->pvts[bearer]);
07917             } else {
07918                if (alloc_sub(p, 0)) {
07919                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
07920                   p = NULL;
07921                   break;
07922                } else
07923                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
07924                p->pri = pri;
07925             }
07926          }
07927 #endif         
07928          if (p->channel == CHAN_PSEUDO) {
07929             p = chandup(p);
07930             if (!p) {
07931                break;
07932             }
07933          }
07934          if (p->owner) {
07935             if (alloc_sub(p, SUB_CALLWAIT)) {
07936                p = NULL;
07937                break;
07938             }
07939          }
07940          p->outgoing = 1;
07941          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
07942 #ifdef HAVE_PRI
07943          if (p->bearer) {
07944             /* Log owner to bearer channel, too */
07945             p->bearer->owner = tmp;
07946          }
07947 #endif         
07948          /* Make special notes */
07949          if (res > 1) {
07950             if (opt == 'c') {
07951                /* Confirm answer */
07952                p->confirmanswer = 1;
07953             } else if (opt == 'r') {
07954                /* Distinctive ring */
07955                if (res < 3)
07956                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
07957                else
07958                   p->distinctivering = y;
07959             } else if (opt == 'd') {
07960                /* If this is an ISDN call, make it digital */
07961                p->digital = 1;
07962                if (tmp)
07963                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
07964             } else {
07965                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
07966             }
07967          }
07968          /* Note if the call is a call waiting call */
07969          if (tmp && callwait)
07970             tmp->cdrflags |= AST_CDR_CALLWAIT;
07971          break;
07972       }
07973 next:
07974       if (backwards) {
07975          p = p->prev;
07976          if (!p)
07977             p = end;
07978       } else {
07979          p = p->next;
07980          if (!p)
07981             p = start;
07982       }
07983       /* stop when you roll to the one that we started from */
07984       if (p == exit)
07985          break;
07986    }
07987    ast_mutex_unlock(lock);
07988    restart_monitor();
07989    if (callwait)
07990       *cause = AST_CAUSE_BUSY;
07991    else if (!tmp) {
07992       if (channelmatched) {
07993          if (busy)
07994             *cause = AST_CAUSE_BUSY;
07995       } else if (groupmatched) {
07996          *cause = AST_CAUSE_CONGESTION;
07997       }
07998    }
07999       
08000    return tmp;
08001 }
08002 
08003 
08004 #ifdef HAVE_PRI
08005 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
08006 {
08007    struct zt_pvt *p;
08008    p = pri->crvs;
08009    while (p) {
08010       if (p->channel == crv)
08011          return p;
08012       p = p->next;
08013    }
08014    return NULL;
08015 }
08016 
08017 
08018 static int pri_find_principle(struct zt_pri *pri, int channel)
08019 {
08020    int x;
08021    int span = PRI_SPAN(channel);
08022    int spanfd;
08023    ZT_PARAMS param;
08024    int principle = -1;
08025    int explicit = PRI_EXPLICIT(channel);
08026    channel = PRI_CHANNEL(channel);
08027 
08028    if (!explicit) {
08029       spanfd = pri_active_dchan_fd(pri);
08030       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
08031          return -1;
08032       span = pris[param.spanno - 1].prilogicalspan;
08033    }
08034 
08035    for (x = 0; x < pri->numchans; x++) {
08036       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
08037          principle = x;
08038          break;
08039       }
08040    }
08041    
08042    return principle;
08043 }
08044 
08045 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
08046 {
08047    int x;
08048    struct zt_pvt *crv;
08049    if (!c) {
08050       if (principle < 0)
08051          return -1;
08052       return principle;
08053    }
08054    if ((principle > -1) && 
08055       (principle < pri->numchans) && 
08056       (pri->pvts[principle]) && 
08057       (pri->pvts[principle]->call == c))
08058       return principle;
08059    /* First, check for other bearers */
08060    for (x = 0; x < pri->numchans; x++) {
08061       if (!pri->pvts[x])
08062          continue;
08063       if (pri->pvts[x]->call == c) {
08064          /* Found our call */
08065          if (principle != x) {
08066             struct zt_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
08067 
08068             if (option_verbose > 2)
08069                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08070                   old->channel, new->channel);
08071             if (new->owner) {
08072                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08073                   old->channel, new->channel, new->channel);
08074                return -1;
08075             }
08076             /* Fix it all up now */
08077             new->owner = old->owner;
08078             old->owner = NULL;
08079             if (new->owner) {
08080                ast_string_field_build(new->owner, name, 
08081                             "Zap/%d:%d-%d", pri->trunkgroup,
08082                             new->channel, 1);
08083                new->owner->tech_pvt = new;
08084                new->owner->fds[0] = new->subs[SUB_REAL].zfd;
08085                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
08086                old->subs[SUB_REAL].owner = NULL;
08087             } else
08088                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);
08089             new->call = old->call;
08090             old->call = NULL;
08091 
08092             /* Copy any DSP that may be present */
08093             new->dsp = old->dsp;
08094             new->dsp_features = old->dsp_features;
08095             old->dsp = NULL;
08096             old->dsp_features = 0;
08097          }
08098          return principle;
08099       }
08100    }
08101    /* Now check for a CRV with no bearer */
08102    crv = pri->crvs;
08103    while (crv) {
08104       if (crv->call == c) {
08105          /* This is our match...  Perform some basic checks */
08106          if (crv->bearer)
08107             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08108          else if (pri->pvts[principle]->owner) 
08109             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08110          else {
08111             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08112                wakeup the potential sleeper */
08113             zt_close(crv->subs[SUB_REAL].zfd);
08114             pri->pvts[principle]->call = crv->call;
08115             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08116             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08117                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08118                            pri->trunkgroup, crv->channel);
08119             wakeup_sub(crv, SUB_REAL, pri);
08120          }
08121          return principle;
08122       }
08123       crv = crv->next;
08124    }
08125    ast_log(LOG_WARNING, "Call specified, but not found?\n");
08126    return -1;
08127 }
08128 
08129 static void *do_idle_thread(void *vchan)
08130 {
08131    struct ast_channel *chan = vchan;
08132    struct zt_pvt *pvt = chan->tech_pvt;
08133    struct ast_frame *f;
08134    char ex[80];
08135    /* Wait up to 30 seconds for an answer */
08136    int newms, ms = 30000;
08137    if (option_verbose > 2) 
08138       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08139    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08140    if (ast_call(chan, ex, 0)) {
08141       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08142       ast_hangup(chan);
08143       return NULL;
08144    }
08145    while ((newms = ast_waitfor(chan, ms)) > 0) {
08146       f = ast_read(chan);
08147       if (!f) {
08148          /* Got hangup */
08149          break;
08150       }
08151       if (f->frametype == AST_FRAME_CONTROL) {
08152          switch (f->subclass) {
08153          case AST_CONTROL_ANSWER:
08154             /* Launch the PBX */
08155             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08156             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08157             chan->priority = 1;
08158             if (option_verbose > 3) 
08159                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08160             ast_pbx_run(chan);
08161             /* It's already hungup, return immediately */
08162             return NULL;
08163          case AST_CONTROL_BUSY:
08164             if (option_verbose > 3) 
08165                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08166             break;
08167          case AST_CONTROL_CONGESTION:
08168             if (option_verbose > 3) 
08169                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08170             break;
08171          };
08172       }
08173       ast_frfree(f);
08174       ms = newms;
08175    }
08176    /* Hangup the channel since nothing happend */
08177    ast_hangup(chan);
08178    return NULL;
08179 }
08180 
08181 #ifndef PRI_RESTART
08182 #error "Upgrade your libpri"
08183 #endif
08184 static void zt_pri_message(struct pri *pri, char *s)
08185 {
08186    int x, y;
08187    int dchan = -1, span = -1;
08188    int dchancount = 0;
08189 
08190    if (pri) {
08191       for (x = 0; x < NUM_SPANS; x++) {
08192          for (y = 0; y < NUM_DCHANS; y++) {
08193             if (pris[x].dchans[y])
08194                dchancount++;
08195 
08196             if (pris[x].dchans[y] == pri)
08197                dchan = y;
08198          }
08199          if (dchan >= 0) {
08200             span = x;
08201             break;
08202          }
08203          dchancount = 0;
08204       }
08205       if ((dchan >= 0) && (span >= 0)) {
08206          if (dchancount > 1)
08207             ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
08208          else
08209             ast_verbose("%s", s);
08210       } else
08211          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08212    } else
08213       ast_verbose("%s", s);
08214 
08215    ast_mutex_lock(&pridebugfdlock);
08216 
08217    if (pridebugfd >= 0)
08218       write(pridebugfd, s, strlen(s));
08219 
08220    ast_mutex_unlock(&pridebugfdlock);
08221 }
08222 
08223 static void zt_pri_error(struct pri *pri, char *s)
08224 {
08225    int x, y;
08226    int dchan = -1, span = -1;
08227    int dchancount = 0;
08228 
08229    if (pri) {
08230       for (x = 0; x < NUM_SPANS; x++) {
08231          for (y = 0; y < NUM_DCHANS; y++) {
08232             if (pris[x].dchans[y])
08233                dchancount++;
08234 
08235             if (pris[x].dchans[y] == pri)
08236                dchan = y;
08237          }
08238          if (dchan >= 0) {
08239             span = x;
08240             break;
08241          }
08242          dchancount = 0;
08243       }
08244       if ((dchan >= 0) && (span >= 0)) {
08245          if (dchancount > 1)
08246             ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
08247          else
08248             ast_log(LOG_ERROR, "%s", s);
08249       } else
08250          ast_log(LOG_ERROR, "PRI debug error: could not find pri associated it with debug message output\n");
08251    } else
08252       ast_log(LOG_ERROR, "%s", s);
08253 
08254    ast_mutex_lock(&pridebugfdlock);
08255 
08256    if (pridebugfd >= 0)
08257       write(pridebugfd, s, strlen(s));
08258 
08259    ast_mutex_unlock(&pridebugfdlock);
08260 }
08261 
08262 static int pri_check_restart(struct zt_pri *pri)
08263 {
08264    do {
08265       pri->resetpos++;
08266    } while ((pri->resetpos < pri->numchans) &&
08267        (!pri->pvts[pri->resetpos] ||
08268         pri->pvts[pri->resetpos]->call ||
08269         pri->pvts[pri->resetpos]->resetting));
08270    if (pri->resetpos < pri->numchans) {
08271       /* Mark the channel as resetting and restart it */
08272       pri->pvts[pri->resetpos]->resetting = 1;
08273       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08274    } else {
08275       pri->resetting = 0;
08276       time(&pri->lastreset);
08277    }
08278    return 0;
08279 }
08280 
08281 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08282 {
08283    int x;
08284    int redo;
08285    ast_mutex_unlock(&pri->lock);
08286    ast_mutex_lock(&p->lock);
08287    do {
08288       redo = 0;
08289       for (x = 0; x < 3; x++) {
08290          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08291             redo++;
08292             ast_mutex_unlock(&p->lock);
08293             usleep(1);
08294             ast_mutex_lock(&p->lock);
08295          }
08296          if (p->subs[x].owner) {
08297             ast_queue_hangup(p->subs[x].owner);
08298             ast_mutex_unlock(&p->subs[x].owner->lock);
08299          }
08300       }
08301    } while (redo);
08302    ast_mutex_unlock(&p->lock);
08303    ast_mutex_lock(&pri->lock);
08304    return 0;
08305 }
08306 
08307 static char * redirectingreason2str(int redirectingreason)
08308 {
08309    switch (redirectingreason) {
08310    case 0:
08311       return "UNKNOWN";
08312    case 1:
08313       return "BUSY";
08314    case 2:
08315       return "NO_REPLY";
08316    case 0xF:
08317       return "UNCONDITIONAL";
08318    default:
08319       return "NOREDIRECT";
08320    }
08321 }
08322 
08323 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08324 {
08325    switch (plan) {
08326    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08327       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08328       break;
08329    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08330       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08331       break;
08332    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08333       snprintf(buf, size, "%s%s", pri->localprefix, number);
08334       break;
08335    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08336       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08337       break;
08338    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08339       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08340       break;
08341    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08342       snprintf(buf, size, "%s", number);
08343       break;
08344    }
08345 }
08346 
08347 static int zt_setlaw(int zfd, int law)
08348 {
08349    int res;
08350    res = ioctl(zfd, ZT_SETLAW, &law);
08351    if (res)
08352       return res;
08353    return 0;
08354 }
08355 
08356 static void *pri_dchannel(void *vpri)
08357 {
08358    struct zt_pri *pri = vpri;
08359    pri_event *e;
08360    struct pollfd fds[NUM_DCHANS];
08361    int res;
08362    int chanpos = 0;
08363    int x;
08364    int haveidles;
08365    int activeidles;
08366    int nextidle = -1;
08367    struct ast_channel *c;
08368    struct timeval tv, lowest, *next;
08369    struct timeval lastidle = { 0, 0 };
08370    int doidling=0;
08371    char *cc;
08372    char idlen[80];
08373    struct ast_channel *idle;
08374    pthread_t p;
08375    time_t t;
08376    int i, which=-1;
08377    int numdchans;
08378    int cause=0;
08379    struct zt_pvt *crv;
08380    pthread_t threadid;
08381    pthread_attr_t attr;
08382    char ani2str[6];
08383    char plancallingnum[256];
08384    char plancallingani[256];
08385    char calledtonstr[10];
08386    
08387    gettimeofday(&lastidle, NULL);
08388    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08389       /* Need to do idle dialing, check to be sure though */
08390       cc = strchr(pri->idleext, '@');
08391       if (cc) {
08392          *cc = '\0';
08393          cc++;
08394          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08395 #if 0
08396          /* Extensions may not be loaded yet */
08397          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08398             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08399          else
08400 #endif
08401             doidling = 1;
08402       } else
08403          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08404    }
08405    for (;;) {
08406       for (i = 0; i < NUM_DCHANS; i++) {
08407          if (!pri->dchannels[i])
08408             break;
08409          fds[i].fd = pri->fds[i];
08410          fds[i].events = POLLIN | POLLPRI;
08411          fds[i].revents = 0;
08412       }
08413       numdchans = i;
08414       time(&t);
08415       ast_mutex_lock(&pri->lock);
08416       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08417          if (pri->resetting && pri_is_up(pri)) {
08418             if (pri->resetpos < 0)
08419                pri_check_restart(pri);
08420          } else {
08421             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08422                pri->resetting = 1;
08423                pri->resetpos = -1;
08424             }
08425          }
08426       }
08427       /* Look for any idle channels if appropriate */
08428       if (doidling && pri_is_up(pri)) {
08429          nextidle = -1;
08430          haveidles = 0;
08431          activeidles = 0;
08432          for (x = pri->numchans; x >= 0; x--) {
08433             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08434                 !pri->pvts[x]->call) {
08435                if (haveidles < pri->minunused) {
08436                   haveidles++;
08437                } else if (!pri->pvts[x]->resetting) {
08438                   nextidle = x;
08439                   break;
08440                }
08441             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08442                activeidles++;
08443          }
08444          if (nextidle > -1) {
08445             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08446                /* Don't create a new idle call more than once per second */
08447                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08448                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08449                if (idle) {
08450                   pri->pvts[nextidle]->isidlecall = 1;
08451                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08452                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08453                      zt_hangup(idle);
08454                   }
08455                } else
08456                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08457                gettimeofday(&lastidle, NULL);
08458             }
08459          } else if ((haveidles < pri->minunused) &&
08460                (activeidles > pri->minidle)) {
08461             /* Mark something for hangup if there is something 
08462                that can be hungup */
08463             for (x = pri->numchans; x >= 0; x--) {
08464                /* find a candidate channel */
08465                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08466                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08467                   haveidles++;
08468                   /* Stop if we have enough idle channels or
08469                     can't spare any more active idle ones */
08470                   if ((haveidles >= pri->minunused) ||
08471                       (activeidles <= pri->minidle))
08472                      break;
08473                } 
08474             }
08475          }
08476       }
08477       /* Start with reasonable max */
08478       lowest = ast_tv(60, 0);
08479       for (i = 0; i < NUM_DCHANS; i++) {
08480          /* Find lowest available d-channel */
08481          if (!pri->dchannels[i])
08482             break;
08483          if ((next = pri_schedule_next(pri->dchans[i]))) {
08484             /* We need relative time here */
08485             tv = ast_tvsub(*next, ast_tvnow());
08486             if (tv.tv_sec < 0) {
08487                tv = ast_tv(0,0);
08488             }
08489             if (doidling || pri->resetting) {
08490                if (tv.tv_sec > 1) {
08491                   tv = ast_tv(1, 0);
08492                }
08493             } else {
08494                if (tv.tv_sec > 60) {
08495                   tv = ast_tv(60, 0);
08496                }
08497             }
08498          } else if (doidling || pri->resetting) {
08499             /* Make sure we stop at least once per second if we're
08500                monitoring idle channels */
08501             tv = ast_tv(1,0);
08502          } else {
08503             /* Don't poll for more than 60 seconds */
08504             tv = ast_tv(60, 0);
08505          }
08506          if (!i || ast_tvcmp(tv, lowest) < 0) {
08507             lowest = tv;
08508          }
08509       }
08510       ast_mutex_unlock(&pri->lock);
08511 
08512       e = NULL;
08513       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
08514 
08515       ast_mutex_lock(&pri->lock);
08516       if (!res) {
08517          for (which = 0; which < NUM_DCHANS; which++) {
08518             if (!pri->dchans[which])
08519                break;
08520             /* Just a timeout, run the scheduler */
08521             e = pri_schedule_run(pri->dchans[which]);
08522             if (e)
08523                break;
08524          }
08525       } else if (res > -1) {
08526          for (which = 0; which < NUM_DCHANS; which++) {
08527             if (!pri->dchans[which])
08528                break;
08529             if (fds[which].revents & POLLPRI) {
08530                /* Check for an event */
08531                x = 0;
08532                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
08533                if (x) 
08534                   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);
08535                /* Keep track of alarm state */  
08536                if (x == ZT_EVENT_ALARM) {
08537                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
08538                   pri_find_dchan(pri);
08539                } else if (x == ZT_EVENT_NOALARM) {
08540                   pri->dchanavail[which] |= DCHAN_NOTINALARM;
08541                   pri_restart(pri->dchans[which]);
08542                }
08543             
08544                if (option_debug)
08545                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
08546             } else if (fds[which].revents & POLLIN) {
08547                e = pri_check_event(pri->dchans[which]);
08548             }
08549             if (e)
08550                break;
08551          }
08552       } else if (errno != EINTR)
08553          ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
08554 
08555       if (e) {
08556          if (pri->debug)
08557             pri_dump_event(pri->dchans[which], e);
08558 
08559          if (e->e != PRI_EVENT_DCHAN_DOWN) {
08560             if (!(pri->dchanavail[which] & DCHAN_UP)) {
08561                if (option_verbose > 1) 
08562                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
08563             }
08564             pri->dchanavail[which] |= DCHAN_UP;
08565          } else {
08566             if (pri->dchanavail[which] & DCHAN_UP) {
08567                if (option_verbose > 1) 
08568                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
08569             }
08570             pri->dchanavail[which] &= ~DCHAN_UP;
08571          }
08572 
08573          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
08574             /* Must be an NFAS group that has the secondary dchan active */
08575             pri->pri = pri->dchans[which];
08576 
08577          switch (e->e) {
08578          case PRI_EVENT_DCHAN_UP:
08579             if (!pri->pri) pri_find_dchan(pri);
08580 
08581             /* Note presense of D-channel */
08582             time(&pri->lastreset);
08583 
08584             /* Restart in 5 seconds */
08585             if (pri->resetinterval > -1) {
08586                pri->lastreset -= pri->resetinterval;
08587                pri->lastreset += 5;
08588             }
08589             pri->resetting = 0;
08590             /* Take the channels from inalarm condition */
08591             for (i = 0; i < pri->numchans; i++)
08592                if (pri->pvts[i]) {
08593                   pri->pvts[i]->inalarm = 0;
08594                }
08595             break;
08596          case PRI_EVENT_DCHAN_DOWN:
08597             pri_find_dchan(pri);
08598             if (!pri_is_up(pri)) {
08599                pri->resetting = 0;
08600                /* Hangup active channels and put them in alarm mode */
08601                for (i = 0; i < pri->numchans; i++) {
08602                   struct zt_pvt *p = pri->pvts[i];
08603                   if (p) {
08604                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08605                         /* T309 is not enabled : hangup calls when alarm occurs */
08606                         if (p->call) {
08607                            if (p->pri && p->pri->pri) {
08608                               pri_hangup(p->pri->pri, p->call, -1);
08609                               pri_destroycall(p->pri->pri, p->call);
08610                               p->call = NULL;
08611                            } else
08612                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
08613                         }
08614                         if (p->realcall) {
08615                            pri_hangup_all(p->realcall, pri);
08616                         } else if (p->owner)
08617                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08618                      }
08619                      p->inalarm = 1;
08620                   }
08621                }
08622             }
08623             break;
08624          case PRI_EVENT_RESTART:
08625             if (e->restart.channel > -1) {
08626                chanpos = pri_find_principle(pri, e->restart.channel);
08627                if (chanpos < 0)
08628                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
08629                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08630                else {
08631                   if (option_verbose > 2)
08632                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
08633                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
08634                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08635                   if (pri->pvts[chanpos]->call) {
08636                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
08637                      pri->pvts[chanpos]->call = NULL;
08638                   }
08639                   /* Force soft hangup if appropriate */
08640                   if (pri->pvts[chanpos]->realcall) 
08641                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08642                   else if (pri->pvts[chanpos]->owner)
08643                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08644                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08645                }
08646             } else {
08647                if (option_verbose > 2)
08648                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
08649                for (x = 0; x < pri->numchans; x++)
08650                   if (pri->pvts[x]) {
08651                      ast_mutex_lock(&pri->pvts[x]->lock);
08652                      if (pri->pvts[x]->call) {
08653                         pri_destroycall(pri->pri, pri->pvts[x]->call);
08654                         pri->pvts[x]->call = NULL;
08655                      }
08656                      if (pri->pvts[chanpos]->realcall) 
08657                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
08658                      else if (pri->pvts[x]->owner)
08659                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08660                      ast_mutex_unlock(&pri->pvts[x]->lock);
08661                   }
08662             }
08663             break;
08664          case PRI_EVENT_KEYPAD_DIGIT:
08665             chanpos = pri_find_principle(pri, e->digit.channel);
08666             if (chanpos < 0) {
08667                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
08668                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
08669             } else {
08670                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
08671                if (chanpos > -1) {
08672                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08673                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
08674                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
08675                      /* how to do that */
08676                      int digitlen = strlen(e->digit.digits);
08677                      char digit;
08678                      int i;               
08679                      for (i = 0; i < digitlen; i++) { 
08680                         digit = e->digit.digits[i];
08681                         {
08682                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08683                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08684                         }
08685                      }
08686                   }
08687                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08688                }
08689             }
08690             break;
08691             
08692          case PRI_EVENT_INFO_RECEIVED:
08693             chanpos = pri_find_principle(pri, e->ring.channel);
08694             if (chanpos < 0) {
08695                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
08696                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08697             } else {
08698                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
08699                if (chanpos > -1) {
08700                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08701                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
08702                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
08703                      /* how to do that */
08704                      int digitlen = strlen(e->ring.callednum);
08705                      char digit;
08706                      int i;               
08707                      for (i = 0; i < digitlen; i++) { 
08708                         digit = e->ring.callednum[i];
08709                         {
08710                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
08711                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
08712                         }
08713                      }
08714                   }
08715                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08716                }
08717             }
08718             break;
08719          case PRI_EVENT_RING:
08720             crv = NULL;
08721             if (e->ring.channel == -1)
08722                chanpos = pri_find_empty_chan(pri, 1);
08723             else
08724                chanpos = pri_find_principle(pri, e->ring.channel);
08725             /* if no channel specified find one empty */
08726             if (chanpos < 0) {
08727                ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n", 
08728                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08729             } else {
08730                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08731                if (pri->pvts[chanpos]->owner) {
08732                   if (pri->pvts[chanpos]->call == e->ring.call) {
08733                      ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
08734                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08735                      break;
08736                   } else {
08737                      /* This is where we handle initial glare */
08738                      ast_log(LOG_DEBUG, "Ring requested on channel %d/%d already in use or previously requested on span %d.  Attempting to renegotiating channel.\n", 
08739                      PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
08740                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08741                      chanpos = -1;
08742                   }
08743                }
08744                if (chanpos > -1)
08745                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08746             }
08747             if ((chanpos < 0) && (e->ring.flexible))
08748                chanpos = pri_find_empty_chan(pri, 1);
08749             if (chanpos > -1) {
08750                ast_mutex_lock(&pri->pvts[chanpos]->lock);
08751                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
08752                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
08753                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
08754                   if (crv)
08755                      ast_mutex_lock(&crv->lock);
08756                   if (!crv || crv->owner) {
08757                      pri->pvts[chanpos]->call = NULL;
08758                      if (crv) {
08759                         if (crv->owner)
08760                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08761                         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);
08762                      } else
08763                         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);
08764                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
08765                      if (crv)
08766                         ast_mutex_unlock(&crv->lock);
08767                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08768                      break;
08769                   }
08770                }
08771                pri->pvts[chanpos]->call = e->ring.call;
08772                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
08773                if (pri->pvts[chanpos]->use_callerid) {
08774                   ast_shrink_phone_number(plancallingnum);
08775                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
08776 #ifdef PRI_ANI
08777                   if (!ast_strlen_zero(e->ring.callingani)) {
08778                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
08779                      ast_shrink_phone_number(plancallingani);
08780                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
08781                   } else {
08782                      pri->pvts[chanpos]->cid_ani[0] = '\0';
08783                   }
08784 #endif
08785                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
08786                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
08787                } else {
08788                   pri->pvts[chanpos]->cid_num[0] = '\0';
08789                   pri->pvts[chanpos]->cid_ani[0] = '\0';
08790                   pri->pvts[chanpos]->cid_name[0] = '\0';
08791                   pri->pvts[chanpos]->cid_ton = 0;
08792                }
08793                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
08794                           e->ring.redirectingnum, e->ring.callingplanrdnis);
08795                /* If immediate=yes go to s|1 */
08796                if (pri->pvts[chanpos]->immediate) {
08797                   if (option_verbose > 2)
08798                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
08799                   pri->pvts[chanpos]->exten[0] = 's';
08800                   pri->pvts[chanpos]->exten[1] = '\0';
08801                }
08802                /* Get called number */
08803                else if (!ast_strlen_zero(e->ring.callednum)) {
08804                   ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
08805                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08806                } else if (pri->overlapdial)
08807                   pri->pvts[chanpos]->exten[0] = '\0';
08808                else {
08809                   /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
08810                   pri->pvts[chanpos]->exten[0] = 's';
08811                   pri->pvts[chanpos]->exten[1] = '\0';
08812                }
08813                /* Set DNID on all incoming calls -- even immediate */
08814                if (!ast_strlen_zero(e->ring.callednum))
08815                   ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
08816                /* No number yet, but received "sending complete"? */
08817                if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
08818                   if (option_verbose > 2)
08819                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
08820                   pri->pvts[chanpos]->exten[0] = 's';
08821                   pri->pvts[chanpos]->exten[1] = '\0';
08822                }
08823                /* Make sure extension exists (or in overlap dial mode, can exist) */
08824                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
08825                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08826                   /* Setup law */
08827                   int law;
08828                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
08829                      /* Set to audio mode at this point */
08830                      law = 1;
08831                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08832                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
08833                   }
08834                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
08835                      law = ZT_LAW_ALAW;
08836                   else
08837                      law = ZT_LAW_MULAW;
08838                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
08839                   if (res < 0) 
08840                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
08841                   res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
08842                   if (res < 0)
08843                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
08844                   if (e->ring.complete || !pri->overlapdial) {
08845                      /* Just announce proceeding */
08846                      pri->pvts[chanpos]->proceeding = 1;
08847                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
08848                   } else {
08849                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
08850                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08851                      else
08852                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
08853                   }
08854                   /* Get the use_callingpres state */
08855                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
08856                
08857                   /* Start PBX */
08858                   if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
08859                      /* Release the PRI lock while we create the channel */
08860                      ast_mutex_unlock(&pri->lock);
08861                      if (crv) {
08862                         /* Set bearer and such */
08863                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
08864                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08865                         pri->pvts[chanpos]->owner = &inuse;
08866                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
08867                      } else {
08868                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
08869                      }
08870 
08871                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08872 
08873                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
08874                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
08875                      }
08876                      if (e->ring.ani2 >= 0) {
08877                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
08878                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08879                      }
08880 
08881 #ifdef SUPPORT_USERUSER
08882                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
08883                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08884                      }
08885 #endif
08886 
08887                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08888                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08889                      if (e->ring.redirectingreason >= 0)
08890                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08891                   
08892                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
08893                      ast_mutex_lock(&pri->lock);
08894 
08895                      pthread_attr_init(&attr);
08896                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08897                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
08898                         if (option_verbose > 2)
08899                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
08900                               plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
08901                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08902                      } else {
08903                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08904                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08905                         if (c)
08906                            ast_hangup(c);
08907                         else {
08908                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08909                            pri->pvts[chanpos]->call = NULL;
08910                         }
08911                      }
08912                      pthread_attr_destroy(&attr);
08913                   } else  {
08914                      ast_mutex_unlock(&pri->lock);
08915                      /* Release PRI lock while we create the channel */
08916                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
08917                      if (c) {
08918                         char calledtonstr[10];
08919 
08920                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08921 
08922                         if (e->ring.ani2 >= 0) {
08923                            snprintf(ani2str, 5, "%d", e->ring.ani2);
08924                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
08925                         }
08926 
08927 #ifdef SUPPORT_USERUSER
08928                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
08929                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
08930                         }
08931 #endif
08932 
08933                         if (e->ring.redirectingreason >= 0)
08934                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
08935                      
08936                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
08937                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
08938 
08939                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
08940                         ast_mutex_lock(&pri->lock);
08941 
08942                         if (option_verbose > 2)
08943                            ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
08944                               plancallingnum, pri->pvts[chanpos]->exten, 
08945                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08946                         zt_enable_ec(pri->pvts[chanpos]);
08947                      } else {
08948 
08949                         ast_mutex_lock(&pri->lock);
08950 
08951                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
08952                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
08953                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
08954                         pri->pvts[chanpos]->call = NULL;
08955                      }
08956                   }
08957                } else {
08958                   if (option_verbose > 2)
08959                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
08960                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
08961                            pri->pvts[chanpos]->prioffset, pri->span);
08962                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
08963                   pri->pvts[chanpos]->call = NULL;
08964                   pri->pvts[chanpos]->exten[0] = '\0';
08965                }
08966                if (crv)
08967                   ast_mutex_unlock(&crv->lock);
08968                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
08969             } else {
08970                if (e->ring.flexible)
08971                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
08972                else
08973                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
08974             }
08975             break;
08976          case PRI_EVENT_RINGING:
08977             chanpos = pri_find_principle(pri, e->ringing.channel);
08978             if (chanpos < 0) {
08979                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
08980                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08981             } else {
08982                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
08983                if (chanpos < 0) {
08984                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
08985                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
08986                } else {
08987                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
08988                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
08989                      zt_enable_ec(pri->pvts[chanpos]);
08990                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
08991                      pri->pvts[chanpos]->alerting = 1;
08992                   } else
08993                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
08994 #ifdef PRI_PROGRESS_MASK
08995                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
08996 #else
08997                   if (e->ringing.progress == 8) {
08998 #endif
08999                      /* Now we can do call progress detection */
09000                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09001                         /* RINGING detection isn't required because we got ALERTING signal */
09002                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
09003                         pri->pvts[chanpos]->dsp_features = 0;
09004                      }
09005                   }
09006 
09007 #ifdef SUPPORT_USERUSER
09008                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
09009                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09010                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09011                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
09012                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09013                   }
09014 #endif
09015 
09016                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09017                }
09018             }
09019             break;
09020          case PRI_EVENT_PROGRESS:
09021             /* Get chan value if e->e is not PRI_EVNT_RINGING */
09022             chanpos = pri_find_principle(pri, e->proceeding.channel);
09023             if (chanpos > -1) {
09024 #ifdef PRI_PROGRESS_MASK
09025                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
09026 #else
09027                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
09028 #endif
09029                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
09030 
09031                   if (e->proceeding.cause > -1) {
09032                      if (option_verbose > 2)
09033                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
09034 
09035                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
09036                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
09037                         if (pri->pvts[chanpos]->owner) {
09038                            if (option_verbose > 2)
09039                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
09040 
09041                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
09042                            f.subclass = AST_CONTROL_BUSY;
09043                         }
09044                      }
09045                   }
09046                   
09047                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09048                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
09049                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09050                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09051 #ifdef PRI_PROGRESS_MASK
09052                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09053 #else
09054                   if (e->proceeding.progress == 8) {
09055 #endif
09056                      /* Now we can do call progress detection */
09057                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09058                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09059                         pri->pvts[chanpos]->dsp_features = 0;
09060                      }
09061                   }
09062                   pri->pvts[chanpos]->progress = 1;
09063                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09064                }
09065             }
09066             break;
09067          case PRI_EVENT_PROCEEDING:
09068             chanpos = pri_find_principle(pri, e->proceeding.channel);
09069             if (chanpos > -1) {
09070                if (!pri->pvts[chanpos]->proceeding) {
09071                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
09072                   
09073                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09074                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
09075                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09076                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09077 #ifdef PRI_PROGRESS_MASK
09078                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09079 #else
09080                   if (e->proceeding.progress == 8) {
09081 #endif
09082                      /* Now we can do call progress detection */
09083                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09084                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09085                         pri->pvts[chanpos]->dsp_features = 0;
09086                      }
09087                      /* Bring voice path up */
09088                      f.subclass = AST_CONTROL_PROGRESS;
09089                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
09090                   }
09091                   pri->pvts[chanpos]->proceeding = 1;
09092                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09093                }
09094             }
09095             break;
09096          case PRI_EVENT_FACNAME:
09097             chanpos = pri_find_principle(pri, e->facname.channel);
09098             if (chanpos < 0) {
09099                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09100                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09101             } else {
09102                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09103                if (chanpos < 0) {
09104                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09105                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09106                } else {
09107                   /* Re-use *69 field for PRI */
09108                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09109                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09110                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09111                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09112                   zt_enable_ec(pri->pvts[chanpos]);
09113                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09114                }
09115             }
09116             break;            
09117          case PRI_EVENT_ANSWER:
09118             chanpos = pri_find_principle(pri, e->answer.channel);
09119             if (chanpos < 0) {
09120                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09121                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09122             } else {
09123                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09124                if (chanpos < 0) {
09125                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09126                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09127                } else {
09128                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09129                   /* Now we can do call progress detection */
09130 
09131                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09132                    * By this time, we need DTMF detection and other features that were previously disabled
09133                    * -- Matt F */
09134                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09135                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09136                      pri->pvts[chanpos]->dsp_features = 0;
09137                   }
09138                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09139                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09140                      x = ZT_START;
09141                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09142                      if (res < 0) {
09143                         if (errno != EINPROGRESS) {
09144                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09145                         }
09146                      }
09147                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09148                      pri->pvts[chanpos]->dialing = 1;
09149                      /* Send any "w" waited stuff */
09150                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09151                      if (res < 0) {
09152                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
09153                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09154                      } else 
09155                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
09156                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
09157                   } else if (pri->pvts[chanpos]->confirmanswer) {
09158                      ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
09159                   } else {
09160                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
09161                      /* Enable echo cancellation if it's not on already */
09162                      zt_enable_ec(pri->pvts[chanpos]);
09163                   }
09164 
09165 #ifdef SUPPORT_USERUSER
09166                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
09167                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09168                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09169                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
09170                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09171                   }
09172 #endif
09173 
09174                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09175                }
09176             }
09177             break;            
09178          case PRI_EVENT_HANGUP:
09179             chanpos = pri_find_principle(pri, e->hangup.channel);
09180             if (chanpos < 0) {
09181                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
09182                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09183             } else {
09184                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09185                if (chanpos > -1) {
09186                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09187                   if (!pri->pvts[chanpos]->alreadyhungup) {
09188                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
09189                      pri->pvts[chanpos]->alreadyhungup = 1;
09190                      if (pri->pvts[chanpos]->realcall) 
09191                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09192                      else if (pri->pvts[chanpos]->owner) {
09193                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
09194                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09195                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09196                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09197                         else {
09198                            switch (e->hangup.cause) {
09199                               case PRI_CAUSE_USER_BUSY:
09200                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09201                                  break;
09202                               case PRI_CAUSE_CALL_REJECTED:
09203                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09204                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09205                               case PRI_CAUSE_SWITCH_CONGESTION:
09206                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09207                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09208                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09209                                  break;
09210                               default:
09211                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09212                            }
09213                         }
09214                      }
09215                      if (option_verbose > 2) 
09216                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
09217                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
09218                   } else {
09219                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09220                      pri->pvts[chanpos]->call = NULL;
09221                   }
09222                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09223                      if (option_verbose > 2)
09224                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
09225                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09226                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09227                      pri->pvts[chanpos]->resetting = 1;
09228                   }
09229                   if (e->hangup.aoc_units > -1)
09230                      if (option_verbose > 2)
09231                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09232                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09233 
09234 #ifdef SUPPORT_USERUSER
09235                   if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
09236                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09237                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09238                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09239                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09240                   }
09241 #endif
09242 
09243                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09244                } else {
09245                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
09246                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09247                }
09248             } 
09249             break;
09250 #ifndef PRI_EVENT_HANGUP_REQ
09251 #error please update libpri
09252 #endif
09253          case PRI_EVENT_HANGUP_REQ:
09254             chanpos = pri_find_principle(pri, e->hangup.channel);
09255             if (chanpos < 0) {
09256                ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
09257                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09258             } else {
09259                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09260                if (chanpos > -1) {
09261                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09262                   if (pri->pvts[chanpos]->realcall) 
09263                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09264                   else if (pri->pvts[chanpos]->owner) {
09265                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
09266                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
09267                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09268                      else {
09269                         switch (e->hangup.cause) {
09270                            case PRI_CAUSE_USER_BUSY:
09271                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
09272                               break;
09273                            case PRI_CAUSE_CALL_REJECTED:
09274                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
09275                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
09276                            case PRI_CAUSE_SWITCH_CONGESTION:
09277                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
09278                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
09279                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
09280                               break;
09281                            default:
09282                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09283                         }
09284                      }
09285                      if (option_verbose > 2) 
09286                         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);
09287                      if (e->hangup.aoc_units > -1)
09288                         if (option_verbose > 2)
09289                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
09290                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
09291                   } else {
09292                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
09293                      pri->pvts[chanpos]->call = NULL;
09294                   }
09295                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
09296                      if (option_verbose > 2)
09297                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
09298                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09299                      pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
09300                      pri->pvts[chanpos]->resetting = 1;
09301                   }
09302 
09303 #ifdef SUPPORT_USERUSER
09304                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09305                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09306                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09307                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09308                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09309                   }
09310 #endif
09311 
09312                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09313                } else {
09314                   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);
09315                }
09316             } 
09317             break;
09318          case PRI_EVENT_HANGUP_ACK:
09319             chanpos = pri_find_principle(pri, e->hangup.channel);
09320             if (chanpos < 0) {
09321                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
09322                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
09323             } else {
09324                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
09325                if (chanpos > -1) {
09326                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09327                   pri->pvts[chanpos]->call = NULL;
09328                   pri->pvts[chanpos]->resetting = 0;
09329                   if (pri->pvts[chanpos]->owner) {
09330                      if (option_verbose > 2) 
09331                         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);
09332                   }
09333 
09334 #ifdef SUPPORT_USERUSER
09335                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
09336                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09337                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09338                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
09339                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09340                   }
09341 #endif
09342 
09343                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09344                }
09345             }
09346             break;
09347          case PRI_EVENT_CONFIG_ERR:
09348             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
09349             break;
09350          case PRI_EVENT_RESTART_ACK:
09351             chanpos = pri_find_principle(pri, e->restartack.channel);
09352             if (chanpos < 0) {
09353                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
09354                   channel number, so we have to figure it out...  This must be why
09355                   everybody resets exactly a channel at a time. */
09356                for (x = 0; x < pri->numchans; x++) {
09357                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
09358                      chanpos = x;
09359                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09360                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
09361                            pri->pvts[chanpos]->prioffset, pri->span);
09362                      if (pri->pvts[chanpos]->realcall) 
09363                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09364                      else if (pri->pvts[chanpos]->owner) {
09365                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
09366                            pri->pvts[chanpos]->prioffset, pri->span);
09367                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09368                      }
09369                      pri->pvts[chanpos]->resetting = 0;
09370                      if (option_verbose > 2)
09371                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09372                            pri->pvts[chanpos]->prioffset, pri->span);
09373                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09374                      if (pri->resetting)
09375                         pri_check_restart(pri);
09376                      break;
09377                   }
09378                }
09379                if (chanpos < 0) {
09380                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
09381                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09382                }
09383             } else {
09384                if (pri->pvts[chanpos]) {
09385                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09386                   if (pri->pvts[chanpos]->realcall) 
09387                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09388                   else if (pri->pvts[chanpos]->owner) {
09389                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
09390                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
09391                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09392                   }
09393                   pri->pvts[chanpos]->resetting = 0;
09394                   if (option_verbose > 2)
09395                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
09396                            pri->pvts[chanpos]->prioffset, pri->span);
09397                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09398                   if (pri->resetting)
09399                      pri_check_restart(pri);
09400                }
09401             }
09402             break;
09403          case PRI_EVENT_SETUP_ACK:
09404             chanpos = pri_find_principle(pri, e->setup_ack.channel);
09405             if (chanpos < 0) {
09406                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
09407                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
09408             } else {
09409                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
09410                if (chanpos > -1) {
09411                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09412                   pri->pvts[chanpos]->setup_ack = 1;
09413                   /* Send any queued digits */
09414                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
09415                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
09416                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
09417                         pri->pvts[chanpos]->dialdest[x]);
09418                   }
09419                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09420                } else
09421                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
09422             }
09423             break;
09424          case PRI_EVENT_NOTIFY:
09425             chanpos = pri_find_principle(pri, e->notify.channel);
09426             if (chanpos < 0) {
09427                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
09428                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
09429             } else {
09430                struct ast_frame f = { AST_FRAME_CONTROL, };
09431                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09432                switch (e->notify.info) {
09433                case PRI_NOTIFY_REMOTE_HOLD:
09434                   f.subclass = AST_CONTROL_HOLD;
09435                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09436                   break;
09437                case PRI_NOTIFY_REMOTE_RETRIEVAL:
09438                   f.subclass = AST_CONTROL_UNHOLD;
09439                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09440                   break;
09441                }
09442                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09443             }
09444             break;
09445          default:
09446             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
09447          }
09448       }  
09449       ast_mutex_unlock(&pri->lock);
09450    }
09451    /* Never reached */
09452    return NULL;
09453 }
09454 
09455 static int start_pri(struct zt_pri *pri)
09456 {
09457    int res, x;
09458    ZT_PARAMS p;
09459    ZT_BUFFERINFO bi;
09460    struct zt_spaninfo si;
09461    int i;
09462    
09463    for (i = 0; i < NUM_DCHANS; i++) {
09464       if (!pri->dchannels[i])
09465          break;
09466       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
09467       x = pri->dchannels[i];
09468       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
09469          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
09470          return -1;
09471       }
09472       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
09473       if (res) {
09474          zt_close(pri->fds[i]);
09475          pri->fds[i] = -1;
09476          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
09477          return -1;
09478       }
09479       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
09480          zt_close(pri->fds[i]);
09481          pri->fds[i] = -1;
09482          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
09483          return -1;
09484       }
09485       memset(&si, 0, sizeof(si));
09486       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
09487       if (res) {
09488          zt_close(pri->fds[i]);
09489          pri->fds[i] = -1;
09490          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
09491       }
09492       if (!si.alarms)
09493          pri->dchanavail[i] |= DCHAN_NOTINALARM;
09494       else
09495          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
09496       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
09497       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
09498       bi.numbufs = 32;
09499       bi.bufsize = 1024;
09500       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
09501          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
09502          zt_close(pri->fds[i]);
09503          pri->fds[i] = -1;
09504          return -1;
09505       }
09506       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
09507       /* Force overlap dial if we're doing GR-303! */
09508       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
09509          pri->overlapdial = 1;
09510       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
09511       /* Enslave to master if appropriate */
09512       if (i)
09513          pri_enslave(pri->dchans[0], pri->dchans[i]);
09514       if (!pri->dchans[i]) {
09515          zt_close(pri->fds[i]);
09516          pri->fds[i] = -1;
09517          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
09518          return -1;
09519       }
09520       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
09521       pri_set_nsf(pri->dchans[i], pri->nsf);
09522 #ifdef PRI_GETSET_TIMERS
09523       for (x = 0; x < PRI_MAX_TIMERS; x++) {
09524          if (pritimers[x] != 0)
09525             pri_set_timer(pri->dchans[i], x, pritimers[x]);
09526       }
09527 #endif
09528    }
09529    /* Assume primary is the one we use */
09530    pri->pri = pri->dchans[0];
09531    pri->resetpos = -1;
09532    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
09533       for (i = 0; i < NUM_DCHANS; i++) {
09534          if (!pri->dchannels[i])
09535             break;
09536          zt_close(pri->fds[i]);
09537          pri->fds[i] = -1;
09538       }
09539       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
09540       return -1;
09541    }
09542    return 0;
09543 }
09544 
09545 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
09546 {
09547    int which, span;
09548    char *ret = NULL;
09549 
09550    if (pos != rpos)
09551       return ret;
09552 
09553    for (which = span = 0; span < NUM_SPANS; span++) {
09554       if (pris[span].pri && ++which > state) {
09555          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
09556          break;
09557       }
09558    }
09559    return ret;
09560 }
09561 
09562 static char *complete_span_4(const char *line, const char *word, int pos, int state)
09563 {
09564    return complete_span_helper(line,word,pos,state,3);
09565 }
09566 
09567 static char *complete_span_5(const char *line, const char *word, int pos, int state)
09568 {
09569    return complete_span_helper(line,word,pos,state,4);
09570 }
09571 
09572 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
09573 {
09574    int myfd;
09575 
09576    if (!strncasecmp(argv[1], "set", 3)) {
09577       if (argc < 5) 
09578          return RESULT_SHOWUSAGE;
09579 
09580       if (ast_strlen_zero(argv[4]))
09581          return RESULT_SHOWUSAGE;
09582 
09583       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
09584       if (myfd < 0) {
09585          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
09586          return RESULT_SUCCESS;
09587       }
09588 
09589       ast_mutex_lock(&pridebugfdlock);
09590 
09591       if (pridebugfd >= 0)
09592          close(pridebugfd);
09593 
09594       pridebugfd = myfd;
09595       ast_copy_string(pridebugfilename,argv[4],sizeof(pridebugfilename));
09596       
09597       ast_mutex_unlock(&pridebugfdlock);
09598 
09599       ast_cli(fd, "PRI debug output will be sent to '%s'\n", argv[4]);
09600    } else {
09601       /* Assume it is unset */
09602       ast_mutex_lock(&pridebugfdlock);
09603       close(pridebugfd);
09604       pridebugfd = -1;
09605       ast_cli(fd, "PRI debug output to file disabled\n");
09606       ast_mutex_unlock(&pridebugfdlock);
09607    }
09608 
09609    return RESULT_SUCCESS;
09610 }
09611 
09612 static int handle_pri_debug(int fd, int argc, char *argv[])
09613 {
09614    int span;
09615    int x;
09616    if (argc < 4) {
09617       return RESULT_SHOWUSAGE;
09618    }
09619    span = atoi(argv[3]);
09620    if ((span < 1) || (span > NUM_SPANS)) {
09621       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
09622       return RESULT_SUCCESS;
09623    }
09624    if (!pris[span-1].pri) {
09625       ast_cli(fd, "No PRI running on span %d\n", span);
09626       return RESULT_SUCCESS;
09627    }
09628    for (x = 0; x < NUM_DCHANS; x++) {
09629       if (pris[span-1].dchans[x])
09630          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09631                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09632                                                PRI_DEBUG_Q921_STATE);
09633    }
09634    ast_cli(fd, "Enabled debugging on span %d\n", span);
09635    return RESULT_SUCCESS;
09636 }
09637 
09638 
09639 
09640 static int handle_pri_no_debug(int fd, int argc, char *argv[])
09641 {
09642    int span;
09643    int x;
09644    if (argc < 5)
09645       return RESULT_SHOWUSAGE;
09646    span = atoi(argv[4]);
09647    if ((span < 1) || (span > NUM_SPANS)) {
09648       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09649       return RESULT_SUCCESS;
09650    }
09651    if (!pris[span-1].pri) {
09652       ast_cli(fd, "No PRI running on span %d\n", span);
09653       return RESULT_SUCCESS;
09654    }
09655    for (x = 0; x < NUM_DCHANS; x++) {
09656       if (pris[span-1].dchans[x])
09657          pri_set_debug(pris[span-1].dchans[x], 0);
09658    }
09659    ast_cli(fd, "Disabled debugging on span %d\n", span);
09660    return RESULT_SUCCESS;
09661 }
09662 
09663 static int handle_pri_really_debug(int fd, int argc, char *argv[])
09664 {
09665    int span;
09666    int x;
09667    if (argc < 5)
09668       return RESULT_SHOWUSAGE;
09669    span = atoi(argv[4]);
09670    if ((span < 1) || (span > NUM_SPANS)) {
09671       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
09672       return RESULT_SUCCESS;
09673    }
09674    if (!pris[span-1].pri) {
09675       ast_cli(fd, "No PRI running on span %d\n", span);
09676       return RESULT_SUCCESS;
09677    }
09678    for (x = 0; x < NUM_DCHANS; x++) {
09679       if (pris[span-1].dchans[x])
09680          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
09681                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
09682                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
09683    }
09684    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
09685    return RESULT_SUCCESS;
09686 }
09687 
09688 static void build_status(char *s, size_t len, int status, int active)
09689 {
09690    if (!s || len < 1) {
09691       return;
09692    }
09693    s[0] = '\0';
09694    if (status & DCHAN_PROVISIONED)
09695       strncat(s, "Provisioned, ", len - strlen(s) - 1);
09696    if (!(status & DCHAN_NOTINALARM))
09697       strncat(s, "In Alarm, ", len - strlen(s) - 1);
09698    if (status & DCHAN_UP)
09699       strncat(s, "Up", len - strlen(s) - 1);
09700    else
09701       strncat(s, "Down", len - strlen(s) - 1);
09702    if (active)
09703       strncat(s, ", Active", len - strlen(s) - 1);
09704    else
09705       strncat(s, ", Standby", len - strlen(s) - 1);
09706    s[len - 1] = '\0';
09707 }
09708 
09709 static int handle_pri_show_spans(int fd, int argc, char *argv[])
09710 {
09711    int span;
09712    int x;
09713    char status[256];
09714    if (argc != 3)
09715       return RESULT_SHOWUSAGE;
09716 
09717    for (span = 0; span < NUM_SPANS; span++) {
09718       if (pris[span].pri) {
09719          for (x = 0; x < NUM_DCHANS; x++) {
09720             if (pris[span].dchannels[x]) {
09721                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
09722                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
09723             }
09724          }
09725       }
09726    }
09727    return RESULT_SUCCESS;
09728 }
09729 
09730 static int handle_pri_show_span(int fd, int argc, char *argv[])
09731 {
09732    int span;
09733    int x;
09734    char status[256];
09735    if (argc < 4)
09736       return RESULT_SHOWUSAGE;
09737    span = atoi(argv[3]);
09738    if ((span < 1) || (span > NUM_SPANS)) {
09739       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
09740       return RESULT_SUCCESS;
09741    }
09742    if (!pris[span-1].pri) {
09743       ast_cli(fd, "No PRI running on span %d\n", span);
09744       return RESULT_SUCCESS;
09745    }
09746    for (x = 0; x < NUM_DCHANS; x++) {
09747       if (pris[span-1].dchannels[x]) {
09748 #ifdef PRI_DUMP_INFO_STR
09749          char *info_str = NULL;
09750 #endif
09751          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
09752          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
09753          ast_cli(fd, "Status: %s\n", status);
09754 #ifdef PRI_DUMP_INFO_STR
09755          info_str = pri_dump_info_str(pris[span-1].pri);
09756          if (info_str) {
09757             ast_cli(fd, "%s", info_str);
09758             free(info_str);
09759          }
09760 #else
09761          pri_dump_info(pris[span-1].pri);
09762 #endif
09763          ast_cli(fd, "\n");
09764       }
09765    }
09766    return RESULT_SUCCESS;
09767 }
09768 
09769 static int handle_pri_show_debug(int fd, int argc, char *argv[])
09770 {
09771    int x;
09772    int span;
09773    int count=0;
09774    int debug=0;
09775 
09776    for (span = 0; span < NUM_SPANS; span++) {
09777            if (pris[span].pri) {
09778          for (x = 0; x < NUM_DCHANS; x++) {
09779             debug = 0;
09780                if (pris[span].dchans[x]) {
09781                   debug = pri_get_debug(pris[span].dchans[x]);
09782                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" );
09783                count++;
09784             }
09785          }
09786       }
09787 
09788    }
09789    ast_mutex_lock(&pridebugfdlock);
09790    if (pridebugfd >= 0) 
09791       ast_cli(fd, "Logging PRI debug to file %s\n", pridebugfilename);
09792    ast_mutex_unlock(&pridebugfdlock);
09793        
09794    if (!count) 
09795       ast_cli(fd, "No debug set or no PRI running\n");
09796    return RESULT_SUCCESS;
09797 }
09798 
09799 static const char pri_debug_help[] = 
09800    "Usage: pri debug span <span>\n"
09801    "       Enables debugging on a given PRI span\n";
09802    
09803 static const char pri_no_debug_help[] = 
09804    "Usage: pri no debug span <span>\n"
09805    "       Disables debugging on a given PRI span\n";
09806 
09807 static const char pri_really_debug_help[] = 
09808    "Usage: pri intensive debug span <span>\n"
09809    "       Enables debugging down to the Q.921 level\n";
09810 
09811 static const char pri_show_span_help[] = 
09812    "Usage: pri show span <span>\n"
09813    "       Displays PRI Information on a given PRI span\n";
09814 
09815 static const char pri_show_spans_help[] = 
09816    "Usage: pri show spans\n"
09817    "       Displays PRI Information\n";
09818 
09819 static struct ast_cli_entry zap_pri_cli[] = {
09820    { { "pri", "debug", "span", NULL },
09821    handle_pri_debug, "Enables PRI debugging on a span",
09822    pri_debug_help, complete_span_4 },
09823 
09824    { { "pri", "no", "debug", "span", NULL },
09825    handle_pri_no_debug, "Disables PRI debugging on a span",
09826    pri_no_debug_help, complete_span_5 },
09827 
09828    { { "pri", "intense", "debug", "span", NULL },
09829    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
09830    pri_really_debug_help, complete_span_5 },
09831 
09832    { { "pri", "show", "spans", NULL },
09833    handle_pri_show_spans, "Displays PRI Information",
09834    pri_show_spans_help },
09835 
09836    { { "pri", "show", "span", NULL },
09837    handle_pri_show_span, "Displays PRI Information",
09838    pri_show_span_help, complete_span_4 },
09839 
09840    { { "pri", "show", "debug", NULL },
09841    handle_pri_show_debug, "Displays current PRI debug settings" },
09842 
09843    { { "pri", "set", "debug", "file", NULL },
09844    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
09845 
09846    { { "pri", "unset", "debug", "file", NULL },
09847    handle_pri_set_debug_file, "Ends PRI debug output to file" },
09848 };
09849 
09850 #endif /* HAVE_PRI */
09851 
09852 static int zap_destroy_channel(int fd, int argc, char **argv)
09853 {
09854    int channel;
09855    
09856    if (argc != 4)
09857       return RESULT_SHOWUSAGE;
09858    
09859    channel = atoi(argv[3]);
09860 
09861    return zap_destroy_channel_bynum(channel);
09862 }
09863 
09864 static int setup_zap(int reload);
09865 static int zap_restart(void)
09866 {
09867    if (option_verbose > 0)
09868       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
09869    while (iflist) {
09870       if (option_debug)
09871          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
09872       /* Also updates iflist: */
09873       destroy_channel(NULL, iflist, 1);
09874    }
09875    if (option_debug)
09876       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
09877    if (setup_zap(0) != 0) {
09878       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
09879       return 1;
09880    }
09881    return 0;
09882 }
09883 
09884 static int zap_restart_cmd(int fd, int argc, char **argv)
09885 {
09886    if (argc != 2) {
09887       return RESULT_SHOWUSAGE;
09888    }
09889 
09890    if (zap_restart() != 0)
09891       return RESULT_FAILURE;
09892    return RESULT_SUCCESS;
09893 }
09894 
09895 static int action_zaprestart(struct mansession *s, const struct message *m)
09896 {
09897    if (zap_restart() != 0) {
09898       astman_send_error(s, m, "Failed rereading zaptel configuration");
09899       return 1;
09900    }
09901    astman_send_ack(s, m, "ZapRestart: Success");
09902    return 0;
09903 }
09904 
09905 static int zap_show_channels(int fd, int argc, char **argv)
09906 {
09907 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09908 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
09909    struct zt_pvt *tmp = NULL;
09910    char tmps[20] = "";
09911    ast_mutex_t *lock;
09912    struct zt_pvt *start;
09913 #ifdef HAVE_PRI
09914    int trunkgroup;
09915    struct zt_pri *pri = NULL;
09916    int x;
09917 #endif
09918 
09919    lock = &iflock;
09920    start = iflist;
09921 
09922 #ifdef HAVE_PRI
09923    if (argc == 4) {
09924       if ((trunkgroup = atoi(argv[3])) < 1)
09925          return RESULT_SHOWUSAGE;
09926       for (x = 0; x < NUM_SPANS; x++) {
09927          if (pris[x].trunkgroup == trunkgroup) {
09928             pri = pris + x;
09929             break;
09930          }
09931       }
09932       if (pri) {
09933          start = pri->crvs;
09934          lock = &pri->lock;
09935       } else {
09936          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
09937          return RESULT_FAILURE;
09938       }
09939    } else
09940 #endif
09941    if (argc != 3)
09942       return RESULT_SHOWUSAGE;
09943 
09944    ast_mutex_lock(lock);
09945 #ifdef HAVE_PRI
09946    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
09947 #else
09948    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
09949 #endif   
09950    
09951    tmp = start;
09952    while (tmp) {
09953       if (tmp->channel > 0) {
09954          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
09955       } else
09956          ast_copy_string(tmps, "pseudo", sizeof(tmps));
09957       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
09958       tmp = tmp->next;
09959    }
09960    ast_mutex_unlock(lock);
09961    return RESULT_SUCCESS;
09962 #undef FORMAT
09963 #undef FORMAT2
09964 }
09965 
09966 static int zap_show_channel(int fd, int argc, char **argv)
09967 {
09968    int channel;
09969    struct zt_pvt *tmp = NULL;
09970    ZT_CONFINFO ci;
09971    ZT_PARAMS ps;
09972    int x;
09973    ast_mutex_t *lock;
09974    struct zt_pvt *start;
09975 #ifdef HAVE_PRI
09976    char *c;
09977    int trunkgroup;
09978    struct zt_pri *pri=NULL;
09979 #endif
09980 
09981    lock = &iflock;
09982    start = iflist;
09983 
09984    if (argc != 4)
09985       return RESULT_SHOWUSAGE;
09986 #ifdef HAVE_PRI
09987    if ((c = strchr(argv[3], ':'))) {
09988       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
09989          return RESULT_SHOWUSAGE;
09990       if ((trunkgroup < 1) || (channel < 1))
09991          return RESULT_SHOWUSAGE;
09992       for (x = 0; x < NUM_SPANS; x++) {
09993          if (pris[x].trunkgroup == trunkgroup) {
09994             pri = pris + x;
09995             break;
09996          }
09997       }
09998       if (pri) {
09999          start = pri->crvs;
10000          lock = &pri->lock;
10001       } else {
10002          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
10003          return RESULT_FAILURE;
10004       }
10005    } else
10006 #endif
10007       channel = atoi(argv[3]);
10008 
10009    ast_mutex_lock(lock);
10010    tmp = start;
10011    while (tmp) {
10012       if (tmp->channel == channel) {
10013 #ifdef HAVE_PRI
10014          if (pri) 
10015             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
10016          else
10017 #endif         
10018          ast_cli(fd, "Channel: %d\n", tmp->channel);
10019          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
10020          ast_cli(fd, "Span: %d\n", tmp->span);
10021          ast_cli(fd, "Extension: %s\n", tmp->exten);
10022          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
10023          ast_cli(fd, "Context: %s\n", tmp->context);
10024          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
10025          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
10026          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
10027          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
10028          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
10029          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
10030          ast_cli(fd, "Radio: %d\n", tmp->radio);
10031          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
10032          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)" : "");
10033          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)" : "");
10034          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)" : "");
10035          ast_cli(fd, "Confno: %d\n", tmp->confno);
10036          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
10037          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
10038          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
10039          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
10040          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
10041          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
10042          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
10043          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
10044          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
10045          if (tmp->master)
10046             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
10047          for (x = 0; x < MAX_SLAVES; x++) {
10048             if (tmp->slaves[x])
10049                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
10050          }
10051 #ifdef HAVE_PRI
10052          if (tmp->pri) {
10053             ast_cli(fd, "PRI Flags: ");
10054             if (tmp->resetting)
10055                ast_cli(fd, "Resetting ");
10056             if (tmp->call)
10057                ast_cli(fd, "Call ");
10058             if (tmp->bearer)
10059                ast_cli(fd, "Bearer ");
10060             ast_cli(fd, "\n");
10061             if (tmp->logicalspan) 
10062                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
10063             else
10064                ast_cli(fd, "PRI Logical Span: Implicit\n");
10065          }
10066             
10067 #endif
10068          memset(&ci, 0, sizeof(ci));
10069          ps.channo = tmp->channel;
10070          if (tmp->subs[SUB_REAL].zfd > -1) {
10071             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
10072                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
10073             }
10074 #ifdef ZT_GETCONFMUTE
10075             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
10076                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
10077             }
10078 #endif
10079             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
10080                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
10081             } else {
10082                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
10083             }
10084          }
10085          ast_mutex_unlock(lock);
10086          return RESULT_SUCCESS;
10087       }
10088       tmp = tmp->next;
10089    }
10090    
10091    ast_cli(fd, "Unable to find given channel %d\n", channel);
10092    ast_mutex_unlock(lock);
10093    return RESULT_FAILURE;
10094 }
10095 
10096 static char zap_show_cadences_help[] =
10097 "Usage: zap show cadences\n"
10098 "       Shows all cadences currently defined\n";
10099 
10100 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
10101 {
10102    int i, j;
10103    for (i = 0; i < num_cadence; i++) {
10104       char output[1024];
10105       char tmp[16], tmp2[64];
10106       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
10107       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
10108 
10109       for (j = 0; j < 16; j++) {
10110          if (cadences[i].ringcadence[j] == 0)
10111             break;
10112          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
10113          if (cidrings[i] * 2 - 1 == j)
10114             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
10115          else
10116             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
10117          if (j != 0)
10118             strncat(output, ",", sizeof(output) - strlen(output) - 1);
10119          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
10120       }
10121       ast_cli(fd,"%s\n",output);
10122    }
10123    return 0;
10124 }
10125 
10126 /* Based on irqmiss.c */
10127 static int zap_show_status(int fd, int argc, char *argv[]) {
10128    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
10129    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
10130 
10131    int span;
10132    int res;
10133    char alarms[50];
10134 
10135    int ctl;
10136    ZT_SPANINFO s;
10137 
10138    ctl = open("/dev/zap/ctl", O_RDWR);
10139    if (ctl < 0) {
10140       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
10141       ast_cli(fd, "No Zaptel interface found.\n");
10142       return RESULT_FAILURE;
10143    }
10144    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10145 
10146    for (span = 1; span < ZT_MAX_SPANS; ++span) {
10147       s.spanno = span;
10148       res = ioctl(ctl, ZT_SPANSTAT, &s);
10149       if (res) {
10150          continue;
10151       }
10152       alarms[0] = '\0';
10153       if (s.alarms > 0) {
10154          if (s.alarms & ZT_ALARM_BLUE)
10155             strcat(alarms, "BLU/");
10156          if (s.alarms & ZT_ALARM_YELLOW)
10157             strcat(alarms, "YEL/");
10158          if (s.alarms & ZT_ALARM_RED)
10159             strcat(alarms, "RED/");
10160          if (s.alarms & ZT_ALARM_LOOPBACK)
10161             strcat(alarms, "LB/");
10162          if (s.alarms & ZT_ALARM_RECOVER)
10163             strcat(alarms, "REC/");
10164          if (s.alarms & ZT_ALARM_NOTOPEN)
10165             strcat(alarms, "NOP/");
10166          if (!strlen(alarms))
10167             strcat(alarms, "UUU/");
10168          if (strlen(alarms)) {
10169             /* Strip trailing / */
10170             alarms[strlen(alarms) - 1] = '\0';
10171          }
10172       } else {
10173          if (s.numchans)
10174             strcpy(alarms, "OK");
10175          else
10176             strcpy(alarms, "UNCONFIGURED");
10177       }
10178 
10179       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
10180    }
10181    close(ctl);
10182 
10183    return RESULT_SUCCESS;
10184 #undef FORMAT
10185 #undef FORMAT2
10186 }
10187 
10188 static char show_channels_usage[] =
10189    "Usage: zap show channels\n"
10190    "  Shows a list of available channels\n";
10191 
10192 static char show_channel_usage[] =
10193    "Usage: zap show channel <chan num>\n"
10194    "  Detailed information about a given channel\n";
10195 
10196 static char zap_show_status_usage[] =
10197    "Usage: zap show status\n"
10198    "       Shows a list of Zaptel cards with status\n";
10199 
10200 static char destroy_channel_usage[] =
10201    "Usage: zap destroy channel <chan num>\n"
10202    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
10203 
10204 static char zap_restart_usage[] =
10205    "Usage: zap restart\n"
10206    "  Restarts the zaptel channels: destroys them all and then\n"
10207    "  re-reads them from zapata.conf.\n"
10208    "  Note that this will STOP any running CALL on zaptel channels.\n"
10209    "";
10210 
10211 static struct ast_cli_entry zap_cli[] = {
10212    { { "zap", "show", "cadences", NULL },
10213    handle_zap_show_cadences, "List cadences",
10214    zap_show_cadences_help },
10215 
10216    { { "zap", "show", "channels", NULL},
10217    zap_show_channels, "Show active zapata channels",
10218    show_channels_usage },
10219 
10220    { { "zap", "show", "channel", NULL},
10221    zap_show_channel, "Show information on a channel",
10222    show_channel_usage },
10223 
10224    { { "zap", "destroy", "channel", NULL},
10225    zap_destroy_channel, "Destroy a channel",
10226    destroy_channel_usage },
10227 
10228    { { "zap", "restart", NULL},
10229    zap_restart_cmd, "Fully restart zaptel channels",
10230    zap_restart_usage },
10231 
10232    { { "zap", "show", "status", NULL},
10233    zap_show_status, "Show all Zaptel cards status",
10234    zap_show_status_usage },
10235 };
10236 
10237 #define TRANSFER  0
10238 #define HANGUP    1
10239 
10240 static int zap_fake_event(struct zt_pvt *p, int mode)
10241 {
10242    if (p) {
10243       switch (mode) {
10244          case TRANSFER:
10245             p->fake_event = ZT_EVENT_WINKFLASH;
10246             break;
10247          case HANGUP:
10248             p->fake_event = ZT_EVENT_ONHOOK;
10249             break;
10250          default:
10251             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
10252       }
10253    }
10254    return 0;
10255 }
10256 static struct zt_pvt *find_channel(int channel)
10257 {
10258    struct zt_pvt *p = iflist;
10259    while (p) {
10260       if (p->channel == channel) {
10261          break;
10262       }
10263       p = p->next;
10264    }
10265    return p;
10266 }
10267 
10268 static int action_zapdndon(struct mansession *s, const struct message *m)
10269 {
10270    struct zt_pvt *p = NULL;
10271    const char *channel = astman_get_header(m, "ZapChannel");
10272 
10273    if (ast_strlen_zero(channel)) {
10274       astman_send_error(s, m, "No channel specified");
10275       return 0;
10276    }
10277    p = find_channel(atoi(channel));
10278    if (!p) {
10279       astman_send_error(s, m, "No such channel");
10280       return 0;
10281    }
10282    p->dnd = 1;
10283    astman_send_ack(s, m, "DND Enabled");
10284    return 0;
10285 }
10286 
10287 static int action_zapdndoff(struct mansession *s, const struct message *m)
10288 {
10289    struct zt_pvt *p = NULL;
10290    const char *channel = astman_get_header(m, "ZapChannel");
10291 
10292    if (ast_strlen_zero(channel)) {
10293       astman_send_error(s, m, "No channel specified");
10294       return 0;
10295    }
10296    p = find_channel(atoi(channel));
10297    if (!p) {
10298       astman_send_error(s, m, "No such channel");
10299       return 0;
10300    }
10301    p->dnd = 0;
10302    astman_send_ack(s, m, "DND Disabled");
10303    return 0;
10304 }
10305 
10306 static int action_transfer(struct mansession *s, const struct message *m)
10307 {
10308    struct zt_pvt *p = NULL;
10309    const char *channel = astman_get_header(m, "ZapChannel");
10310 
10311    if (ast_strlen_zero(channel)) {
10312       astman_send_error(s, m, "No channel specified");
10313       return 0;
10314    }
10315    p = find_channel(atoi(channel));
10316    if (!p) {
10317       astman_send_error(s, m, "No such channel");
10318       return 0;
10319    }
10320    zap_fake_event(p,TRANSFER);
10321    astman_send_ack(s, m, "ZapTransfer");
10322    return 0;
10323 }
10324 
10325 static int action_transferhangup(struct mansession *s, const struct message *m)
10326 {
10327    struct zt_pvt *p = NULL;
10328    const char *channel = astman_get_header(m, "ZapChannel");
10329 
10330    if (ast_strlen_zero(channel)) {
10331       astman_send_error(s, m, "No channel specified");
10332       return 0;
10333    }
10334    p = find_channel(atoi(channel));
10335    if (!p) {
10336       astman_send_error(s, m, "No such channel");
10337       return 0;
10338    }
10339    zap_fake_event(p,HANGUP);
10340    astman_send_ack(s, m, "ZapHangup");
10341    return 0;
10342 }
10343 
10344 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
10345 {
10346    struct zt_pvt *p = NULL;
10347    const char *channel = astman_get_header(m, "ZapChannel");
10348    const char *number = astman_get_header(m, "Number");
10349    int i;
10350 
10351    if (ast_strlen_zero(channel)) {
10352       astman_send_error(s, m, "No channel specified");
10353       return 0;
10354    }
10355    if (ast_strlen_zero(number)) {
10356       astman_send_error(s, m, "No number specified");
10357       return 0;
10358    }
10359    p = find_channel(atoi(channel));
10360    if (!p) {
10361       astman_send_error(s, m, "No such channel");
10362       return 0;
10363    }
10364    if (!p->owner) {
10365       astman_send_error(s, m, "Channel does not have it's owner");
10366       return 0;
10367    }
10368    for (i = 0; i < strlen(number); i++) {
10369       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
10370       zap_queue_frame(p, &f, NULL); 
10371    }
10372    astman_send_ack(s, m, "ZapDialOffhook");
10373    return 0;
10374 }
10375 
10376 static int action_zapshowchannels(struct mansession *s, const struct message *m)
10377 {
10378    struct zt_pvt *tmp = NULL;
10379    const char *id = astman_get_header(m, "ActionID");
10380    char idText[256] = "";
10381 
10382    astman_send_ack(s, m, "Zapata channel status will follow");
10383    if (!ast_strlen_zero(id))
10384       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
10385 
10386    ast_mutex_lock(&iflock);
10387    
10388    tmp = iflist;
10389    while (tmp) {
10390       if (tmp->channel > 0) {
10391          int alarm = get_alarms(tmp);
10392          astman_append(s,
10393             "Event: ZapShowChannels\r\n"
10394             "Channel: %d\r\n"
10395             "Signalling: %s\r\n"
10396             "Context: %s\r\n"
10397             "DND: %s\r\n"
10398             "Alarm: %s\r\n"
10399             "%s"
10400             "\r\n",
10401             tmp->channel, sig2str(tmp->sig), tmp->context, 
10402             tmp->dnd ? "Enabled" : "Disabled",
10403             alarm2str(alarm), idText);
10404       } 
10405 
10406       tmp = tmp->next;
10407    }
10408 
10409    ast_mutex_unlock(&iflock);
10410    
10411    astman_append(s, 
10412       "Event: ZapShowChannelsComplete\r\n"
10413       "%s"
10414       "\r\n", 
10415       idText);
10416    return 0;
10417 }
10418 
10419 static int __unload_module(void)
10420 {
10421    int x;
10422    struct zt_pvt *p, *pl;
10423 
10424 #ifdef HAVE_PRI
10425    int i;
10426    for (i = 0; i < NUM_SPANS; i++) {
10427       if (pris[i].master != AST_PTHREADT_NULL) 
10428          pthread_cancel(pris[i].master);
10429    }
10430    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
10431    ast_unregister_application(zap_send_keypad_facility_app);
10432 #endif
10433    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
10434    ast_manager_unregister( "ZapDialOffhook" );
10435    ast_manager_unregister( "ZapHangup" );
10436    ast_manager_unregister( "ZapTransfer" );
10437    ast_manager_unregister( "ZapDNDoff" );
10438    ast_manager_unregister( "ZapDNDon" );
10439    ast_manager_unregister("ZapShowChannels");
10440    ast_manager_unregister("ZapRestart");
10441    ast_channel_unregister(&zap_tech);
10442    ast_mutex_lock(&iflock);
10443    /* Hangup all interfaces if they have an owner */
10444    p = iflist;
10445    while (p) {
10446       if (p->owner)
10447          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
10448       p = p->next;
10449    }
10450    ast_mutex_unlock(&iflock);
10451    ast_mutex_lock(&monlock);
10452    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
10453       pthread_cancel(monitor_thread);
10454       pthread_kill(monitor_thread, SIGURG);
10455       pthread_join(monitor_thread, NULL);
10456    }
10457    monitor_thread = AST_PTHREADT_STOP;
10458    ast_mutex_unlock(&monlock);
10459 
10460    ast_mutex_lock(&iflock);
10461    /* Destroy all the interfaces and free their memory */
10462    p = iflist;
10463    while (p) {
10464       /* Free any callerid */
10465       if (p->cidspill)
10466          free(p->cidspill);
10467       /* Close the zapata thingy */
10468       if (p->subs[SUB_REAL].zfd > -1)
10469          zt_close(p->subs[SUB_REAL].zfd);
10470       pl = p;
10471       p = p->next;
10472       x = pl->channel;
10473       /* Free associated memory */
10474       if (pl)
10475          destroy_zt_pvt(&pl);
10476       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
10477    }
10478    iflist = NULL;
10479    ifcount = 0;
10480    ast_mutex_unlock(&iflock);
10481 #ifdef HAVE_PRI      
10482    for (i = 0; i < NUM_SPANS; i++) {
10483       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
10484          pthread_join(pris[i].master, NULL);
10485       zt_close(pris[i].fds[i]);
10486    }
10487 #endif
10488    return 0;
10489 }
10490 
10491 static int unload_module(void)
10492 {
10493 #ifdef HAVE_PRI      
10494    int y;
10495    for (y = 0; y < NUM_SPANS; y++)
10496       ast_mutex_destroy(&pris[y].lock);
10497 #endif
10498    return __unload_module();
10499 }
10500 
10501 static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
10502 {
10503    char *c, *chan;
10504    int x, start, finish;
10505    struct zt_pvt *tmp;
10506 #ifdef HAVE_PRI
10507    struct zt_pri *pri;
10508    int trunkgroup, y;
10509 #endif
10510    
10511    if ((reload == 0) && (conf.chan.sig < 0)) {
10512       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
10513       return -1;
10514    }
10515 
10516    c = ast_strdupa(value);
10517 
10518 #ifdef HAVE_PRI
10519    pri = NULL;
10520    if (iscrv) {
10521       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
10522          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
10523          return -1;
10524       }
10525       if (trunkgroup < 1) {
10526          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
10527          return -1;
10528       }
10529       c += y;
10530       for (y = 0; y < NUM_SPANS; y++) {
10531          if (pris[y].trunkgroup == trunkgroup) {
10532             pri = pris + y;
10533             break;
10534          }
10535       }
10536       if (!pri) {
10537          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
10538          return -1;
10539       }
10540    }
10541 #endif         
10542 
10543    while ((chan = strsep(&c, ","))) {
10544       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
10545          /* Range */
10546       } else if (sscanf(chan, "%d", &start)) {
10547          /* Just one */
10548          finish = start;
10549       } else if (!strcasecmp(chan, "pseudo")) {
10550          finish = start = CHAN_PSEUDO;
10551          if (found_pseudo)
10552             *found_pseudo = 1;
10553       } else {
10554          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
10555          return -1;
10556       }
10557       if (finish < start) {
10558          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
10559          x = finish;
10560          finish = start;
10561          start = x;
10562       }
10563 
10564       for (x = start; x <= finish; x++) {
10565 #ifdef HAVE_PRI
10566          tmp = mkintf(x, conf, pri, reload);
10567 #else       
10568          tmp = mkintf(x, conf, NULL, reload);
10569 #endif         
10570 
10571          if (tmp) {
10572             if (option_verbose > 2) {
10573 #ifdef HAVE_PRI
10574                if (pri)
10575                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
10576                else
10577 #endif
10578                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
10579             }
10580          } else {
10581             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
10582                (reload == 1) ? "reconfigure" : "register", value);
10583             return -1;
10584          }
10585       }
10586    }
10587 
10588    return 0;
10589 }
10590 
10591 /** The length of the parameters list of 'zapchan'. 
10592  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10593 #define MAX_CHANLIST_LEN 80
10594 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
10595 {
10596    struct zt_pvt *tmp;
10597    char *ringc; /* temporary string for parsing the dring number. */
10598    int y;
10599    int found_pseudo = 0;
10600         char zapchan[MAX_CHANLIST_LEN] = {};
10601 
10602    for (; v; v = v->next) {
10603       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
10604          continue;
10605 
10606       /* Create the interface list */
10607       if (!strcasecmp(v->name, "channel")
10608 #ifdef HAVE_PRI
10609           || !strcasecmp(v->name, "crv")
10610 #endif         
10611          ) {
10612          int iscrv;
10613          if (skipchannels)
10614             continue;
10615          iscrv = !strcasecmp(v->name, "crv");
10616          if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
10617                return -1;
10618       } else if (!strcasecmp(v->name, "zapchan")) {
10619          ast_copy_string(zapchan, v->value, sizeof(zapchan));
10620       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
10621          if (ast_true(v->value))
10622             confp->chan.usedistinctiveringdetection = 1;
10623       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
10624          if (ast_true(v->value))
10625             distinctiveringaftercid = 1;
10626       } else if (!strcasecmp(v->name, "dring1context")) {
10627          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
10628       } else if (!strcasecmp(v->name, "dring2context")) {
10629          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
10630       } else if (!strcasecmp(v->name, "dring3context")) {
10631          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
10632       } else if (!strcasecmp(v->name, "dring1")) {
10633          ringc = v->value;
10634          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
10635       } else if (!strcasecmp(v->name, "dring2")) {
10636          ringc = v->value;
10637          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
10638       } else if (!strcasecmp(v->name, "dring3")) {
10639          ringc = v->value;
10640          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
10641       } else if (!strcasecmp(v->name, "usecallerid")) {
10642          confp->chan.use_callerid = ast_true(v->value);
10643       } else if (!strcasecmp(v->name, "cidsignalling")) {
10644          if (!strcasecmp(v->value, "bell"))
10645             confp->chan.cid_signalling = CID_SIG_BELL;
10646          else if (!strcasecmp(v->value, "v23"))
10647             confp->chan.cid_signalling = CID_SIG_V23;
10648          else if (!strcasecmp(v->value, "dtmf"))
10649             confp->chan.cid_signalling = CID_SIG_DTMF;
10650          else if (!strcasecmp(v->value, "smdi"))
10651             confp->chan.cid_signalling = CID_SIG_SMDI;
10652          else if (!strcasecmp(v->value, "v23_jp"))
10653             confp->chan.cid_signalling = CID_SIG_V23_JP;
10654          else if (ast_true(v->value))
10655             confp->chan.cid_signalling = CID_SIG_BELL;
10656       } else if (!strcasecmp(v->name, "cidstart")) {
10657          if (!strcasecmp(v->value, "ring"))
10658             confp->chan.cid_start = CID_START_RING;
10659          else if (!strcasecmp(v->value, "polarity"))
10660             confp->chan.cid_start = CID_START_POLARITY;
10661          else if (ast_true(v->value))
10662             confp->chan.cid_start = CID_START_RING;
10663       } else if (!strcasecmp(v->name, "threewaycalling")) {
10664          confp->chan.threewaycalling = ast_true(v->value);
10665       } else if (!strcasecmp(v->name, "cancallforward")) {
10666          confp->chan.cancallforward = ast_true(v->value);
10667       } else if (!strcasecmp(v->name, "relaxdtmf")) {
10668          if (ast_true(v->value)) 
10669             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
10670          else
10671             confp->chan.dtmfrelax = 0;
10672       } else if (!strcasecmp(v->name, "mailbox")) {
10673          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
10674       } else if (!strcasecmp(v->name, "adsi")) {
10675          confp->chan.adsi = ast_true(v->value);
10676       } else if (!strcasecmp(v->name, "usesmdi")) {
10677          confp->chan.use_smdi = ast_true(v->value);
10678       } else if (!strcasecmp(v->name, "smdiport")) {
10679          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
10680       } else if (!strcasecmp(v->name, "transfer")) {
10681          confp->chan.transfer = ast_true(v->value);
10682       } else if (!strcasecmp(v->name, "canpark")) {
10683          confp->chan.canpark = ast_true(v->value);
10684       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
10685          confp->chan.echocanbridged = ast_true(v->value);
10686       } else if (!strcasecmp(v->name, "busydetect")) {
10687          confp->chan.busydetect = ast_true(v->value);
10688       } else if (!strcasecmp(v->name, "busycount")) {
10689          confp->chan.busycount = atoi(v->value);
10690       } else if (!strcasecmp(v->name, "busypattern")) {
10691          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
10692             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
10693          }
10694       } else if (!strcasecmp(v->name, "callprogress")) {
10695          if (ast_true(v->value))
10696             confp->chan.callprogress |= 1;
10697          else
10698             confp->chan.callprogress &= ~1;
10699       } else if (!strcasecmp(v->name, "faxdetect")) {
10700          if (!strcasecmp(v->value, "incoming")) {
10701             confp->chan.callprogress |= 4;
10702             confp->chan.callprogress &= ~2;
10703          } else if (!strcasecmp(v->value, "outgoing")) {
10704             confp->chan.callprogress &= ~4;
10705             confp->chan.callprogress |= 2;
10706          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
10707             confp->chan.callprogress |= 6;
10708          else
10709             confp->chan.callprogress &= ~6;
10710       } else if (!strcasecmp(v->name, "echocancel")) {
10711          if (!ast_strlen_zero(v->value)) {
10712             y = atoi(v->value);
10713          } else
10714             y = 0;
10715          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
10716             confp->chan.echocancel = y;
10717          else {
10718             confp->chan.echocancel = ast_true(v->value);
10719             if (confp->chan.echocancel)
10720                confp->chan.echocancel=128;
10721          }
10722       } else if (!strcasecmp(v->name, "echotraining")) {
10723          if (sscanf(v->value, "%d", &y) == 1) {
10724             if ((y < 10) || (y > 4000)) {
10725                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
10726             } else {
10727                confp->chan.echotraining = y;
10728             }
10729          } else if (ast_true(v->value)) {
10730             confp->chan.echotraining = 400;
10731          } else
10732             confp->chan.echotraining = 0;
10733       } else if (!strcasecmp(v->name, "hidecallerid")) {
10734          confp->chan.hidecallerid = ast_true(v->value);
10735       } else if (!strcasecmp(v->name, "hidecalleridname")) {
10736          confp->chan.hidecalleridname = ast_true(v->value);
10737       } else if (!strcasecmp(v->name, "pulsedial")) {
10738          confp->chan.pulse = ast_true(v->value);
10739       } else if (!strcasecmp(v->name, "callreturn")) {
10740          confp->chan.callreturn = ast_true(v->value);
10741       } else if (!strcasecmp(v->name, "callwaiting")) {
10742          confp->chan.callwaiting = ast_true(v->value);
10743       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
10744          confp->chan.callwaitingcallerid = ast_true(v->value);
10745       } else if (!strcasecmp(v->name, "context")) {
10746          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
10747       } else if (!strcasecmp(v->name, "language")) {
10748          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
10749       } else if (!strcasecmp(v->name, "progzone")) {
10750          ast_copy_string(progzone, v->value, sizeof(progzone));
10751       } else if (!strcasecmp(v->name, "mohinterpret") 
10752          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
10753          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
10754       } else if (!strcasecmp(v->name, "mohsuggest")) {
10755          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
10756       } else if (!strcasecmp(v->name, "stripmsd")) {
10757          confp->chan.stripmsd = atoi(v->value);
10758       } else if (!strcasecmp(v->name, "jitterbuffers")) {
10759          numbufs = atoi(v->value);
10760       } else if (!strcasecmp(v->name, "group")) {
10761          confp->chan.group = ast_get_group(v->value);
10762       } else if (!strcasecmp(v->name, "callgroup")) {
10763          confp->chan.callgroup = ast_get_group(v->value);
10764       } else if (!strcasecmp(v->name, "pickupgroup")) {
10765          confp->chan.pickupgroup = ast_get_group(v->value);
10766       } else if (!strcasecmp(v->name, "immediate")) {
10767          confp->chan.immediate = ast_true(v->value);
10768       } else if (!strcasecmp(v->name, "transfertobusy")) {
10769          confp->chan.transfertobusy = ast_true(v->value);
10770       } else if (!strcasecmp(v->name, "rxgain")) {
10771          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
10772             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
10773          }
10774       } else if (!strcasecmp(v->name, "txgain")) {
10775          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
10776             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
10777          }
10778       } else if (!strcasecmp(v->name, "tonezone")) {
10779          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
10780             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
10781          }
10782       } else if (!strcasecmp(v->name, "callerid")) {
10783          if (!strcasecmp(v->value, "asreceived")) {
10784             confp->chan.cid_num[0] = '\0';
10785             confp->chan.cid_name[0] = '\0';
10786          } else {
10787             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
10788          } 
10789       } else if (!strcasecmp(v->name, "fullname")) {
10790          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
10791       } else if (!strcasecmp(v->name, "cid_number")) {
10792          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
10793       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
10794          confp->chan.zaptrcallerid = ast_true(v->value);
10795       } else if (!strcasecmp(v->name, "restrictcid")) {
10796          confp->chan.restrictcid = ast_true(v->value);
10797       } else if (!strcasecmp(v->name, "usecallingpres")) {
10798          confp->chan.use_callingpres = ast_true(v->value);
10799       } else if (!strcasecmp(v->name, "accountcode")) {
10800          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
10801       } else if (!strcasecmp(v->name, "amaflags")) {
10802          y = ast_cdr_amaflags2int(v->value);
10803          if (y < 0) 
10804             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
10805          else
10806             confp->chan.amaflags = y;
10807       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
10808          confp->chan.polarityonanswerdelay = atoi(v->value);
10809       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
10810          confp->chan.answeronpolarityswitch = ast_true(v->value);
10811       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
10812          confp->chan.hanguponpolarityswitch = ast_true(v->value);
10813       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
10814          confp->chan.sendcalleridafter = atoi(v->value);
10815       } else if (!reload){ 
10816           if (!strcasecmp(v->name, "signalling")) {
10817             confp->chan.outsigmod = -1;
10818             if (!strcasecmp(v->value, "em")) {
10819                confp->chan.sig = SIG_EM;
10820             } else if (!strcasecmp(v->value, "em_e1")) {
10821                confp->chan.sig = SIG_EM_E1;
10822             } else if (!strcasecmp(v->value, "em_w")) {
10823                confp->chan.sig = SIG_EMWINK;
10824                confp->chan.radio = 0;
10825             } else if (!strcasecmp(v->value, "fxs_ls")) {
10826                confp->chan.sig = SIG_FXSLS;
10827                confp->chan.radio = 0;
10828             } else if (!strcasecmp(v->value, "fxs_gs")) {
10829                confp->chan.sig = SIG_FXSGS;
10830                confp->chan.radio = 0;
10831             } else if (!strcasecmp(v->value, "fxs_ks")) {
10832                confp->chan.sig = SIG_FXSKS;
10833                confp->chan.radio = 0;
10834             } else if (!strcasecmp(v->value, "fxo_ls")) {
10835                confp->chan.sig = SIG_FXOLS;
10836                confp->chan.radio = 0;
10837             } else if (!strcasecmp(v->value, "fxo_gs")) {
10838                confp->chan.sig = SIG_FXOGS;
10839                confp->chan.radio = 0;
10840             } else if (!strcasecmp(v->value, "fxo_ks")) {
10841                confp->chan.sig = SIG_FXOKS;
10842                confp->chan.radio = 0;
10843             } else if (!strcasecmp(v->value, "fxs_rx")) {
10844                confp->chan.sig = SIG_FXSKS;
10845                confp->chan.radio = 1;
10846             } else if (!strcasecmp(v->value, "fxo_rx")) {
10847                confp->chan.sig = SIG_FXOLS;
10848                confp->chan.radio = 1;
10849             } else if (!strcasecmp(v->value, "fxs_tx")) {
10850                confp->chan.sig = SIG_FXSLS;
10851                confp->chan.radio = 1;
10852             } else if (!strcasecmp(v->value, "fxo_tx")) {
10853                confp->chan.sig = SIG_FXOGS;
10854                confp->chan.radio = 1;
10855             } else if (!strcasecmp(v->value, "em_rx")) {
10856                confp->chan.sig = SIG_EM;
10857                confp->chan.radio = 1;
10858             } else if (!strcasecmp(v->value, "em_tx")) {
10859                confp->chan.sig = SIG_EM;
10860                confp->chan.radio = 1;
10861             } else if (!strcasecmp(v->value, "em_rxtx")) {
10862                confp->chan.sig = SIG_EM;
10863                confp->chan.radio = 2;
10864             } else if (!strcasecmp(v->value, "em_txrx")) {
10865                confp->chan.sig = SIG_EM;
10866                confp->chan.radio = 2;
10867             } else if (!strcasecmp(v->value, "sf")) {
10868                confp->chan.sig = SIG_SF;
10869                confp->chan.radio = 0;
10870             } else if (!strcasecmp(v->value, "sf_w")) {
10871                confp->chan.sig = SIG_SFWINK;
10872                confp->chan.radio = 0;
10873             } else if (!strcasecmp(v->value, "sf_featd")) {
10874                confp->chan.sig = SIG_FEATD;
10875                confp->chan.radio = 0;
10876             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10877                confp->chan.sig = SIG_FEATDMF;
10878                confp->chan.radio = 0;
10879             } else if (!strcasecmp(v->value, "sf_featb")) {
10880                confp->chan.sig = SIG_SF_FEATB;
10881                confp->chan.radio = 0;
10882             } else if (!strcasecmp(v->value, "sf")) {
10883                confp->chan.sig = SIG_SF;
10884                confp->chan.radio = 0;
10885             } else if (!strcasecmp(v->value, "sf_rx")) {
10886                confp->chan.sig = SIG_SF;
10887                confp->chan.radio = 1;
10888             } else if (!strcasecmp(v->value, "sf_tx")) {
10889                confp->chan.sig = SIG_SF;
10890                confp->chan.radio = 1;
10891             } else if (!strcasecmp(v->value, "sf_rxtx")) {
10892                confp->chan.sig = SIG_SF;
10893                confp->chan.radio = 2;
10894             } else if (!strcasecmp(v->value, "sf_txrx")) {
10895                confp->chan.sig = SIG_SF;
10896                confp->chan.radio = 2;
10897             } else if (!strcasecmp(v->value, "featd")) {
10898                confp->chan.sig = SIG_FEATD;
10899                confp->chan.radio = 0;
10900             } else if (!strcasecmp(v->value, "featdmf")) {
10901                confp->chan.sig = SIG_FEATDMF;
10902                confp->chan.radio = 0;
10903             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10904                confp->chan.sig = SIG_FEATDMF_TA;
10905                confp->chan.radio = 0;
10906             } else if (!strcasecmp(v->value, "e911")) {
10907                confp->chan.sig = SIG_E911;
10908                confp->chan.radio = 0;
10909             } else if (!strcasecmp(v->value, "fgccama")) {
10910                confp->chan.sig = SIG_FGC_CAMA;
10911                confp->chan.radio = 0;
10912             } else if (!strcasecmp(v->value, "fgccamamf")) {
10913                confp->chan.sig = SIG_FGC_CAMAMF;
10914                confp->chan.radio = 0;
10915             } else if (!strcasecmp(v->value, "featb")) {
10916                confp->chan.sig = SIG_FEATB;
10917                confp->chan.radio = 0;
10918 #ifdef HAVE_PRI
10919             } else if (!strcasecmp(v->value, "pri_net")) {
10920                confp->chan.radio = 0;
10921                confp->chan.sig = SIG_PRI;
10922                confp->pri.nodetype = PRI_NETWORK;
10923             } else if (!strcasecmp(v->value, "pri_cpe")) {
10924                confp->chan.sig = SIG_PRI;
10925                confp->chan.radio = 0;
10926                confp->pri.nodetype = PRI_CPE;
10927             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
10928                confp->chan.sig = SIG_GR303FXOKS;
10929                confp->chan.radio = 0;
10930                confp->pri.nodetype = PRI_NETWORK;
10931             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
10932                confp->chan.sig = SIG_GR303FXSKS;
10933                confp->chan.radio = 0;
10934                confp->pri.nodetype = PRI_CPE;
10935 #endif
10936             } else {
10937                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10938             }
10939           } else if (!strcasecmp(v->name, "outsignalling")) {
10940             if (!strcasecmp(v->value, "em")) {
10941                confp->chan.outsigmod = SIG_EM;
10942             } else if (!strcasecmp(v->value, "em_e1")) {
10943                confp->chan.outsigmod = SIG_EM_E1;
10944             } else if (!strcasecmp(v->value, "em_w")) {
10945                confp->chan.outsigmod = SIG_EMWINK;
10946             } else if (!strcasecmp(v->value, "sf")) {
10947                confp->chan.outsigmod = SIG_SF;
10948             } else if (!strcasecmp(v->value, "sf_w")) {
10949                confp->chan.outsigmod = SIG_SFWINK;
10950             } else if (!strcasecmp(v->value, "sf_featd")) {
10951                confp->chan.outsigmod = SIG_FEATD;
10952             } else if (!strcasecmp(v->value, "sf_featdmf")) {
10953                confp->chan.outsigmod = SIG_FEATDMF;
10954             } else if (!strcasecmp(v->value, "sf_featb")) {
10955                confp->chan.outsigmod = SIG_SF_FEATB;
10956             } else if (!strcasecmp(v->value, "sf")) {
10957                confp->chan.outsigmod = SIG_SF;
10958             } else if (!strcasecmp(v->value, "featd")) {
10959                confp->chan.outsigmod = SIG_FEATD;
10960             } else if (!strcasecmp(v->value, "featdmf")) {
10961                confp->chan.outsigmod = SIG_FEATDMF;
10962             } else if (!strcasecmp(v->value, "featdmf_ta")) {
10963                confp->chan.outsigmod = SIG_FEATDMF_TA;
10964             } else if (!strcasecmp(v->value, "e911")) {
10965                confp->chan.outsigmod = SIG_E911;
10966             } else if (!strcasecmp(v->value, "fgccama")) {
10967                confp->chan.outsigmod = SIG_FGC_CAMA;
10968             } else if (!strcasecmp(v->value, "fgccamamf")) {
10969                confp->chan.outsigmod = SIG_FGC_CAMAMF;
10970             } else if (!strcasecmp(v->value, "featb")) {
10971                confp->chan.outsigmod = SIG_FEATB;
10972             } else {
10973                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
10974             }
10975 #ifdef HAVE_PRI
10976          } else if (!strcasecmp(v->name, "pridialplan")) {
10977             if (!strcasecmp(v->value, "national")) {
10978                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
10979             } else if (!strcasecmp(v->value, "unknown")) {
10980                confp->pri.dialplan = PRI_UNKNOWN + 1;
10981             } else if (!strcasecmp(v->value, "private")) {
10982                confp->pri.dialplan = PRI_PRIVATE + 1;
10983             } else if (!strcasecmp(v->value, "international")) {
10984                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
10985             } else if (!strcasecmp(v->value, "local")) {
10986                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
10987             } else if (!strcasecmp(v->value, "dynamic")) {
10988                confp->pri.dialplan = -1;
10989             } else {
10990                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
10991             }
10992          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
10993             if (!strcasecmp(v->value, "national")) {
10994                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
10995             } else if (!strcasecmp(v->value, "unknown")) {
10996                confp->pri.localdialplan = PRI_UNKNOWN + 1;
10997             } else if (!strcasecmp(v->value, "private")) {
10998                confp->pri.localdialplan = PRI_PRIVATE + 1;
10999             } else if (!strcasecmp(v->value, "international")) {
11000                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
11001             } else if (!strcasecmp(v->value, "local")) {
11002                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
11003             } else if (!strcasecmp(v->value, "dynamic")) {
11004                confp->pri.localdialplan = -1;
11005             } else {
11006                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
11007             }
11008          } else if (!strcasecmp(v->name, "switchtype")) {
11009             if (!strcasecmp(v->value, "national")) 
11010                confp->pri.switchtype = PRI_SWITCH_NI2;
11011             else if (!strcasecmp(v->value, "ni1"))
11012                confp->pri.switchtype = PRI_SWITCH_NI1;
11013             else if (!strcasecmp(v->value, "dms100"))
11014                confp->pri.switchtype = PRI_SWITCH_DMS100;
11015             else if (!strcasecmp(v->value, "4ess"))
11016                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
11017             else if (!strcasecmp(v->value, "5ess"))
11018                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
11019             else if (!strcasecmp(v->value, "euroisdn"))
11020                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
11021             else if (!strcasecmp(v->value, "qsig"))
11022                confp->pri.switchtype = PRI_SWITCH_QSIG;
11023             else {
11024                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
11025                return -1;
11026             }
11027          } else if (!strcasecmp(v->name, "nsf")) {
11028             if (!strcasecmp(v->value, "sdn"))
11029                confp->pri.nsf = PRI_NSF_SDN;
11030             else if (!strcasecmp(v->value, "megacom"))
11031                confp->pri.nsf = PRI_NSF_MEGACOM;
11032             else if (!strcasecmp(v->value, "tollfreemegacom"))
11033                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
11034             else if (!strcasecmp(v->value, "accunet"))
11035                confp->pri.nsf = PRI_NSF_ACCUNET;
11036             else if (!strcasecmp(v->value, "none"))
11037                confp->pri.nsf = PRI_NSF_NONE;
11038             else {
11039                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
11040                confp->pri.nsf = PRI_NSF_NONE;
11041             }
11042          } else if (!strcasecmp(v->name, "priindication")) {
11043             if (!strcasecmp(v->value, "outofband"))
11044                confp->chan.priindication_oob = 1;
11045             else if (!strcasecmp(v->value, "inband"))
11046                confp->chan.priindication_oob = 0;
11047             else
11048                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
11049                   v->value, v->lineno);
11050          } else if (!strcasecmp(v->name, "priexclusive")) {
11051             confp->chan.priexclusive = ast_true(v->value);
11052          } else if (!strcasecmp(v->name, "internationalprefix")) {
11053             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
11054          } else if (!strcasecmp(v->name, "nationalprefix")) {
11055             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
11056          } else if (!strcasecmp(v->name, "localprefix")) {
11057             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
11058          } else if (!strcasecmp(v->name, "privateprefix")) {
11059             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
11060          } else if (!strcasecmp(v->name, "unknownprefix")) {
11061             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
11062          } else if (!strcasecmp(v->name, "resetinterval")) {
11063             if (!strcasecmp(v->value, "never"))
11064                confp->pri.resetinterval = -1;
11065             else if (atoi(v->value) >= 60)
11066                confp->pri.resetinterval = atoi(v->value);
11067             else
11068                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
11069                   v->value, v->lineno);
11070          } else if (!strcasecmp(v->name, "minunused")) {
11071             confp->pri.minunused = atoi(v->value);
11072          } else if (!strcasecmp(v->name, "minidle")) {
11073             confp->pri.minidle = atoi(v->value); 
11074          } else if (!strcasecmp(v->name, "idleext")) {
11075             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
11076          } else if (!strcasecmp(v->name, "idledial")) {
11077             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
11078          } else if (!strcasecmp(v->name, "overlapdial")) {
11079             confp->pri.overlapdial = ast_true(v->value);
11080          } else if (!strcasecmp(v->name, "pritimer")) {
11081 #ifdef PRI_GETSET_TIMERS
11082             char *timerc, *c;
11083             int timer, timeridx;
11084             c = v->value;
11085             timerc = strsep(&c, ",");
11086             if (timerc) {
11087                timer = atoi(c);
11088                if (!timer)
11089                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
11090                else {
11091                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
11092                      pritimers[timeridx] = timer;
11093                   else
11094                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
11095                }
11096             } else
11097                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
11098 
11099          } else if (!strcasecmp(v->name, "facilityenable")) {
11100             confp->pri.facilityenable = ast_true(v->value);
11101 #endif /* PRI_GETSET_TIMERS */
11102 #endif /* HAVE_PRI */
11103          } else if (!strcasecmp(v->name, "cadence")) {
11104             /* setup to scan our argument */
11105             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
11106             int i;
11107             struct zt_ring_cadence new_cadence;
11108             int cid_location = -1;
11109             int firstcadencepos = 0;
11110             char original_args[80];
11111             int cadence_is_ok = 1;
11112 
11113             ast_copy_string(original_args, v->value, sizeof(original_args));
11114             /* 16 cadences allowed (8 pairs) */
11115             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]);
11116    
11117             /* Cadence must be even (on/off) */
11118             if (element_count % 2 == 1) {
11119                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
11120                cadence_is_ok = 0;
11121             }
11122    
11123             /* Ring cadences cannot be negative */
11124             for (i = 0; i < element_count; i++) {
11125                if (c[i] == 0) {
11126                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
11127                   cadence_is_ok = 0;
11128                   break;
11129                } else if (c[i] < 0) {
11130                   if (i % 2 == 1) {
11131                      /* Silence duration, negative possibly okay */
11132                      if (cid_location == -1) {
11133                         cid_location = i;
11134                         c[i] *= -1;
11135                      } else {
11136                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
11137                         cadence_is_ok = 0;
11138                         break;
11139                      }
11140                   } else {
11141                      if (firstcadencepos == 0) {
11142                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
11143                                  /* duration will be passed negative to the zaptel driver */
11144                      } else {
11145                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
11146                         cadence_is_ok = 0;
11147                         break;
11148                      }
11149                   }
11150                }
11151             }
11152    
11153             /* Substitute our scanned cadence */
11154             for (i = 0; i < 16; i++) {
11155                new_cadence.ringcadence[i] = c[i];
11156             }
11157    
11158             if (cadence_is_ok) {
11159                /* ---we scanned it without getting annoyed; now some sanity checks--- */
11160                if (element_count < 2) {
11161                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
11162                } else {
11163                   if (cid_location == -1) {
11164                      /* user didn't say; default to first pause */
11165                      cid_location = 1;
11166                   } else {
11167                      /* convert element_index to cidrings value */
11168                      cid_location = (cid_location + 1) / 2;
11169                   }
11170                   /* ---we like their cadence; try to install it--- */
11171                   if (!user_has_defined_cadences++)
11172                      /* this is the first user-defined cadence; clear the default user cadences */
11173                      num_cadence = 0;
11174                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
11175                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
11176                   else {
11177                      cadences[num_cadence] = new_cadence;
11178                      cidrings[num_cadence++] = cid_location;
11179                      if (option_verbose > 2)
11180                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
11181                   }
11182                }
11183             }
11184          } else if (!strcasecmp(v->name, "ringtimeout")) {
11185             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
11186          } else if (!strcasecmp(v->name, "prewink")) {
11187             confp->timing.prewinktime = atoi(v->value);
11188          } else if (!strcasecmp(v->name, "preflash")) {
11189             confp->timing.preflashtime = atoi(v->value);
11190          } else if (!strcasecmp(v->name, "wink")) {
11191             confp->timing.winktime = atoi(v->value);
11192          } else if (!strcasecmp(v->name, "flash")) {
11193             confp->timing.flashtime = atoi(v->value);
11194          } else if (!strcasecmp(v->name, "start")) {
11195             confp->timing.starttime = atoi(v->value);
11196          } else if (!strcasecmp(v->name, "rxwink")) {
11197             confp->timing.rxwinktime = atoi(v->value);
11198          } else if (!strcasecmp(v->name, "rxflash")) {
11199             confp->timing.rxflashtime = atoi(v->value);
11200          } else if (!strcasecmp(v->name, "debounce")) {
11201             confp->timing.debouncetime = atoi(v->value);
11202          } else if (!strcasecmp(v->name, "toneduration")) {
11203             int toneduration;
11204             int ctlfd;
11205             int res;
11206             struct zt_dialparams dps;
11207 
11208             ctlfd = open("/dev/zap/ctl", O_RDWR);
11209             if (ctlfd == -1) {
11210                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
11211                return -1;
11212             }
11213 
11214             toneduration = atoi(v->value);
11215             if (toneduration > -1) {
11216                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
11217                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
11218                if (res < 0) {
11219                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
11220                   return -1;
11221                }
11222             }
11223             close(ctlfd);
11224          } else if (!strcasecmp(v->name, "defaultcic")) {
11225             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
11226          } else if (!strcasecmp(v->name, "defaultozz")) {
11227             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
11228          } 
11229       } else if (!skipchannels)
11230          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
11231    }
11232    if (zapchan[0]) { 
11233       /* The user has set 'zapchan' */
11234       /*< \todo pass proper line number instead of 0 */
11235       if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
11236          return -1;
11237       }
11238    }
11239    /*< \todo why check for the pseudo in the per-channel section.
11240     * Any actual use for manual setup of the pseudo channel? */
11241    if (!found_pseudo && reload == 0) {
11242       /* Make sure pseudo isn't a member of any groups if
11243          we're automatically making it. */   
11244       
11245       confp->chan.group = 0;
11246       confp->chan.callgroup = 0;
11247       confp->chan.pickupgroup = 0;
11248 
11249       tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
11250 
11251       if (tmp) {
11252          if (option_verbose > 2)
11253             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
11254       } else {
11255          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
11256       }
11257    }
11258    return 0;
11259 }
11260       
11261 static int setup_zap(int reload)
11262 {
11263    struct ast_config *cfg;
11264    struct ast_variable *v;
11265    struct zt_chan_conf conf = zt_chan_conf_default();
11266    int res;
11267 
11268 #ifdef HAVE_PRI
11269    char *c;
11270    int spanno;
11271    int i, x;
11272    int logicalspan;
11273    int trunkgroup;
11274    int dchannels[NUM_DCHANS];
11275 #endif
11276 
11277    cfg = ast_config_load(config);
11278 
11279    /* Error if we have no config file */
11280    if (!cfg) {
11281       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
11282       return 0;
11283    }
11284 
11285    /* It's a little silly to lock it, but we mind as well just to be sure */
11286    ast_mutex_lock(&iflock);
11287 #ifdef HAVE_PRI
11288    if (!reload) {
11289       /* Process trunkgroups first */
11290       v = ast_variable_browse(cfg, "trunkgroups");
11291       while (v) {
11292          if (!strcasecmp(v->name, "trunkgroup")) {
11293             trunkgroup = atoi(v->value);
11294             if (trunkgroup > 0) {
11295                if ((c = strchr(v->value, ','))) {
11296                   i = 0;
11297                   memset(dchannels, 0, sizeof(dchannels));
11298                   while (c && (i < NUM_DCHANS)) {
11299                      dchannels[i] = atoi(c + 1);
11300                      if (dchannels[i] < 0) {
11301                         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);
11302                      } else
11303                         i++;
11304                      c = strchr(c + 1, ',');
11305                   }
11306                   if (i) {
11307                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
11308                         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);
11309                      } else if (option_verbose > 1)
11310                         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");
11311                   } else
11312                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
11313                } else
11314                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
11315             } else
11316                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
11317          } else if (!strcasecmp(v->name, "spanmap")) {
11318             spanno = atoi(v->value);
11319             if (spanno > 0) {
11320                if ((c = strchr(v->value, ','))) {
11321                   trunkgroup = atoi(c + 1);
11322                   if (trunkgroup > 0) {
11323                      if ((c = strchr(c + 1, ','))) 
11324                         logicalspan = atoi(c + 1);
11325                      else
11326                         logicalspan = 0;
11327                      if (logicalspan >= 0) {
11328                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
11329                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11330                         } else if (option_verbose > 1) 
11331                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
11332                      } else
11333                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
11334                   } else
11335                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
11336                } else
11337                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
11338             } else
11339                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
11340          } else {
11341             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
11342          }
11343          v = v->next;
11344       }
11345    }
11346 #endif
11347    
11348    /* Copy the default jb config over global_jbconf */
11349    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
11350 
11351    v = ast_variable_browse(cfg, "channels");
11352    res = process_zap(&conf, v, reload, 0);
11353    ast_mutex_unlock(&iflock);
11354    ast_config_destroy(cfg);
11355    if (res)
11356       return res;
11357    cfg = ast_config_load("users.conf");
11358    if (cfg) {
11359       char *cat;
11360       const char *chans;
11361       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
11362       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
11363          if (!strcasecmp(cat, "general"))
11364             continue;
11365          chans = ast_variable_retrieve(cfg, cat, "zapchan");
11366          if (!ast_strlen_zero(chans)) {
11367             /** \todo At this point we should probably 
11368              * duplicate conf, and pass a copy, to prevent 
11369              * one section from affecting another
11370              */
11371             process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
11372          }
11373       }
11374       ast_config_destroy(cfg);
11375    }
11376 #ifdef HAVE_PRI
11377    if (!reload) {
11378       for (x = 0; x < NUM_SPANS; x++) {
11379          if (pris[x].pvts[0]) {
11380             if (start_pri(pris + x)) {
11381                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
11382                return -1;
11383             } else if (option_verbose > 1)
11384                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
11385          }
11386       }
11387    }
11388 #endif
11389    /* And start the monitor for the first time */
11390    restart_monitor();
11391    return 0;
11392 }
11393 
11394 static int load_module(void)
11395 {
11396    int res;
11397 
11398 #ifdef HAVE_PRI
11399    int y,i;
11400    memset(pris, 0, sizeof(pris));
11401    for (y = 0; y < NUM_SPANS; y++) {
11402       ast_mutex_init(&pris[y].lock);
11403       pris[y].offset = -1;
11404       pris[y].master = AST_PTHREADT_NULL;
11405       for (i = 0; i < NUM_DCHANS; i++)
11406          pris[y].fds[i] = -1;
11407    }
11408    pri_set_error(zt_pri_error);
11409    pri_set_message(zt_pri_message);
11410    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
11411          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
11412 #endif
11413    res = setup_zap(0);
11414    /* Make sure we can register our Zap channel type */
11415    if (res)
11416       return AST_MODULE_LOAD_DECLINE;
11417    if (ast_channel_register(&zap_tech)) {
11418       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
11419       __unload_module();
11420       return -1;
11421    }
11422 #ifdef HAVE_PRI
11423    ast_string_field_init(&inuse, 16);
11424    ast_string_field_set(&inuse, name, "GR-303InUse");
11425    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11426 #endif   
11427    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11428    
11429    memset(round_robin, 0, sizeof(round_robin));
11430    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
11431    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
11432    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
11433    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
11434    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
11435    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
11436    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
11437 
11438    return res;
11439 }
11440 
11441 static int zt_sendtext(struct ast_channel *c, const char *text)
11442 {
11443 #define  END_SILENCE_LEN 400
11444 #define  HEADER_MS 50
11445 #define  TRAILER_MS 5
11446 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11447 #define  ASCII_BYTES_PER_CHAR 80
11448 
11449    unsigned char *buf,*mybuf;
11450    struct zt_pvt *p = c->tech_pvt;
11451    struct pollfd fds[1];
11452    int size,res,fd,len,x;
11453    int bytes=0;
11454    /* Initial carrier (imaginary) */
11455    float cr = 1.0;
11456    float ci = 0.0;
11457    float scont = 0.0;
11458    int index;
11459 
11460    index = zt_get_index(c, p, 0);
11461    if (index < 0) {
11462       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
11463       return -1;
11464    }
11465    if (!text[0]) return(0); /* if nothing to send, dont */
11466    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
11467    if (p->mate) 
11468       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
11469    else
11470       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
11471    if (!buf)
11472       return -1;
11473    mybuf = buf;
11474    if (p->mate) {
11475       int codec = AST_LAW(p);
11476       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
11477          PUT_CLID_MARKMS;
11478       }
11479       /* Put actual message */
11480       for (x = 0; text[x]; x++) {
11481          PUT_CLID(text[x]);
11482       }
11483       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
11484          PUT_CLID_MARKMS;
11485       }
11486       len = bytes;
11487       buf = mybuf;
11488    } else {
11489       len = tdd_generate(p->tdd, buf, text);
11490       if (len < 1) {
11491          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
11492          free(mybuf);
11493          return -1;
11494       }
11495    }
11496    memset(buf + len, 0x7f, END_SILENCE_LEN);
11497    len += END_SILENCE_LEN;
11498    fd = p->subs[index].zfd;
11499    while (len) {
11500       if (ast_check_hangup(c)) {
11501          free(mybuf);
11502          return -1;
11503       }
11504       size = len;
11505       if (size > READ_SIZE)
11506          size = READ_SIZE;
11507       fds[0].fd = fd;
11508       fds[0].events = POLLOUT | POLLPRI;
11509       fds[0].revents = 0;
11510       res = poll(fds, 1, -1);
11511       if (!res) {
11512          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
11513          continue;
11514       }
11515         /* if got exception */
11516       if (fds[0].revents & POLLPRI) {
11517          ast_free(mybuf);
11518          return -1;
11519       }
11520       if (!(fds[0].revents & POLLOUT)) {
11521          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
11522          continue;
11523       }
11524       res = write(fd, buf, size);
11525       if (res != size) {
11526          if (res == -1) {
11527             free(mybuf);
11528             return -1;
11529          }
11530          if (option_debug)
11531             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
11532          break;
11533       }
11534       len -= size;
11535       buf += size;
11536    }
11537    free(mybuf);
11538    return(0);
11539 }
11540 
11541 
11542 static int reload(void)
11543 {
11544    int res = 0;
11545 
11546    res = setup_zap(1);
11547    if (res) {
11548       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
11549       return -1;
11550    }
11551    return 0;
11552 }
11553 
11554 /* This is a workaround so that menuselect displays a proper description
11555  * AST_MODULE_INFO(, , "Zapata Telephony"
11556  */
11557 
11558 #ifdef ZAPATA_PRI
11559 #define tdesc "Zapata Telephony w/PRI"
11560 #else
11561 #define tdesc "Zapata Telephony"
11562 #endif
11563 
11564 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
11565       .load = load_module,
11566       .unload = unload_module,
11567       .reload = reload,
11568           );
11569 
11570 

Generated on Mon Mar 31 07:38:01 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1