Thu Oct 8 21:57:24 2009

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  * Copyright (C) 2003-2006 Junghanns.NET GmbH
00015  * Klaus-Peter Junghanns <kpj@junghanns.net>
00016  *
00017  *
00018  * This program is free software, distributed under the terms of
00019  * the GNU General Public License Version 2. See the LICENSE file
00020  * at the top of the source tree.
00021  */
00022 
00023 /*! \file
00024  *
00025  * \brief Zaptel Pseudo TDM interface 
00026  *
00027  * \author Mark Spencer <markster@digium.com>
00028  * 
00029  * Connects to the zaptel telephony library as well as 
00030  * libpri. Libpri is optional and needed only if you are
00031  * going to use ISDN connections.
00032  *
00033  * You need to install libraries before you attempt to compile
00034  * and install the zaptel channel.
00035  *
00036  * \par See also
00037  * \arg \ref Config_zap
00038  *
00039  * \ingroup channel_drivers
00040  *
00041  * \todo Deprecate the "musiconhold" configuration option post 1.4
00042  */
00043 
00044 /*** MODULEINFO
00045    <depend>res_smdi</depend>
00046    <depend>zaptel_vldtmf</depend>
00047    <depend>zaptel</depend>
00048    <depend>tonezone</depend>
00049    <depend>res_features</depend>
00050    <use>pri</use>
00051  ***/
00052 
00053 #include "asterisk.h"
00054 
00055 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 120425 $")
00056 
00057 #include <stdio.h>
00058 #include <string.h>
00059 #ifdef __NetBSD__
00060 #include <pthread.h>
00061 #include <signal.h>
00062 #else
00063 #include <sys/signal.h>
00064 #endif
00065 #include <errno.h>
00066 #include <stdlib.h>
00067 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00068 #include <stdint.h>
00069 #endif
00070 #include <unistd.h>
00071 #include <sys/ioctl.h>
00072 #include <math.h>
00073 #include <ctype.h>
00074 #include <zaptel/zaptel.h>
00075 #include <zaptel/tonezone.h>
00076 
00077 #ifdef HAVE_PRI
00078 #include <bristuffed/libpri.h>
00079 #endif
00080 #ifdef HAVE_GSMAT
00081 #include <libgsmat.h>
00082 #endif
00083 
00084 #include "asterisk/lock.h"
00085 #include "asterisk/channel.h"
00086 #include "asterisk/config.h"
00087 #include "asterisk/logger.h"
00088 #include "asterisk/module.h"
00089 #include "asterisk/pbx.h"
00090 #include "asterisk/options.h"
00091 #include "asterisk/file.h"
00092 #include "asterisk/ulaw.h"
00093 #include "asterisk/alaw.h"
00094 #include "asterisk/callerid.h"
00095 #include "asterisk/adsi.h"
00096 #include "asterisk/cli.h"
00097 #include "asterisk/cdr.h"
00098 #include "asterisk/features.h"
00099 #include "asterisk/musiconhold.h"
00100 #include "asterisk/say.h"
00101 #include "asterisk/tdd.h"
00102 #include "asterisk/app.h"
00103 #include "asterisk/dsp.h"
00104 #include "asterisk/astdb.h"
00105 #include "asterisk/manager.h"
00106 #include "asterisk/causes.h"
00107 #include "asterisk/term.h"
00108 #include "asterisk/utils.h"
00109 #include "asterisk/transcap.h"
00110 #include "asterisk/stringfields.h"
00111 #include "asterisk/abstract_jb.h"
00112 #include "asterisk/smdi.h"
00113 #include "asterisk/astobj.h"
00114 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00115 
00116 /*! Global jitterbuffer configuration - by default, jb is disabled */
00117 static struct ast_jb_conf default_jbconf =
00118 {
00119    .flags = 0,
00120    .max_size = -1,
00121    .resync_threshold = -1,
00122    .impl = ""
00123 };
00124 static struct ast_jb_conf global_jbconf;
00125 
00126 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00127 #error "Your zaptel is too old.  Please update"
00128 #endif
00129 
00130 #ifndef ZT_TONEDETECT
00131 /* Work around older code with no tone detect */
00132 #define ZT_EVENT_DTMFDOWN 0
00133 #define ZT_EVENT_DTMFUP 0
00134 #endif
00135 
00136 /* define this to send PRI user-user information elements */
00137 #undef SUPPORT_USERUSER
00138 
00139 /*! 
00140  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00141  * the user hangs up to reset the state machine so ring works properly.
00142  * This is used to be able to support kewlstart by putting the zhone in
00143  * groundstart mode since their forward disconnect supervision is entirely
00144  * broken even though their documentation says it isn't and their support
00145  * is entirely unwilling to provide any assistance with their channel banks
00146  * even though their web site says they support their products for life.
00147  */
00148 /* #define ZHONE_HACK */
00149 
00150 /*! \note
00151  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00152  * before dialing on it.  Certain FXO interfaces always think they're out of
00153  * service with this method however.
00154  */
00155 /* #define ZAP_CHECK_HOOKSTATE */
00156 
00157 /*! \brief Typically, how many rings before we should send Caller*ID */
00158 #define DEFAULT_CIDRINGS 1
00159 
00160 #define CHANNEL_PSEUDO -12
00161 
00162 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00163 
00164 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00165 #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)) 
00166 
00167 static const char tdesc[] = "Zapata Telephony Driver"
00168 #ifdef HAVE_PRI
00169                " w/PRI"
00170 #endif
00171 ;
00172 
00173 static const char config[] = "zapata.conf";
00174 
00175 #define SIG_EM    ZT_SIG_EM
00176 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00177 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00178 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00179 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00180 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00181 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00182 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00183 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00184 #define SIG_FXSLS ZT_SIG_FXSLS
00185 #define SIG_FXSGS ZT_SIG_FXSGS
00186 #define SIG_FXSKS ZT_SIG_FXSKS
00187 #define SIG_FXOLS ZT_SIG_FXOLS
00188 #define SIG_FXOGS ZT_SIG_FXOGS
00189 #define SIG_FXOKS ZT_SIG_FXOKS
00190 #define SIG_PRI      ZT_SIG_CLEAR
00191 #define SIG_GSM      (0x100000 | ZT_SIG_CLEAR)
00192 #define  SIG_SF      ZT_SIG_SF
00193 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00194 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00195 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00196 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00197 #define SIG_EM_E1 ZT_SIG_EM_E1
00198 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00199 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00200 
00201 #define NUM_SPANS       ZT_MAX_SPANS
00202 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00203 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00204 
00205 #define CHAN_PSEUDO  -2
00206 
00207 #define DCHAN_PROVISIONED (1 << 0)
00208 #define DCHAN_NOTINALARM  (1 << 1)
00209 #define DCHAN_UP          (1 << 2)
00210 
00211 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00212 
00213 static char defaultcic[64] = "";
00214 static char defaultozz[64] = "";
00215 
00216 static char progzone[10] = "";
00217 
00218 static int distinctiveringaftercid = 0;
00219 
00220 static int numbufs = 4;
00221 
00222 #ifdef HAVE_PRI
00223 static struct ast_channel inuse;
00224 #ifdef PRI_GETSET_TIMERS
00225 static int pritimers[PRI_MAX_TIMERS];
00226 #endif
00227 #endif
00228 
00229 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00230 static int firstdigittimeout = 16000;
00231 
00232 /*! \brief How long to wait for following digits (FXO logic) */
00233 static int gendigittimeout = 8000;
00234 
00235 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00236 static int matchdigittimeout = 3000;
00237 
00238 /*! \brief Protect the interface list (of zt_pvt's) */
00239 AST_MUTEX_DEFINE_STATIC(iflock);
00240 
00241 static char gsm_modem_pin[20];
00242 static char gsm_modem_exten[AST_MAX_EXTENSION];
00243 
00244 static int ifcount = 0;
00245 
00246 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00247    when it's doing something critical. */
00248 AST_MUTEX_DEFINE_STATIC(monlock);
00249 
00250 /*! \brief This is the thread for the monitor which checks for input on the channels
00251    which are not currently in use. */
00252 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00253 
00254 static int restart_monitor(void);
00255 
00256 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);
00257 
00258 static int zt_sendtext(struct ast_channel *c, const char *text);
00259 
00260 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00261 
00262 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00263 static inline int zt_get_event(int fd)
00264 {
00265    int j;
00266    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00267       return -1;
00268    return j;
00269 }
00270 
00271 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00272 static inline int zt_wait_event(int fd)
00273 {
00274    int i, j = 0;
00275    i = ZT_IOMUX_SIGEVENT;
00276    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00277       return -1;
00278    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00279       return -1;
00280    return j;
00281 }
00282 
00283 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00284 #define READ_SIZE 160
00285 
00286 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00287 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00288 
00289 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00290 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
00291 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00292 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00293 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
00294 
00295 struct zt_pvt;
00296 
00297 static int ringt_base = DEFAULT_RINGT;
00298 
00299 #ifdef HAVE_PRI
00300 
00301 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00302 #define PRI_CHANNEL(p) ((p) & 0xff)
00303 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00304 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00305 
00306 struct zt_suspended_call {
00307    ast_mutex_t lock;    /* Mutex */
00308    char msn[AST_MAX_EXTENSION];  /* the MSN to which this parked call belongs */
00309    char callid[10];        /* the callID provided by the user */
00310    int parked_at;       /* extension in the call parking context */
00311    struct zt_suspended_call *next;
00312 };
00313 
00314 struct zt_pri {
00315    pthread_t master;                /*!< Thread of master */
00316    ast_mutex_t lock;                /*!< Mutex */
00317    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00318    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00319    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00320    int minunused;                   /*!< Min # of channels to keep empty */
00321    int minidle;                     /*!< Min # of "idling" calls to keep active */
00322    int nodetype;                    /*!< Node type */
00323    int switchtype;                     /*!< Type of switch to emulate */
00324    int nsf;                   /*!< Network-Specific Facilities */
00325    int dialplan;                    /*!< Dialing plan */
00326    int localdialplan;                  /*!< Local dialing plan */
00327    char nocid[AST_MAX_EXTENSION];               /*!< CallerID string to use if none provided */
00328    char withheldcid[AST_MAX_EXTENSION];            /*!< CallerID string to use if CallerID is withheld */
00329    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00330    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00331    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00332    char privateprefix[20];                /*!< for private dialplans */
00333    char unknownprefix[20];                /*!< for unknown dialplans */
00334    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00335    int trunkgroup;                     /*!< What our trunkgroup is */
00336    int mastertrunkgroup;                  /*!< What trunk group is our master */
00337    int prilogicalspan;                 /*!< Logical span number within trunk group */
00338    int numchans;                    /*!< Num of channels we represent */
00339    int overlapdial;                 /*!< In overlap dialing mode */
00340    int usercid;
00341    int facilityenable;                 /*!< Enable facility IEs */
00342    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00343    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00344    struct pri *pri;                 /*!< Currently active D-channel */
00345    int debug;
00346    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00347    int offset;
00348    int span;
00349    int resetting;
00350    int resetpos;
00351    time_t lastreset;                /*!< time when unused channels were last reset */
00352    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00353    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00354    struct zt_pvt *crvs;                /*!< Member CRV structs */
00355    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00356    struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
00357    int debugfd;
00358 };
00359 
00360 #ifdef HAVE_GSMAT
00361 struct zt_gsm {
00362    pthread_t master;
00363    ast_mutex_t lock;    /* Mutex */
00364    int fd;
00365    int span;
00366    struct gsm_modul *modul;
00367    char pin[256];
00368    int available;
00369    char exten[AST_MAX_EXTENSION];      /* Where to idle extra calls */
00370    struct zt_pvt *pvt;
00371 };
00372 #endif
00373 
00374 static struct zt_pri pris[NUM_SPANS];
00375 
00376 #if 0
00377 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00378 #else
00379 #define DEFAULT_PRI_DEBUG 0
00380 #endif
00381 
00382 static inline void pri_rel(struct zt_pri *pri)
00383 {
00384    ast_mutex_unlock(&pri->lock);
00385 }
00386 
00387 #else
00388 /*! Shut up the compiler */
00389 struct zt_pri;
00390 #endif
00391 
00392 #define SUB_REAL  0        /*!< Active call */
00393 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00394 #define SUB_THREEWAY 2        /*!< Three-way call */
00395 
00396 /* Polarity states */
00397 #define POLARITY_IDLE   0
00398 #define POLARITY_REV    1
00399 
00400 
00401 
00402 static struct zt_distRings drings;
00403 
00404 struct distRingData {
00405    int ring[3];
00406 };
00407 struct ringContextData {
00408    char contextData[AST_MAX_CONTEXT];
00409 };
00410 struct zt_distRings {
00411    struct distRingData ringnum[3];
00412    struct ringContextData ringContext[3];
00413 };
00414 
00415 static char *subnames[] = {
00416    "Real",
00417    "Callwait",
00418    "Threeway"
00419 };
00420 
00421 struct zt_subchannel {
00422    int zfd;
00423    struct ast_channel *owner;
00424    int chan;
00425    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00426    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00427    unsigned int needringing:1;
00428    unsigned int needbusy:1;
00429    unsigned int needcongestion:1;
00430    unsigned int needcallerid:1;
00431    unsigned int needanswer:1;
00432    unsigned int needflash:1;
00433    unsigned int needhold:1;
00434    unsigned int needunhold:1;
00435    unsigned int linear:1;
00436    unsigned int inthreeway:1;
00437    ZT_CONFINFO curconf;
00438 };
00439 
00440 #define CONF_USER_REAL     (1 << 0)
00441 #define CONF_USER_THIRDCALL   (1 << 1)
00442 
00443 #define MAX_SLAVES   4
00444 
00445 static struct zt_pvt {
00446    ast_mutex_t lock;
00447    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00448                      /*!< Up to three channels can be associated with this call */
00449       
00450    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00451    struct zt_subchannel subs[3];       /*!< Sub-channels */
00452    struct zt_confinfo saveconf;        /*!< Saved conference info */
00453 
00454    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00455    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00456    int inconference;          /*!< If our real should be in the conference */
00457    
00458    int sig;             /*!< Signalling style */
00459    int radio;              /*!< radio type */
00460    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00461    int oprmode;               /*!< "Operator Services" mode */
00462    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00463    float rxgain;
00464    float txgain;
00465    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00466    struct zt_pvt *next;          /*!< Next channel in list */
00467    struct zt_pvt *prev;          /*!< Prev channel in list */
00468 
00469    /* flags */
00470    unsigned int adsi:1;
00471    unsigned int answeronpolarityswitch:1;
00472    unsigned int busydetect:1;
00473    unsigned int callreturn:1;
00474    unsigned int callwaiting:1;
00475    unsigned int callwaitingcallerid:1;
00476    unsigned int cancallforward:1;
00477    unsigned int canpark:1;
00478    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00479    unsigned int destroy:1;
00480    unsigned int didtdd:1;           /*!< flag to say its done it once */
00481    unsigned int dialednone:1;
00482    unsigned int dialing:1;
00483    unsigned int digital:1;
00484    unsigned int dnd:1;
00485    unsigned int echobreak:1;
00486    unsigned int echocanbridged:1;
00487    unsigned int echocanon:1;
00488    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00489                      /*!< KPJ: i will abuse this flag to implement a zapata option for dialing out
00490                          on a zap channel with EC to be off no matter what happens. */
00491    unsigned int firstradio:1;
00492    unsigned int hanguponpolarityswitch:1;
00493    unsigned int hardwaredtmf:1;
00494    unsigned int hidecallerid:1;
00495    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00496    unsigned int ignoredtmf:1;
00497    unsigned int immediate:1;        /*!< Answer before getting digits? */
00498    unsigned int inalarm:1;
00499    unsigned int unknown_alarm:1;
00500    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00501    unsigned int outgoing:1;
00502    unsigned int overlapdial:1;
00503    unsigned int permcallwaiting:1;
00504    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00505    unsigned int priindication_oob:2;
00506    unsigned int pritransfer:2;
00507    unsigned int priexclusive:1;
00508    unsigned int pulse:1;
00509    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00510    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00511    unsigned int threewaycalling:1;
00512    unsigned int transfer:1;
00513    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00514    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00515    unsigned int usedistinctiveringdetection:1;
00516    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00517    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00518 #if defined(HAVE_PRI)
00519    unsigned int alerting:1;
00520    unsigned int alreadyhungup:1;
00521    unsigned int isidlecall:1;
00522    unsigned int proceeding:1;
00523    unsigned int progress:1;
00524    unsigned int resetting:1;
00525    unsigned int setup_ack:1;
00526 #endif
00527    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00528    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00529 
00530    struct zt_distRings drings;
00531 
00532    char context[AST_MAX_CONTEXT];
00533    char defcontext[AST_MAX_CONTEXT];
00534    char exten[AST_MAX_EXTENSION];
00535    char language[MAX_LANGUAGE];
00536    char mohinterpret[MAX_MUSICCLASS];
00537    char mohsuggest[MAX_MUSICCLASS];
00538 #ifdef PRI_ANI
00539    char cid_ani[AST_MAX_EXTENSION];
00540 #endif
00541    char cid_num[AST_MAX_EXTENSION];
00542    int cid_ton;               /*!< Type Of Number (TON) */
00543    int cid_pres;              /*!< Calling Presentation */
00544    char cid_name[AST_MAX_EXTENSION];
00545    char lastcid_num[AST_MAX_EXTENSION];
00546    char lastcid_name[AST_MAX_EXTENSION];
00547    char *origcid_num;            /*!< malloced original callerid */
00548    char *origcid_name;           /*!< malloced original callerid */
00549    char callwait_num[AST_MAX_EXTENSION];
00550    char callwait_name[AST_MAX_EXTENSION];
00551    char rdnis[AST_MAX_EXTENSION];
00552    char dnid[AST_MAX_EXTENSION];
00553    ast_group_t group;
00554    int law;
00555    int confno;             /*!< Our conference */
00556    int confusers;             /*!< Who is using our conference */
00557    int propconfno;               /*!< Propagated conference number */
00558    ast_group_t callgroup;
00559    ast_group_t pickupgroup;
00560    int channel;               /*!< Channel Number or CRV */
00561    int span;               /*!< Span number */
00562    time_t guardtime;          /*!< Must wait this much time before using for new call */
00563    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00564    int cid_start;             /*!< CID start indicator, polarity or ring */
00565    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00566    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00567    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00568    unsigned char *cidspill;
00569    int cidpos;
00570    int cidlen;
00571    int ringt;
00572    int ringt_base;
00573    int stripmsd;
00574    int callwaitcas;
00575    int callwaitrings;
00576    int echocancel;
00577    int echotraining;
00578    char echorest[20];
00579    int busycount;
00580    int busy_tonelength;
00581    int busy_quietlength;
00582    int callprogress;
00583    struct timeval flashtime;        /*!< Last flash-hook time */
00584    struct ast_dsp *dsp;
00585    int cref;               /*!< Call reference number */
00586    ZT_DIAL_OPERATION dop;
00587    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00588    char finaldial[64];
00589    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00590    int amaflags;              /*!< AMA Flags */
00591    struct tdd_state *tdd;           /*!< TDD flag */
00592    char call_forward[AST_MAX_EXTENSION];
00593    char mailbox[AST_MAX_EXTENSION];
00594    char dialdest[256];
00595    int onhooktime;
00596    int msgstate;
00597    int distinctivering;          /*!< Which distinctivering to use */
00598    int cidrings;              /*!< Which ring to deliver CID on */
00599    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00600    int fake_event;
00601    int polarityonanswerdelay;
00602    struct timeval polaritydelaytv;
00603    int sendcalleridafter;
00604 #ifdef HAVE_PRI
00605    struct zt_pri *pri;
00606    struct zt_pvt *bearer;
00607    struct zt_pvt *realcall;
00608    q931_call *call;
00609    int tei;             /* channel in use by this tei */
00610    q931_call *holdedcall;
00611    int prioffset;
00612    int logicalspan;
00613 #endif   
00614 #ifdef HAVE_GSMAT
00615    struct zt_gsm gsm;
00616 #endif
00617    int polarity;
00618    int dsp_features;
00619    char begindigit;
00620 } *iflist = NULL, *ifend = NULL;
00621 
00622 /*! \brief Channel configuration from zapata.conf .
00623  * This struct is used for parsing the [channels] section of zapata.conf.
00624  * Generally there is a field here for every possible configuration item.
00625  *
00626  * The state of fields is saved along the parsing and whenever a 'channel'
00627  * statement is reached, the current zt_chan_conf is used to configure the 
00628  * channel (struct zt_pvt)
00629  *
00630  * @seealso zt_chan_init for the default values.
00631  */
00632 struct zt_chan_conf {
00633    struct zt_pvt chan;
00634 #ifdef HAVE_PRI
00635    struct zt_pri pri;
00636 #endif
00637    ZT_PARAMS timing;
00638 
00639    char smdi_port[SMDI_MAX_FILENAME_LEN];
00640 };
00641 
00642 /** returns a new zt_chan_conf with default values (by-value) */
00643 static struct zt_chan_conf zt_chan_conf_default(void) {
00644    /* recall that if a field is not included here it is initialized
00645     * to 0 or equivalent
00646     */
00647    struct zt_chan_conf conf = {
00648 #ifdef HAVE_PRI
00649       .pri = {
00650          .nsf = PRI_NSF_NONE,
00651          .switchtype = PRI_SWITCH_NI2,
00652          .dialplan = PRI_NATIONAL_ISDN + 1,
00653          .localdialplan = PRI_NATIONAL_ISDN + 1,
00654          .nodetype = PRI_CPE,
00655 
00656          .minunused = 2,
00657          .idleext = "",
00658          .idledial = "",
00659          .nocid = "No CID available",
00660          .withheldcid = "CID withheld",
00661          .internationalprefix = "",
00662          .nationalprefix = "",
00663          .localprefix = "",
00664          .privateprefix = "",
00665          .unknownprefix = "",
00666          .usercid = 0,
00667 
00668          .resetinterval = 3600
00669       },
00670 #endif
00671       .chan = {
00672          .context = "default",
00673          .cid_num = "",
00674          .cid_name = "",
00675          .mohinterpret = "default",
00676          .mohsuggest = "",
00677          .transfertobusy = 1,
00678          .priindication_oob = 0,
00679          .pritransfer = 0,
00680 
00681          .cid_signalling = CID_SIG_BELL,
00682          .cid_start = CID_START_RING,
00683          .zaptrcallerid = 0,
00684          .use_callerid = 1,
00685          .sig = -1,
00686          .outsigmod = -1,
00687 
00688          .tonezone = -1,
00689 
00690          .echocancel = 1,
00691 
00692          .busycount = 3,
00693 
00694          .accountcode = "",
00695 
00696          .mailbox = "",
00697 
00698 
00699          .polarityonanswerdelay = 600,
00700 
00701          .sendcalleridafter = DEFAULT_CIDRINGS
00702       },
00703       .timing = {
00704          .prewinktime = -1,
00705          .preflashtime = -1,
00706          .winktime = -1,
00707          .flashtime = -1,
00708          .starttime = -1,
00709          .rxwinktime = -1,
00710          .rxflashtime = -1,
00711          .debouncetime = -1
00712       },
00713       .smdi_port = "/dev/ttyS0",
00714    };
00715 
00716    return conf;
00717 }
00718 
00719 
00720 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00721 static int zt_digit_begin(struct ast_channel *ast, char digit);
00722 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00723 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00724 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00725 static int zt_hangup(struct ast_channel *ast);
00726 static int zt_answer(struct ast_channel *ast);
00727 static struct ast_frame *zt_read(struct ast_channel *ast);
00728 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00729 static struct ast_frame *zt_exception(struct ast_channel *ast);
00730 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00731 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00732 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00733 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00734 static void enable_dtmf_detect(struct zt_pvt *p);
00735 static void disable_dtmf_detect(struct zt_pvt *p);
00736 
00737 static const struct ast_channel_tech zap_tech = {
00738    .type = "Zap",
00739    .description = tdesc,
00740    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00741    .requester = zt_request,
00742    .send_digit_begin = zt_digit_begin,
00743    .send_digit_end = zt_digit_end,
00744    .send_text = zt_sendtext,
00745 #if 0 /* we (Debian) disable that addition because of ABI breakage */
00746    .send_message = zt_sendmessage,
00747 #endif
00748    .call = zt_call,
00749    .hangup = zt_hangup,
00750    .answer = zt_answer,
00751    .read = zt_read,
00752    .write = zt_write,
00753    .bridge = zt_bridge,
00754    .exception = zt_exception,
00755    .indicate = zt_indicate,
00756    .fixup = zt_fixup,
00757    .setoption = zt_setoption,
00758    .func_channel_read = zt_func_read,
00759 };
00760 
00761 #ifdef HAVE_PRI
00762 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00763 #else
00764 #define GET_CHANNEL(p) ((p)->channel)
00765 #endif
00766 
00767 struct zt_pvt *round_robin[32];
00768 
00769 #ifdef HAVE_PRI
00770 struct app_tmp {
00771    char app[256];
00772    char data[256];
00773    struct ast_channel *chan;
00774    pthread_t t;
00775 };
00776 
00777 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00778 {
00779    int res;
00780    /* Grab the lock first */
00781    do {
00782       res = ast_mutex_trylock(&pri->lock);
00783       if (res) {
00784          DEADLOCK_AVOIDANCE(&pvt->lock);
00785       }
00786    } while (res);
00787    /* Then break the poll */
00788    pthread_kill(pri->master, SIGURG);
00789    return 0;
00790 }
00791 #endif
00792 
00793 #define NUM_CADENCE_MAX 25
00794 static int num_cadence = 4;
00795 static int user_has_defined_cadences = 0;
00796 
00797 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00798    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00799    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00800    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00801    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00802 };
00803 
00804 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00805  * is 1, the second pause is 2 and so on.
00806  */
00807 
00808 static int cidrings[NUM_CADENCE_MAX] = {
00809    2,                            /*!< Right after first long ring */
00810    4,                            /*!< Right after long part */
00811    3,                            /*!< After third chirp */
00812    2,                            /*!< Second spell */
00813 };
00814 
00815 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00816          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00817 
00818 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00819 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00820 
00821 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00822 {
00823    int res;
00824    if (p->subs[0].owner == ast)
00825       res = 0;
00826    else if (p->subs[1].owner == ast)
00827       res = 1;
00828    else if (p->subs[2].owner == ast)
00829       res = 2;
00830    else {
00831       res = -1;
00832       if (!nullok)
00833          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00834    }
00835    return res;
00836 }
00837 
00838 #ifdef HAVE_PRI
00839 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00840 #else
00841 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00842 #endif
00843 {
00844 #ifdef HAVE_PRI
00845    if (pri)
00846       ast_mutex_unlock(&pri->lock);
00847 #endif         
00848    for (;;) {
00849       if (p->subs[a].owner) {
00850          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00851             DEADLOCK_AVOIDANCE(&p->lock);
00852          } else {
00853             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00854             ast_mutex_unlock(&p->subs[a].owner->lock);
00855             break;
00856          }
00857       } else
00858          break;
00859    }
00860 #ifdef HAVE_PRI
00861    if (pri)
00862       ast_mutex_lock(&pri->lock);
00863 #endif         
00864 }
00865 
00866 #ifdef HAVE_PRI
00867 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00868 #else
00869 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00870 #endif
00871 {
00872    /* We must unlock the PRI to avoid the possibility of a deadlock */
00873 #ifdef HAVE_PRI
00874    if (pri)
00875       ast_mutex_unlock(&pri->lock);
00876 #endif      
00877    for (;;) {
00878       if (p->owner) {
00879          if (ast_mutex_trylock(&p->owner->lock)) {
00880             DEADLOCK_AVOIDANCE(&p->lock);
00881          } else {
00882             ast_queue_frame(p->owner, f);
00883             ast_mutex_unlock(&p->owner->lock);
00884             break;
00885          }
00886       } else
00887          break;
00888    }
00889 #ifdef HAVE_PRI
00890    if (pri)
00891       ast_mutex_lock(&pri->lock);
00892 #endif      
00893 }
00894 
00895 static int restore_gains(struct zt_pvt *p);
00896 
00897 static void swap_subs(struct zt_pvt *p, int a, int b)
00898 {
00899    int tchan;
00900    int tinthreeway;
00901    struct ast_channel *towner;
00902 
00903    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
00904 
00905    tchan = p->subs[a].chan;
00906    towner = p->subs[a].owner;
00907    tinthreeway = p->subs[a].inthreeway;
00908 
00909    p->subs[a].chan = p->subs[b].chan;
00910    p->subs[a].owner = p->subs[b].owner;
00911    p->subs[a].inthreeway = p->subs[b].inthreeway;
00912 
00913    p->subs[b].chan = tchan;
00914    p->subs[b].owner = towner;
00915    p->subs[b].inthreeway = tinthreeway;
00916 
00917    if (p->subs[a].owner) 
00918       p->subs[a].owner->fds[0] = p->subs[a].zfd;
00919    if (p->subs[b].owner) 
00920       p->subs[b].owner->fds[0] = p->subs[b].zfd;
00921    wakeup_sub(p, a, NULL);
00922    wakeup_sub(p, b, NULL);
00923 }
00924 
00925 static int zt_open(char *fn)
00926 {
00927    int fd;
00928    int isnum;
00929    int chan = 0;
00930    int bs;
00931    int x;
00932    isnum = 1;
00933    for (x = 0; x < strlen(fn); x++) {
00934       if (!isdigit(fn[x])) {
00935          isnum = 0;
00936          break;
00937       }
00938    }
00939    if (isnum) {
00940       chan = atoi(fn);
00941       if (chan < 1) {
00942          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
00943          return -1;
00944       }
00945       fn = "/dev/zap/channel";
00946    }
00947    fd = open(fn, O_RDWR | O_NONBLOCK);
00948    if (fd < 0) {
00949       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
00950       return -1;
00951    }
00952    if (chan) {
00953       if (ioctl(fd, ZT_SPECIFY, &chan)) {
00954          x = errno;
00955          close(fd);
00956          errno = x;
00957          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
00958          return -1;
00959       }
00960    }
00961    bs = READ_SIZE;
00962    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
00963       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
00964       x = errno;
00965       close(fd);
00966       errno = x;
00967       return -1;
00968    }
00969    return fd;
00970 }
00971 
00972 static void zt_close(int fd)
00973 {
00974    if (fd > 0)
00975       close(fd);
00976 }
00977 
00978 static int zt_setlinear(int zfd, int linear)
00979 {
00980    int res;
00981    res = ioctl(zfd, ZT_SETLINEAR, &linear);
00982    if (res)
00983       return res;
00984    return 0;
00985 }
00986 
00987 
00988 static int alloc_sub(struct zt_pvt *p, int x)
00989 {
00990    ZT_BUFFERINFO bi;
00991    int res;
00992    if (p->subs[x].zfd < 0) {
00993       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
00994       if (p->subs[x].zfd > -1) {
00995          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
00996          if (!res) {
00997             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
00998             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
00999             bi.numbufs = numbufs;
01000             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
01001             if (res < 0) {
01002                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
01003             }
01004          } else 
01005             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
01006          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
01007             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
01008             zt_close(p->subs[x].zfd);
01009             p->subs[x].zfd = -1;
01010             return -1;
01011          }
01012          if (option_debug)
01013             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
01014          return 0;
01015       } else
01016          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01017       return -1;
01018    }
01019    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01020    return -1;
01021 }
01022 
01023 static int unalloc_sub(struct zt_pvt *p, int x)
01024 {
01025    if (!x) {
01026       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01027       return -1;
01028    }
01029    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01030    if (p->subs[x].zfd > -1) {
01031       zt_close(p->subs[x].zfd);
01032    }
01033    p->subs[x].zfd = -1;
01034    p->subs[x].linear = 0;
01035    p->subs[x].chan = 0;
01036    p->subs[x].owner = NULL;
01037    p->subs[x].inthreeway = 0;
01038    p->polarity = POLARITY_IDLE;
01039    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01040    return 0;
01041 }
01042 
01043 static int digit_to_dtmfindex(char digit)
01044 {
01045    if (isdigit(digit))
01046       return ZT_TONE_DTMF_BASE + (digit - '0');
01047    else if (digit >= 'A' && digit <= 'D')
01048       return ZT_TONE_DTMF_A + (digit - 'A');
01049    else if (digit >= 'a' && digit <= 'd')
01050       return ZT_TONE_DTMF_A + (digit - 'a');
01051    else if (digit == '*')
01052       return ZT_TONE_DTMF_s;
01053    else if (digit == '#')
01054       return ZT_TONE_DTMF_p;
01055    else
01056       return -1;
01057 }
01058 
01059 static int zt_digit_begin(struct ast_channel *chan, char digit)
01060 {
01061    struct zt_pvt *pvt;
01062    int index;
01063    int dtmf = -1;
01064    
01065    pvt = chan->tech_pvt;
01066 
01067    ast_mutex_lock(&pvt->lock);
01068 
01069    index = zt_get_index(chan, pvt, 0);
01070 
01071    if ((index != SUB_REAL) || !pvt->owner)
01072       goto out;
01073 
01074 #ifdef HAVE_PRI
01075    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01076       if (pvt->setup_ack) {
01077          if (!pri_grab(pvt, pvt->pri)) {
01078             pri_information(pvt->pri->pri, pvt->call, digit);
01079             pri_rel(pvt->pri);
01080          } else
01081             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01082       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01083          int res;
01084          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01085          res = strlen(pvt->dialdest);
01086          pvt->dialdest[res++] = digit;
01087          pvt->dialdest[res] = '\0';
01088       }
01089       goto out;
01090    }
01091 #endif
01092    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01093       goto out;
01094 
01095    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01096       int res;
01097       ZT_DIAL_OPERATION zo = {
01098          .op = ZT_DIAL_OP_APPEND,
01099          .dialstr[0] = 'T',
01100          .dialstr[1] = digit,
01101          .dialstr[2] = 0,
01102       };
01103       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01104          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01105       else
01106          pvt->dialing = 1;
01107    } else {
01108       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01109       pvt->dialing = 1;
01110       pvt->begindigit = digit;
01111    }
01112 
01113 out:
01114    ast_mutex_unlock(&pvt->lock);
01115 
01116    return 0;
01117 }
01118 
01119 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01120 {
01121    struct zt_pvt *pvt;
01122    int res = 0;
01123    int index;
01124    int x;
01125    
01126    pvt = chan->tech_pvt;
01127 
01128    ast_mutex_lock(&pvt->lock);
01129    
01130    index = zt_get_index(chan, pvt, 0);
01131 
01132    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01133       goto out;
01134 
01135 #ifdef HAVE_PRI
01136    /* This means that the digit was already sent via PRI signalling */
01137    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01138       goto out;
01139 #endif
01140 
01141    if (pvt->begindigit) {
01142       x = -1;
01143       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01144       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01145       pvt->dialing = 0;
01146       pvt->begindigit = 0;
01147    }
01148 
01149 out:
01150    ast_mutex_unlock(&pvt->lock);
01151 
01152    return res;
01153 }
01154 
01155 static char *events[] = {
01156    "No event",
01157    "On hook",
01158    "Ring/Answered",
01159    "Wink/Flash",
01160    "Alarm",
01161    "No more alarm",
01162    "HDLC Abort",
01163    "HDLC Overrun",
01164    "HDLC Bad FCS",
01165    "Dial Complete",
01166    "Ringer On",
01167    "Ringer Off",
01168    "Hook Transition Complete",
01169    "Bits Changed",
01170    "Pulse Start",
01171    "Timer Expired",
01172    "Timer Ping",
01173    "Polarity Reversal",
01174    "Ring Begin",
01175 };
01176 
01177 static struct {
01178    int alarm;
01179    char *name;
01180 } alarms[] = {
01181    { ZT_ALARM_RED, "Red Alarm" },
01182    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01183    { ZT_ALARM_BLUE, "Blue Alarm" },
01184    { ZT_ALARM_RECOVER, "Recovering" },
01185    { ZT_ALARM_LOOPBACK, "Loopback" },
01186    { ZT_ALARM_NOTOPEN, "Not Open" },
01187    { ZT_ALARM_NONE, "None" },
01188 };
01189 
01190 static char *alarm2str(int alarm)
01191 {
01192    int x;
01193    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01194       if (alarms[x].alarm & alarm)
01195          return alarms[x].name;
01196    }
01197    return alarm ? "Unknown Alarm" : "No Alarm";
01198 }
01199 
01200 static char *event2str(int event)
01201 {
01202    static char buf[256];
01203    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01204       return events[event];
01205    sprintf(buf, "Event %d", event); /* safe */
01206    return buf;
01207 }
01208 
01209 #ifdef HAVE_PRI
01210 static char *dialplan2str(int dialplan)
01211 {
01212    if (dialplan == -1) {
01213       return("Dynamically set dialplan in ISDN");
01214    }
01215    return (pri_plan2str(dialplan));
01216 }
01217 #endif
01218 
01219 static char *zap_sig2str(int sig)
01220 {
01221    static char buf[256];
01222    switch (sig) {
01223    case SIG_EM:
01224       return "E & M Immediate";
01225    case SIG_EMWINK:
01226       return "E & M Wink";
01227    case SIG_EM_E1:
01228       return "E & M E1";
01229    case SIG_FEATD:
01230       return "Feature Group D (DTMF)";
01231    case SIG_FEATDMF:
01232       return "Feature Group D (MF)";
01233    case SIG_FEATDMF_TA:
01234       return "Feature Groud D (MF) Tandem Access";
01235    case SIG_FEATB:
01236       return "Feature Group B (MF)";
01237    case SIG_E911:
01238       return "E911 (MF)";
01239    case SIG_FGC_CAMA:
01240       return "FGC/CAMA (Dialpulse)";
01241    case SIG_FGC_CAMAMF:
01242       return "FGC/CAMA (MF)";
01243    case SIG_FXSLS:
01244       return "FXS Loopstart";
01245    case SIG_FXSGS:
01246       return "FXS Groundstart";
01247    case SIG_FXSKS:
01248       return "FXS Kewlstart";
01249    case SIG_FXOLS:
01250       return "FXO Loopstart";
01251    case SIG_FXOGS:
01252       return "FXO Groundstart";
01253    case SIG_FXOKS:
01254       return "FXO Kewlstart";
01255    case SIG_PRI:
01256       return "ISDN PRI";
01257    case SIG_SF:
01258       return "SF (Tone) Immediate";
01259    case SIG_SFWINK:
01260       return "SF (Tone) Wink";
01261    case SIG_SF_FEATD:
01262       return "SF (Tone) with Feature Group D (DTMF)";
01263    case SIG_SF_FEATDMF:
01264       return "SF (Tone) with Feature Group D (MF)";
01265    case SIG_SF_FEATB:
01266       return "SF (Tone) with Feature Group B (MF)";
01267    case SIG_GR303FXOKS:
01268       return "GR-303 with FXOKS";
01269    case SIG_GR303FXSKS:
01270       return "GR-303 with FXSKS";
01271    case SIG_GSM:
01272       return "GSM";
01273    case 0:
01274       return "Pseudo";
01275    default:
01276       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01277       return buf;
01278    }
01279 }
01280 
01281 #define sig2str zap_sig2str
01282 
01283 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01284 {
01285    /* If the conference already exists, and we're already in it
01286       don't bother doing anything */
01287    ZT_CONFINFO zi;
01288    
01289    memset(&zi, 0, sizeof(zi));
01290    zi.chan = 0;
01291 
01292    if (slavechannel > 0) {
01293       /* If we have only one slave, do a digital mon */
01294       zi.confmode = ZT_CONF_DIGITALMON;
01295       zi.confno = slavechannel;
01296    } else {
01297       if (!index) {
01298          /* Real-side and pseudo-side both participate in conference */
01299          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01300             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01301       } else
01302          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01303       zi.confno = p->confno;
01304    }
01305    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01306       return 0;
01307    if (c->zfd < 0)
01308       return 0;
01309    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01310       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01311       return -1;
01312    }
01313    if (slavechannel < 1) {
01314       p->confno = zi.confno;
01315    }
01316    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01317    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01318    return 0;
01319 }
01320 
01321 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01322 {
01323    /* If they're listening to our channel, they're ours */  
01324    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01325       return 1;
01326    /* If they're a talker on our (allocated) conference, they're ours */
01327    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01328       return 1;
01329    return 0;
01330 }
01331 
01332 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01333 {
01334    ZT_CONFINFO zi;
01335    if (/* Can't delete if there's no zfd */
01336       (c->zfd < 0) ||
01337       /* Don't delete from the conference if it's not our conference */
01338       !isourconf(p, c)
01339       /* Don't delete if we don't think it's conferenced at all (implied) */
01340       ) return 0;
01341    memset(&zi, 0, sizeof(zi));
01342    zi.chan = 0;
01343    zi.confno = 0;
01344    zi.confmode = 0;
01345    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01346       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01347       return -1;
01348    }
01349    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01350    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01351    return 0;
01352 }
01353 
01354 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01355 {
01356    int x;
01357    int useslavenative;
01358    struct zt_pvt *slave = NULL;
01359    /* Start out optimistic */
01360    useslavenative = 1;
01361    /* Update conference state in a stateless fashion */
01362    for (x = 0; x < 3; x++) {
01363       /* Any three-way calling makes slave native mode *definitely* out
01364          of the question */
01365       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01366          useslavenative = 0;
01367    }
01368    /* If we don't have any 3-way calls, check to see if we have
01369       precisely one slave */
01370    if (useslavenative) {
01371       for (x = 0; x < MAX_SLAVES; x++) {
01372          if (p->slaves[x]) {
01373             if (slave) {
01374                /* Whoops already have a slave!  No 
01375                   slave native and stop right away */
01376                slave = NULL;
01377                useslavenative = 0;
01378                break;
01379             } else {
01380                /* We have one slave so far */
01381                slave = p->slaves[x];
01382             }
01383          }
01384       }
01385    }
01386    /* If no slave, slave native definitely out */
01387    if (!slave)
01388       useslavenative = 0;
01389    else if (slave->law != p->law) {
01390       useslavenative = 0;
01391       slave = NULL;
01392    }
01393    if (out)
01394       *out = slave;
01395    return useslavenative;
01396 }
01397 
01398 static int reset_conf(struct zt_pvt *p)
01399 {
01400    ZT_CONFINFO zi;
01401    memset(&zi, 0, sizeof(zi));
01402    p->confno = -1;
01403    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01404    if (p->subs[SUB_REAL].zfd > -1) {
01405       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01406          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01407    }
01408    return 0;
01409 }
01410 
01411 static int update_conf(struct zt_pvt *p)
01412 {
01413    int needconf = 0;
01414    int x;
01415    int useslavenative;
01416    struct zt_pvt *slave = NULL;
01417 
01418    useslavenative = isslavenative(p, &slave);
01419    /* Start with the obvious, general stuff */
01420    for (x = 0; x < 3; x++) {
01421       /* Look for three way calls */
01422       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01423          conf_add(p, &p->subs[x], x, 0);
01424          needconf++;
01425       } else {
01426          conf_del(p, &p->subs[x], x);
01427       }
01428    }
01429    /* If we have a slave, add him to our conference now. or DAX
01430       if this is slave native */
01431    for (x = 0; x < MAX_SLAVES; x++) {
01432       if (p->slaves[x]) {
01433          if (useslavenative)
01434             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01435          else {
01436             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01437             needconf++;
01438          }
01439       }
01440    }
01441    /* If we're supposed to be in there, do so now */
01442    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01443       if (useslavenative)
01444          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01445       else {
01446          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01447          needconf++;
01448       }
01449    }
01450    /* If we have a master, add ourselves to his conference */
01451    if (p->master) {
01452       if (isslavenative(p->master, NULL)) {
01453          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01454       } else {
01455          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01456       }
01457    }
01458    if (!needconf) {
01459       /* Nobody is left (or should be left) in our conference.
01460          Kill it. */
01461       p->confno = -1;
01462    }
01463    if (option_debug)
01464       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01465    return 0;
01466 }
01467 
01468 static void zt_enable_ec(struct zt_pvt *p)
01469 {
01470    int x;
01471    int res;
01472    if (!p)
01473       return;
01474    if (p->faxhandled)  {
01475       ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n");
01476       return;
01477    }
01478    if (p->echocanon) {
01479       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01480       return;
01481    }
01482    if (p->digital) {
01483       ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n");
01484       return;
01485    }
01486    if (p->echocancel) {
01487       if (p->sig == SIG_PRI) {
01488          x = 1;
01489          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01490          if (res)
01491             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
01492       }
01493       x = p->echocancel;
01494       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01495       if (res) 
01496          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
01497       else {
01498          p->echocanon = 1;
01499          if (option_debug)
01500             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01501       }
01502    } else if (option_debug)
01503       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01504 }
01505 
01506 static void zt_train_ec(struct zt_pvt *p)
01507 {
01508    int x;
01509    int res;
01510    if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) {
01511       x = p->echotraining;
01512       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01513       if (res)
01514          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01515       else {
01516          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01517       }
01518    } else
01519       ast_log(LOG_DEBUG, "No echo training requested\n");
01520 }
01521 
01522 static void zt_disable_ec(struct zt_pvt *p)
01523 {
01524    int x;
01525    int res;
01526    if (p->echocancel) {
01527       x = 0;
01528       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01529       if (res)
01530          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01531       else if (option_debug)
01532          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01533    }
01534    p->echocanon = 0;
01535 }
01536 
01537 static void fill_txgain(struct zt_gains *g, float gain, int law)
01538 {
01539    int j;
01540    int k;
01541    float linear_gain = pow(10.0, gain / 20.0);
01542 
01543    switch (law) {
01544    case ZT_LAW_ALAW:
01545       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01546          if (gain) {
01547             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01548             if (k > 32767) k = 32767;
01549             if (k < -32767) k = -32767;
01550             g->txgain[j] = AST_LIN2A(k);
01551          } else {
01552             g->txgain[j] = j;
01553          }
01554       }
01555       break;
01556    case ZT_LAW_MULAW:
01557       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01558          if (gain) {
01559             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01560             if (k > 32767) k = 32767;
01561             if (k < -32767) k = -32767;
01562             g->txgain[j] = AST_LIN2MU(k);
01563          } else {
01564             g->txgain[j] = j;
01565          }
01566       }
01567       break;
01568    }
01569 }
01570 
01571 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01572 {
01573    int j;
01574    int k;
01575    float linear_gain = pow(10.0, gain / 20.0);
01576 
01577    switch (law) {
01578    case ZT_LAW_ALAW:
01579       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01580          if (gain) {
01581             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01582             if (k > 32767) k = 32767;
01583             if (k < -32767) k = -32767;
01584             g->rxgain[j] = AST_LIN2A(k);
01585          } else {
01586             g->rxgain[j] = j;
01587          }
01588       }
01589       break;
01590    case ZT_LAW_MULAW:
01591       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01592          if (gain) {
01593             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01594             if (k > 32767) k = 32767;
01595             if (k < -32767) k = -32767;
01596             g->rxgain[j] = AST_LIN2MU(k);
01597          } else {
01598             g->rxgain[j] = j;
01599          }
01600       }
01601       break;
01602    }
01603 }
01604 
01605 static int set_actual_txgain(int fd, int chan, float gain, int law)
01606 {
01607    struct zt_gains g;
01608    int res;
01609 
01610    memset(&g, 0, sizeof(g));
01611    g.chan = chan;
01612    res = ioctl(fd, ZT_GETGAINS, &g);
01613    if (res) {
01614       if (option_debug)
01615          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01616       return res;
01617    }
01618 
01619    fill_txgain(&g, gain, law);
01620 
01621    return ioctl(fd, ZT_SETGAINS, &g);
01622 }
01623 
01624 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01625 {
01626    struct zt_gains g;
01627    int res;
01628 
01629    memset(&g, 0, sizeof(g));
01630    g.chan = chan;
01631    res = ioctl(fd, ZT_GETGAINS, &g);
01632    if (res) {
01633       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01634       return res;
01635    }
01636 
01637    fill_rxgain(&g, gain, law);
01638 
01639    return ioctl(fd, ZT_SETGAINS, &g);
01640 }
01641 
01642 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01643 {
01644    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01645 }
01646 
01647 static int bump_gains(struct zt_pvt *p)
01648 {
01649    int res;
01650 
01651    /* Bump receive gain by 5.0db */
01652    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01653    if (res) {
01654       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01655       return -1;
01656    }
01657 
01658    return 0;
01659 }
01660 
01661 static int restore_gains(struct zt_pvt *p)
01662 {
01663    int res;
01664 
01665    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01666    if (res) {
01667       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01668       return -1;
01669    }
01670 
01671    return 0;
01672 }
01673 
01674 static inline int zt_set_hook(int fd, int hs)
01675 {
01676    int x, res;
01677 
01678    x = hs;
01679    res = ioctl(fd, ZT_HOOK, &x);
01680 
01681    if (res < 0) {
01682       if (errno == EINPROGRESS)
01683          return 0;
01684       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01685    }
01686 
01687    return res;
01688 }
01689 
01690 static inline int zt_confmute(struct zt_pvt *p, int muted)
01691 {
01692    int x, y, res;
01693    x = muted;
01694    if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) {
01695       y = 1;
01696       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01697       if (res)
01698          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01699    }
01700    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01701    if (res < 0)
01702       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01703    return res;
01704 }
01705 
01706 static int save_conference(struct zt_pvt *p)
01707 {
01708    struct zt_confinfo c;
01709    int res;
01710    if (p->saveconf.confmode) {
01711       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01712       return -1;
01713    }
01714    p->saveconf.chan = 0;
01715    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01716    if (res) {
01717       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01718       p->saveconf.confmode = 0;
01719       return -1;
01720    }
01721    c.chan = 0;
01722    c.confno = 0;
01723    c.confmode = ZT_CONF_NORMAL;
01724    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01725    if (res) {
01726       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01727       return -1;
01728    }
01729    if (option_debug)
01730       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01731    return 0;
01732 }
01733 
01734 static int restore_conference(struct zt_pvt *p)
01735 {
01736    int res;
01737    if (p->saveconf.confmode) {
01738       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01739       p->saveconf.confmode = 0;
01740       if (res) {
01741          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01742          return -1;
01743       }
01744    }
01745    if (option_debug)
01746       ast_log(LOG_DEBUG, "Restored conferencing\n");
01747    return 0;
01748 }
01749 
01750 static int send_callerid(struct zt_pvt *p);
01751 
01752 static int send_cwcidspill(struct zt_pvt *p)
01753 {
01754    p->callwaitcas = 0;
01755    p->cidcwexpire = 0;
01756    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01757       return -1;
01758    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01759    /* Make sure we account for the end */
01760    p->cidlen += READ_SIZE * 4;
01761    p->cidpos = 0;
01762    send_callerid(p);
01763    if (option_verbose > 2)
01764       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01765    return 0;
01766 }
01767 
01768 static int has_voicemail(struct zt_pvt *p)
01769 {
01770 
01771    return ast_app_has_voicemail(p->mailbox, NULL);
01772 }
01773 
01774 static int send_callerid(struct zt_pvt *p)
01775 {
01776    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01777    int res;
01778    /* Take out of linear mode if necessary */
01779    if (p->subs[SUB_REAL].linear) {
01780       p->subs[SUB_REAL].linear = 0;
01781       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01782    }
01783    while (p->cidpos < p->cidlen) {
01784       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01785       if (res < 0) {
01786          if (errno == EAGAIN)
01787             return 0;
01788          else {
01789             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01790             return -1;
01791          }
01792       }
01793       if (!res)
01794          return 0;
01795       p->cidpos += res;
01796    }
01797    free(p->cidspill);
01798    p->cidspill = NULL;
01799    if (p->callwaitcas) {
01800       /* Wait for CID/CW to expire */
01801       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01802    } else
01803       restore_conference(p);
01804    return 0;
01805 }
01806 
01807 static int zt_callwait(struct ast_channel *ast)
01808 {
01809    struct zt_pvt *p = ast->tech_pvt;
01810    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01811    if (p->cidspill) {
01812       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01813       free(p->cidspill);
01814    }
01815    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01816       return -1;
01817    save_conference(p);
01818    /* Silence */
01819    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01820    if (!p->callwaitrings && p->callwaitingcallerid) {
01821       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01822       p->callwaitcas = 1;
01823       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01824    } else {
01825       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01826       p->callwaitcas = 0;
01827       p->cidlen = 2400 + READ_SIZE * 4;
01828    }
01829    p->cidpos = 0;
01830    send_callerid(p);
01831    
01832    return 0;
01833 }
01834 
01835 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01836 {
01837    struct zt_pvt *p = ast->tech_pvt;
01838    int x, res, index,mysig;
01839    char *c, *n, *l;
01840 #ifdef HAVE_PRI
01841    char *s = NULL;
01842 #endif
01843    char dest[256]; /* must be same length as p->dialdest */
01844    ast_mutex_lock(&p->lock);
01845    ast_copy_string(dest, rdest, sizeof(dest));
01846    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01847    if ((ast->_state == AST_STATE_BUSY)) {
01848       p->subs[SUB_REAL].needbusy = 1;
01849       ast_mutex_unlock(&p->lock);
01850       return 0;
01851    }
01852    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01853       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01854       ast_mutex_unlock(&p->lock);
01855       return -1;
01856    }
01857    p->dialednone = 0;
01858    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01859    {
01860       /* Special pseudo -- automatically up */
01861       ast_setstate(ast, AST_STATE_UP); 
01862       ast_mutex_unlock(&p->lock);
01863       return 0;
01864    }
01865    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01866    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01867    if (res)
01868       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01869    p->outgoing = 1;
01870 
01871    if (IS_DIGITAL(ast->transfercapability)) {
01872        set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
01873    } else {
01874        set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01875    }
01876 
01877 
01878    mysig = p->sig;
01879    if (p->outsigmod > -1)
01880       mysig = p->outsigmod;
01881 
01882    switch (mysig) {
01883    case SIG_FXOLS:
01884    case SIG_FXOGS:
01885    case SIG_FXOKS:
01886       if (p->owner == ast) {
01887          /* Normal ring, on hook */
01888          
01889          /* Don't send audio while on hook, until the call is answered */
01890          p->dialing = 1;
01891          if (p->use_callerid) {
01892             /* Generate the Caller-ID spill if desired */
01893             if (p->cidspill) {
01894                ast_log(LOG_WARNING, "cidspill already exists??\n");
01895                free(p->cidspill);
01896             }
01897             p->callwaitcas = 0;
01898             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
01899                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
01900                p->cidpos = 0;
01901                send_callerid(p);
01902             }
01903          }
01904          /* Choose proper cadence */
01905          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
01906             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
01907                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
01908             p->cidrings = cidrings[p->distinctivering - 1];
01909          } else {
01910             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
01911                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
01912             p->cidrings = p->sendcalleridafter;
01913          }
01914 
01915          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
01916          c = strchr(dest, '/');
01917          if (c)
01918             c++;
01919          if (c && (strlen(c) < p->stripmsd)) {
01920             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01921             c = NULL;
01922          }
01923          if (c) {
01924             p->dop.op = ZT_DIAL_OP_REPLACE;
01925             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
01926             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
01927          } else {
01928             p->dop.dialstr[0] = '\0';
01929          }
01930          x = ZT_RING;
01931          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
01932             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
01933             ast_mutex_unlock(&p->lock);
01934             return -1;
01935          }
01936          p->dialing = 1;
01937       } else {
01938          /* Call waiting call */
01939          p->callwaitrings = 0;
01940          if (ast->cid.cid_num)
01941             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
01942          else
01943             p->callwait_num[0] = '\0';
01944          if (ast->cid.cid_name)
01945             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
01946          else
01947             p->callwait_name[0] = '\0';
01948          /* Call waiting tone instead */
01949          if (zt_callwait(ast)) {
01950             ast_mutex_unlock(&p->lock);
01951             return -1;
01952          }
01953          /* Make ring-back */
01954          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
01955             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
01956             
01957       }
01958       n = ast->cid.cid_name;
01959       l = ast->cid.cid_num;
01960       if (l)
01961          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
01962       else
01963          p->lastcid_num[0] = '\0';
01964       if (n)
01965          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
01966       else
01967          p->lastcid_name[0] = '\0';
01968       ast_setstate(ast, AST_STATE_RINGING);
01969       index = zt_get_index(ast, p, 0);
01970       if (index > -1) {
01971          p->subs[index].needringing = 1;
01972       }
01973       break;
01974    case SIG_FXSLS:
01975    case SIG_FXSGS:
01976    case SIG_FXSKS:
01977    case SIG_EMWINK:
01978    case SIG_EM:
01979    case SIG_EM_E1:
01980    case SIG_FEATD:
01981    case SIG_FEATDMF:
01982    case SIG_E911:
01983    case SIG_FGC_CAMA:
01984    case SIG_FGC_CAMAMF:
01985    case SIG_FEATB:
01986    case SIG_SFWINK:
01987    case SIG_SF:
01988    case SIG_SF_FEATD:
01989    case SIG_SF_FEATDMF:
01990    case SIG_FEATDMF_TA:
01991    case SIG_SF_FEATB:
01992       c = strchr(dest, '/');
01993       if (c)
01994          c++;
01995       else
01996          c = "";
01997       if (strlen(c) < p->stripmsd) {
01998          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
01999          ast_mutex_unlock(&p->lock);
02000          return -1;
02001       }
02002 #ifdef HAVE_PRI
02003       /* Start the trunk, if not GR-303 */
02004       if (!p->pri) {
02005 #endif
02006          x = ZT_START;
02007          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02008          if (res < 0) {
02009             if (errno != EINPROGRESS) {
02010                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
02011                ast_mutex_unlock(&p->lock);
02012                return -1;
02013             }
02014          }
02015 #ifdef HAVE_PRI
02016       }
02017 #endif
02018       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
02019       p->dop.op = ZT_DIAL_OP_REPLACE;
02020 
02021       c += p->stripmsd;
02022 
02023       switch (mysig) {
02024       case SIG_FEATD:
02025          l = ast->cid.cid_num;
02026          if (l) 
02027             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
02028          else
02029             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
02030          break;
02031       case SIG_FEATDMF:
02032          l = ast->cid.cid_num;
02033          if (l) 
02034             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
02035          else
02036             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
02037          break;
02038       case SIG_FEATDMF_TA:
02039       {
02040          const char *cic, *ozz;
02041 
02042          /* If you have to go through a Tandem Access point you need to use this */
02043          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
02044          if (!ozz)
02045             ozz = defaultozz;
02046          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
02047          if (!cic)
02048             cic = defaultcic;
02049          if (!ozz || !cic) {
02050             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
02051             ast_mutex_unlock(&p->lock);
02052             return -1;
02053          }
02054          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
02055          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
02056          p->whichwink = 0;
02057       }
02058          break;
02059       case SIG_E911:
02060          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
02061          break;
02062       case SIG_FGC_CAMA:
02063          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02064          break;
02065       case SIG_FGC_CAMAMF:
02066       case SIG_FEATB:
02067          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02068          break;
02069       default:
02070          if (p->pulse)
02071             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02072          else
02073             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02074          break;
02075       }
02076 
02077       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02078          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02079          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02080          p->echorest[sizeof(p->echorest) - 1] = '\0';
02081          p->echobreak = 1;
02082          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02083       } else
02084          p->echobreak = 0;
02085       if (!res) {
02086          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02087             x = ZT_ONHOOK;
02088             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02089             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02090             ast_mutex_unlock(&p->lock);
02091             return -1;
02092          }
02093       } else
02094          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02095       p->dialing = 1;
02096       if (ast_strlen_zero(c))
02097          p->dialednone = 1;
02098       ast_setstate(ast, AST_STATE_DIALING);
02099       break;
02100    case 0:
02101       /* Special pseudo -- automatically up*/
02102       ast_setstate(ast, AST_STATE_UP);
02103       break;      
02104    case SIG_PRI:
02105       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02106       p->dialdest[0] = '\0';
02107       disable_dtmf_detect(p);
02108       break;
02109    case SIG_GSM:
02110 #ifdef HAVE_GSMAT
02111       if (p->gsm.modul) {
02112           c = strchr(dest, '/');
02113           if (c)
02114          c++;
02115           else
02116          c = dest;
02117           ast_mutex_lock(&p->gsm.lock);
02118           if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) {
02119          ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel);
02120          ast_mutex_unlock(&p->gsm.lock);
02121          ast_mutex_unlock(&p->lock);
02122          return -1;
02123           }
02124           ast_mutex_unlock(&p->gsm.lock);
02125       }
02126 #endif
02127       break;
02128    default:
02129       ast_log(LOG_DEBUG, "not yet implemented\n");
02130       ast_mutex_unlock(&p->lock);
02131       return -1;
02132    }
02133 #ifdef HAVE_PRI
02134    if (p->pri) {
02135       struct pri_sr *sr;
02136 #ifdef SUPPORT_USERUSER
02137       const char *useruser;
02138 #endif
02139       int pridialplan;
02140       int dp_strip;
02141       int prilocaldialplan;
02142       int ldp_strip;
02143       int exclusive;
02144       const char *rr_str;
02145       int redirect_reason;
02146 
02147       if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
02148           // pass NO audio when ringing an isdn phone
02149           p->dialing = 1;
02150           // maybe we could allow passing audio when calling a p2p PBX, but well... ;-)
02151       }
02152 
02153       c = strchr(dest, '/');
02154       if (c)
02155          c++;
02156       else
02157          c = dest;
02158 
02159       l = NULL;
02160       n = NULL;
02161 
02162       if (!p->hidecallerid) {
02163          l = ast->cid.cid_num;
02164          if (!p->hidecalleridname) {
02165             n = ast->cid.cid_name;
02166          }
02167       }
02168 
02169 
02170       if (strlen(c) < p->stripmsd) {
02171          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02172          ast_mutex_unlock(&p->lock);
02173          return -1;
02174       }
02175       strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1);
02176       if (mysig != SIG_FXSKS) {
02177          p->dop.op = ZT_DIAL_OP_REPLACE;
02178          s = strchr(c + p->stripmsd, 'w');
02179          if (s) {
02180             if (strlen(s) > 1)
02181                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02182             else
02183                p->dop.dialstr[0] = '\0';
02184             *s = '\0';
02185          } else {
02186             p->dop.dialstr[0] = '\0';
02187          }
02188       }
02189       if (pri_grab(p, p->pri)) {
02190          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02191          ast_mutex_unlock(&p->lock);
02192          return -1;
02193       }
02194       if (!(p->call = pri_new_call(p->pri->pri))) {
02195          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02196          pri_rel(p->pri);
02197          ast_mutex_unlock(&p->lock);
02198          return -1;
02199       } else {
02200       // ast_log(LOG_NOTICE, "call %d\n", p->call);
02201       }
02202       if (!(sr = pri_sr_new())) {
02203          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02204          pri_destroycall(p->pri->pri, p->call);
02205          p->call = NULL;
02206          pri_rel(p->pri);
02207          ast_mutex_unlock(&p->lock);
02208          return -1;
02209       }
02210       if (p->bearer || (mysig == SIG_FXSKS)) {
02211          if (p->bearer) {
02212             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);
02213             p->bearer->call = p->call;
02214          } else
02215             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02216          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02217       }
02218       p->digital = IS_DIGITAL(ast->transfercapability);
02219       /* Add support for exclusive override */
02220       if (p->priexclusive)
02221          exclusive = 1;
02222       else {
02223       /* otherwise, traditional behavior */
02224          if (p->pri->nodetype == PRI_NETWORK)
02225             exclusive = 0;
02226          else
02227             exclusive = 1;
02228       }
02229       
02230       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02231       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02232                (p->digital ? -1 : 
02233                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat);
02234       if (p->pri->facilityenable)
02235          pri_facility_enable(p->pri->pri);
02236 
02237       if (option_verbose > 2)
02238          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02239       dp_strip = 0;
02240       pridialplan = p->pri->dialplan - 1;
02241       if (pridialplan == -2) { /* compute dynamically */
02242          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02243             dp_strip = strlen(p->pri->internationalprefix);
02244             pridialplan = PRI_INTERNATIONAL_ISDN;
02245          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02246             dp_strip = strlen(p->pri->nationalprefix);
02247             pridialplan = PRI_NATIONAL_ISDN;
02248          } else {
02249             pridialplan = PRI_LOCAL_ISDN;
02250          }
02251       }
02252       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02253 
02254       ldp_strip = 0;
02255       prilocaldialplan = p->pri->localdialplan - 1;
02256       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02257          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02258             ldp_strip = strlen(p->pri->internationalprefix);
02259             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02260          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02261             ldp_strip = strlen(p->pri->nationalprefix);
02262             prilocaldialplan = PRI_NATIONAL_ISDN;
02263          } else {
02264             prilocaldialplan = PRI_LOCAL_ISDN;
02265          }
02266       }
02267       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02268          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02269       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02270          if (!strcasecmp(rr_str, "UNKNOWN"))
02271             redirect_reason = 0;
02272          else if (!strcasecmp(rr_str, "BUSY"))
02273             redirect_reason = 1;
02274          else if (!strcasecmp(rr_str, "NO_REPLY"))
02275             redirect_reason = 2;
02276          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02277             redirect_reason = 15;
02278          else
02279             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02280       } else
02281          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02282       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02283 
02284 #ifdef SUPPORT_USERUSER
02285       /* User-user info */
02286       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02287 
02288       if (useruser)
02289          pri_sr_set_useruser(sr, useruser);
02290 #endif
02291 
02292       if (pri_setup(p->pri->pri, p->call, sr)) {
02293          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02294             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02295          pri_rel(p->pri);
02296          ast_mutex_unlock(&p->lock);
02297          pri_sr_free(sr);
02298          return -1;
02299       }
02300       pri_sr_free(sr);
02301       ast_setstate(ast, AST_STATE_DIALING);
02302       pri_rel(p->pri);
02303    }
02304 #endif      
02305    ast_mutex_unlock(&p->lock);
02306    return 0;
02307 }
02308 
02309 static void destroy_zt_pvt(struct zt_pvt **pvt)
02310 {
02311    struct zt_pvt *p = *pvt;
02312    /* Remove channel from the list */
02313    if (p->prev)
02314       p->prev->next = p->next;
02315    if (p->next)
02316       p->next->prev = p->prev;
02317    if (p->use_smdi)
02318       ast_smdi_interface_unref(p->smdi_iface);
02319    ast_mutex_destroy(&p->lock);
02320    free(p);
02321    *pvt = NULL;
02322 }
02323 
02324 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02325 {
02326    int owned = 0;
02327    int i = 0;
02328 
02329    if (!now) {
02330       if (cur->owner) {
02331          owned = 1;
02332       }
02333 
02334       for (i = 0; i < 3; i++) {
02335          if (cur->subs[i].owner) {
02336             owned = 1;
02337          }
02338       }
02339       if (!owned) {
02340          if (prev) {
02341             prev->next = cur->next;
02342             if (prev->next)
02343                prev->next->prev = prev;
02344             else
02345                ifend = prev;
02346          } else {
02347             iflist = cur->next;
02348             if (iflist)
02349                iflist->prev = NULL;
02350             else
02351                ifend = NULL;
02352          }
02353          if (cur->subs[SUB_REAL].zfd > -1) {
02354             zt_close(cur->subs[SUB_REAL].zfd);
02355          }
02356          destroy_zt_pvt(&cur);
02357       }
02358    } else {
02359       if (prev) {
02360          prev->next = cur->next;
02361          if (prev->next)
02362             prev->next->prev = prev;
02363          else
02364             ifend = prev;
02365       } else {
02366          iflist = cur->next;
02367          if (iflist)
02368             iflist->prev = NULL;
02369          else
02370             ifend = NULL;
02371       }
02372       if (cur->subs[SUB_REAL].zfd > -1) {
02373          zt_close(cur->subs[SUB_REAL].zfd);
02374       }
02375       destroy_zt_pvt(&cur);
02376    }
02377    return 0;
02378 }
02379 
02380 #ifdef HAVE_PRI
02381 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02382 
02383 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02384 
02385 static char *zap_send_keypad_facility_descrip = 
02386 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02387 "  IE over the current channel.\n";
02388 
02389 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02390 {
02391    /* Data will be our digit string */
02392    struct zt_pvt *p;
02393    char *digits = (char *) data;
02394 
02395    if (ast_strlen_zero(digits)) {
02396       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02397       return -1;
02398    }
02399 
02400    p = (struct zt_pvt *)chan->tech_pvt;
02401 
02402    if (!p) {
02403       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02404       return -1;
02405    }
02406 
02407    ast_mutex_lock(&p->lock);
02408 
02409    if (!p->pri || !p->call) {
02410       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02411       ast_mutex_unlock(&p->lock);
02412       return -1;
02413    }
02414 
02415    if (!pri_grab(p, p->pri)) {
02416       pri_keypad_facility(p->pri->pri, p->call, digits);
02417       pri_rel(p->pri);
02418    } else {
02419       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02420       ast_mutex_unlock(&p->lock);
02421       return -1;
02422    }
02423 
02424    ast_mutex_unlock(&p->lock);
02425 
02426    return 0;
02427 }
02428 
02429 static int pri_is_up(struct zt_pri *pri)
02430 {
02431    int x;
02432    for (x = 0; x < NUM_DCHANS; x++) {
02433       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02434          return 1;
02435    }
02436    return 0;
02437 }
02438 
02439 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02440 {
02441    bearer->owner = &inuse;
02442    bearer->realcall = crv;
02443    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02444    if (crv->subs[SUB_REAL].owner)
02445       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02446    crv->bearer = bearer;
02447    crv->call = bearer->call;
02448    crv->pri = pri;
02449    return 0;
02450 }
02451 
02452 static char *pri_order(int level)
02453 {
02454    switch (level) {
02455    case 0:
02456       return "Primary";
02457    case 1:
02458       return "Secondary";
02459    case 2:
02460       return "Tertiary";
02461    case 3:
02462       return "Quaternary";
02463    default:
02464       return "<Unknown>";
02465    }     
02466 }
02467 
02468 /* Returns fd of the active dchan */
02469 static int pri_active_dchan_fd(struct zt_pri *pri)
02470 {
02471    int x = -1;
02472 
02473    for (x = 0; x < NUM_DCHANS; x++) {
02474       if ((pri->dchans[x] == pri->pri))
02475          break;
02476    }
02477 
02478    return pri->fds[x];
02479 }
02480 
02481 static int pri_find_dchan(struct zt_pri *pri)
02482 {
02483    int oldslot = -1;
02484    struct pri *old;
02485    int newslot = -1;
02486    int x;
02487    old = pri->pri;
02488    for (x = 0; x < NUM_DCHANS; x++) {
02489       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02490          newslot = x;
02491       if (pri->dchans[x] == old) {
02492          oldslot = x;
02493       }
02494    }
02495    if (newslot < 0) {
02496       newslot = 0;
02497       if (pri->nodetype != BRI_CPE_PTMP) {
02498           ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02499          pri->dchannels[newslot]);
02500       }
02501    }
02502    if (old && (oldslot != newslot))
02503       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02504          pri->dchannels[oldslot], pri->dchannels[newslot]);
02505    pri->pri = pri->dchans[newslot];
02506    return 0;
02507 }
02508 #endif
02509 
02510 static int zt_setlaw(int zfd, int law)
02511 {
02512    int res;
02513    res = ioctl(zfd, ZT_SETLAW, &law);
02514    if (res)
02515       return res;
02516    return 0;
02517 }
02518 
02519 
02520 static int zt_hangup(struct ast_channel *ast)
02521 {
02522    int res;
02523    int index,x, law;
02524    /*static int restore_gains(struct zt_pvt *p);*/
02525    struct zt_pvt *p = ast->tech_pvt;
02526    struct zt_pvt *tmp = NULL;
02527    struct zt_pvt *prev = NULL;
02528    ZT_PARAMS par;
02529 
02530    if (option_debug)
02531       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02532    if (!ast->tech_pvt) {
02533       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02534       return 0;
02535    }
02536    
02537    ast_mutex_lock(&p->lock);
02538    
02539    index = zt_get_index(ast, p, 1);
02540 
02541    if (p->sig == SIG_PRI) {
02542       x = 1;
02543       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02544    }
02545 
02546    x = 0;
02547    zt_confmute(p, 0);
02548    restore_gains(p);
02549    if (p->origcid_num) {
02550       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02551       free(p->origcid_num);
02552       p->origcid_num = NULL;
02553    }  
02554    if (p->origcid_name) {
02555       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02556       free(p->origcid_name);
02557       p->origcid_name = NULL;
02558    }  
02559    if (p->dsp)
02560       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02561    if (p->exten)
02562       p->exten[0] = '\0';
02563 
02564    if (option_debug)
02565       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02566       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02567 
02568    if (index > -1) {
02569       /* Real channel, do some fixup */
02570       p->subs[index].owner = NULL;
02571       p->subs[index].needanswer = 0;
02572       p->subs[index].needflash = 0;
02573       p->subs[index].needringing = 0;
02574       p->subs[index].needbusy = 0;
02575       p->subs[index].needcongestion = 0;
02576       p->subs[index].linear = 0;
02577       p->subs[index].needcallerid = 0;
02578       p->polarity = POLARITY_IDLE;
02579       zt_setlinear(p->subs[index].zfd, 0);
02580       if (index == SUB_REAL) {
02581          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02582             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02583             if (p->subs[SUB_CALLWAIT].inthreeway) {
02584                /* We had flipped over to answer a callwait and now it's gone */
02585                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02586                /* Move to the call-wait, but un-own us until they flip back. */
02587                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02588                unalloc_sub(p, SUB_CALLWAIT);
02589                p->owner = NULL;
02590             } else {
02591                /* The three way hung up, but we still have a call wait */
02592                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02593                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02594                unalloc_sub(p, SUB_THREEWAY);
02595                if (p->subs[SUB_REAL].inthreeway) {
02596                   /* This was part of a three way call.  Immediately make way for
02597                      another call */
02598                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02599                   p->owner = p->subs[SUB_REAL].owner;
02600                } else {
02601                   /* This call hasn't been completed yet...  Set owner to NULL */
02602                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02603                   p->owner = NULL;
02604                }
02605                p->subs[SUB_REAL].inthreeway = 0;
02606             }
02607          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02608             /* Move to the call-wait and switch back to them. */
02609             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02610             unalloc_sub(p, SUB_CALLWAIT);
02611             p->owner = p->subs[SUB_REAL].owner;
02612             if (p->owner->_state != AST_STATE_UP)
02613                p->subs[SUB_REAL].needanswer = 1;
02614             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02615                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02616          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02617             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02618             unalloc_sub(p, SUB_THREEWAY);
02619             if (p->subs[SUB_REAL].inthreeway) {
02620                /* This was part of a three way call.  Immediately make way for
02621                   another call */
02622                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02623                p->owner = p->subs[SUB_REAL].owner;
02624             } else {
02625                /* This call hasn't been completed yet...  Set owner to NULL */
02626                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02627                p->owner = NULL;
02628             }
02629             p->subs[SUB_REAL].inthreeway = 0;
02630          }
02631       } else if (index == SUB_CALLWAIT) {
02632          /* Ditch the holding callwait call, and immediately make it availabe */
02633          if (p->subs[SUB_CALLWAIT].inthreeway) {
02634             /* This is actually part of a three way, placed on hold.  Place the third part
02635                on music on hold now */
02636             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02637                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02638                   S_OR(p->mohsuggest, NULL),
02639                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02640             }
02641             p->subs[SUB_THREEWAY].inthreeway = 0;
02642             /* Make it the call wait now */
02643             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02644             unalloc_sub(p, SUB_THREEWAY);
02645          } else
02646             unalloc_sub(p, SUB_CALLWAIT);
02647       } else if (index == SUB_THREEWAY) {
02648          if (p->subs[SUB_CALLWAIT].inthreeway) {
02649             /* The other party of the three way call is currently in a call-wait state.
02650                Start music on hold for them, and take the main guy out of the third call */
02651             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02652                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02653                   S_OR(p->mohsuggest, NULL),
02654                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02655             }
02656             p->subs[SUB_CALLWAIT].inthreeway = 0;
02657          }
02658          p->subs[SUB_REAL].inthreeway = 0;
02659          /* If this was part of a three way call index, let us make
02660             another three way call */
02661          unalloc_sub(p, SUB_THREEWAY);
02662       } else {
02663          /* This wasn't any sort of call, but how are we an index? */
02664          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02665       }
02666    }
02667 
02668    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02669       int outgoing = p->outgoing;
02670       p->owner = NULL;
02671       p->ringt = 0;
02672       p->distinctivering = 0;
02673       p->confirmanswer = 0;
02674       p->cidrings = 1;
02675       p->outgoing = 0;
02676       p->digital = 0;
02677       p->faxhandled = 0;
02678       p->pulsedial = 0;
02679       p->onhooktime = time(NULL);
02680 #ifdef HAVE_PRI
02681       p->proceeding = 0;
02682       p->progress = 0;
02683       p->alerting = 0;
02684       p->setup_ack = 0;
02685 #endif      
02686       if (p->dsp) {
02687          ast_dsp_free(p->dsp);
02688          p->dsp = NULL;
02689       }
02690 
02691       law = ZT_LAW_DEFAULT;
02692       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02693       if (res < 0) 
02694          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02695       /* Perform low level hangup if no owner left */
02696 #ifdef HAVE_PRI
02697       if (p->pri) {
02698 #ifdef SUPPORT_USERUSER
02699          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02700 #endif
02701 
02702          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02703          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02704             if (!pri_grab(p, p->pri)) {
02705                if (p->alreadyhungup) {
02706                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02707 
02708 #ifdef SUPPORT_USERUSER
02709                   pri_call_set_useruser(p->call, useruser);
02710 #endif
02711 
02712                   pri_hangup(p->pri->pri, p->call, -1, -1);
02713                   p->call = NULL;
02714                   if (p->bearer) 
02715                      p->bearer->call = NULL;
02716                } else {
02717                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02718                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02719                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02720 
02721 #ifdef SUPPORT_USERUSER
02722                   pri_call_set_useruser(p->call, useruser);
02723 #endif
02724 
02725                   p->alreadyhungup = 1;
02726                   if (p->bearer)
02727                      p->bearer->alreadyhungup = 1;
02728                   if (cause) {
02729                      if (atoi(cause))
02730                         icause = atoi(cause);
02731                   }
02732 
02733                   pri_hangup(p->pri->pri, p->call, icause, -1);
02734 
02735                   /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */
02736                   if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) {
02737                       if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) {
02738                      /* no-op */
02739                       } else {
02740                      ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state);
02741                      icause = 16; /* Note, in pri_hangup() libpri will already override the cause */
02742                       }
02743                       p->call = NULL;
02744                   }
02745 
02746                   if (p->pri->nodetype == BRI_NETWORK_PTMP) {
02747                       if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) {
02748                      if (outgoing) {
02749                          p->call = NULL;
02750                      }
02751                       }
02752                   }
02753 
02754 
02755                }
02756                if (res < 0) 
02757                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02758                pri_rel(p->pri);        
02759             } else {
02760                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02761                res = -1;
02762             }
02763          } else {
02764             if (p->bearer)
02765                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02766             p->call = NULL;
02767             res = 0;
02768          }
02769       }
02770 #endif
02771 #ifdef HAVE_GSMAT
02772       if (p->gsm.modul) {
02773           if (!p->alreadyhungup)
02774          gsm_hangup(p->gsm.modul);
02775       }
02776 #endif
02777       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM))
02778          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02779       if (res < 0) {
02780          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02781       }
02782       switch (p->sig) {
02783       case SIG_FXOGS:
02784       case SIG_FXOLS:
02785       case SIG_FXOKS:
02786          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02787          if (!res) {
02788 #if 0
02789             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02790 #endif
02791             /* If they're off hook, try playing congestion */
02792             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02793                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02794             else
02795                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02796          }
02797          break;
02798       case SIG_FXSGS:
02799       case SIG_FXSLS:
02800       case SIG_FXSKS:
02801          /* Make sure we're not made available for at least two seconds assuming
02802             we were actually used for an inbound or outbound call. */
02803          if (ast->_state != AST_STATE_RESERVED) {
02804             time(&p->guardtime);
02805             p->guardtime += 2;
02806          }
02807          break;
02808       default:
02809          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02810       }
02811       if (p->cidspill)
02812          free(p->cidspill);
02813       if (p->sig)
02814          zt_disable_ec(p);
02815       x = 0;
02816       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02817       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02818       p->didtdd = 0;
02819       p->cidspill = NULL;
02820       p->callwaitcas = 0;
02821       p->callwaiting = p->permcallwaiting;
02822       p->hidecallerid = p->permhidecallerid;
02823       p->dialing = 0;
02824       p->rdnis[0] = '\0';
02825       update_conf(p);
02826       reset_conf(p);
02827       /* Restore data mode */
02828       if (p->sig == SIG_PRI) {
02829          x = 0;
02830          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02831       }
02832 #ifdef HAVE_PRI
02833       if (p->bearer) {
02834          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02835          /* Free up the bearer channel as well, and
02836             don't use its file descriptor anymore */
02837          update_conf(p->bearer);
02838          reset_conf(p->bearer);
02839          p->bearer->owner = NULL;
02840          p->bearer->realcall = NULL;
02841          p->bearer = NULL;
02842          p->subs[SUB_REAL].zfd = -1;
02843          p->pri = NULL;
02844       }
02845 #endif
02846       restart_monitor();
02847    }
02848 
02849    p->callwaitingrepeat = 0;
02850    p->cidcwexpire = 0;
02851    p->oprmode = 0;
02852    ast->tech_pvt = NULL;
02853    ast_mutex_unlock(&p->lock);
02854    ast_module_unref(ast_module_info->self);
02855    if (option_verbose > 2) 
02856       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02857 
02858    ast_mutex_lock(&iflock);
02859    tmp = iflist;
02860    prev = NULL;
02861    if (p->destroy) {
02862       while (tmp) {
02863          if (tmp == p) {
02864             destroy_channel(prev, tmp, 0);
02865             break;
02866          } else {
02867             prev = tmp;
02868             tmp = tmp->next;
02869          }
02870       }
02871    }
02872    ast_mutex_unlock(&iflock);
02873    return 0;
02874 }
02875 
02876 static int zt_answer(struct ast_channel *ast)
02877 {
02878    struct zt_pvt *p = ast->tech_pvt;
02879    int res = 0;
02880    int index;
02881    int oldstate = ast->_state;
02882    ast_setstate(ast, AST_STATE_UP);
02883    ast_mutex_lock(&p->lock);
02884    index = zt_get_index(ast, p, 0);
02885    if (index < 0)
02886       index = SUB_REAL;
02887    /* nothing to do if a radio channel */
02888    if ((p->radio || (p->oprmode < 0))) {
02889       ast_mutex_unlock(&p->lock);
02890       return 0;
02891    }
02892    switch (p->sig) {
02893    case SIG_FXSLS:
02894    case SIG_FXSGS:
02895    case SIG_FXSKS:
02896       p->ringt = 0;
02897       /* Fall through */
02898    case SIG_EM:
02899    case SIG_EM_E1:
02900    case SIG_EMWINK:
02901    case SIG_FEATD:
02902    case SIG_FEATDMF:
02903    case SIG_FEATDMF_TA:
02904    case SIG_E911:
02905    case SIG_FGC_CAMA:
02906    case SIG_FGC_CAMAMF:
02907    case SIG_FEATB:
02908    case SIG_SF:
02909    case SIG_SFWINK:
02910    case SIG_SF_FEATD:
02911    case SIG_SF_FEATDMF:
02912    case SIG_SF_FEATB:
02913    case SIG_FXOLS:
02914    case SIG_FXOGS:
02915    case SIG_FXOKS:
02916       /* Pick up the line */
02917       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
02918       if (p->hanguponpolarityswitch) {
02919          gettimeofday(&p->polaritydelaytv, NULL);
02920       }
02921       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
02922       tone_zone_play_tone(p->subs[index].zfd, -1);
02923       p->dialing = 0;
02924       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
02925          if (oldstate == AST_STATE_RINGING) {
02926             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
02927             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
02928             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02929             p->owner = p->subs[SUB_REAL].owner;
02930          }
02931       }
02932       if (p->sig & __ZT_SIG_FXS) {
02933          zt_enable_ec(p);
02934          zt_train_ec(p);
02935       }
02936       break;
02937 #ifdef HAVE_PRI
02938    case SIG_PRI:
02939       /* Send a pri acknowledge */
02940       if (!pri_grab(p, p->pri)) {
02941          p->proceeding = 1;
02942          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
02943          pri_rel(p->pri);
02944          /* stop ignoring inband dtmf */
02945          enable_dtmf_detect(p);
02946       } else {
02947          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02948          res = -1;
02949       }
02950       /* the audio path is complete now, train the echo canceler */
02951       zt_train_ec(p);
02952       break;
02953 #endif
02954 #ifdef HAVE_GSMAT
02955    case SIG_GSM:
02956       if (p->gsm.modul) {
02957           gsm_answer(p->gsm.modul);
02958       }
02959       break;
02960 #endif
02961    case 0:
02962       ast_mutex_unlock(&p->lock);
02963       return 0;
02964    default:
02965       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
02966       res = -1;
02967    }
02968    ast_mutex_unlock(&p->lock);
02969    return res;
02970 }
02971 
02972 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
02973 {
02974    char *cp;
02975    signed char *scp;
02976    int x;
02977    int index;
02978    struct zt_pvt *p = chan->tech_pvt, *pp;
02979    struct oprmode *oprmode;
02980    
02981 
02982    /* all supported options require data */
02983    if (!data || (datalen < 1)) {
02984       errno = EINVAL;
02985       return -1;
02986    }
02987 
02988    switch (option) {
02989    case AST_OPTION_TXGAIN:
02990       scp = (signed char *) data;
02991       index = zt_get_index(chan, p, 0);
02992       if (index < 0) {
02993          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
02994          return -1;
02995       }
02996       if (option_debug)
02997          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
02998       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
02999    case AST_OPTION_RXGAIN:
03000       scp = (signed char *) data;
03001       index = zt_get_index(chan, p, 0);
03002       if (index < 0) {
03003          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
03004          return -1;
03005       }
03006       if (option_debug)
03007          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
03008       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
03009    case AST_OPTION_TONE_VERIFY:
03010       if (!p->dsp)
03011          break;
03012       cp = (char *) data;
03013       switch (*cp) {
03014       case 1:
03015          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
03016          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
03017          break;
03018       case 2:
03019          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
03020          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
03021          break;
03022       default:
03023          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
03024          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
03025          break;
03026       }
03027       break;
03028    case AST_OPTION_TDD:
03029       /* turn on or off TDD */
03030       cp = (char *) data;
03031       p->mate = 0;
03032       if (!*cp) { /* turn it off */
03033          if (option_debug)
03034             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
03035          if (p->tdd)
03036             tdd_free(p->tdd);
03037          p->tdd = 0;
03038          break;
03039       }
03040       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
03041          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
03042       zt_disable_ec(p);
03043       /* otherwise, turn it on */
03044       if (!p->didtdd) { /* if havent done it yet */
03045          unsigned char mybuf[41000], *buf;
03046          int size, res, fd, len;
03047          struct pollfd fds[1];
03048 
03049          buf = mybuf;
03050          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
03051          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
03052          len = 40000;
03053          index = zt_get_index(chan, p, 0);
03054          if (index < 0) {
03055             ast_log(LOG_WARNING, "No index in TDD?\n");
03056             return -1;
03057          }
03058          fd = p->subs[index].zfd;
03059          while (len) {
03060             if (ast_check_hangup(chan))
03061                return -1;
03062             size = len;
03063             if (size > READ_SIZE)
03064                size = READ_SIZE;
03065             fds[0].fd = fd;
03066             fds[0].events = POLLPRI | POLLOUT;
03067             fds[0].revents = 0;
03068             res = poll(fds, 1, -1);
03069             if (!res) {
03070                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
03071                continue;
03072             }
03073             /* if got exception */
03074             if (fds[0].revents & POLLPRI)
03075                return -1;
03076             if (!(fds[0].revents & POLLOUT)) {
03077                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
03078                continue;
03079             }
03080             res = write(fd, buf, size);
03081             if (res != size) {
03082                if (res == -1) return -1;
03083                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
03084                break;
03085             }
03086             len -= size;
03087             buf += size;
03088          }
03089          p->didtdd = 1; /* set to have done it now */    
03090       }
03091       if (*cp == 2) { /* Mate mode */
03092          if (p->tdd)
03093             tdd_free(p->tdd);
03094          p->tdd = 0;
03095          p->mate = 1;
03096          break;
03097       }     
03098       if (!p->tdd) { /* if we dont have one yet */
03099          p->tdd = tdd_new(); /* allocate one */
03100       }     
03101       break;
03102    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
03103       if (!p->dsp)
03104          break;
03105       cp = (char *) data;
03106       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
03107          *cp ? "ON" : "OFF", (int) *cp, chan->name);
03108                 p->dtmfrelax = 0;
03109                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
03110                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
03111       break;
03112    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
03113       cp = (char *) data;
03114       if (!*cp) {    
03115          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
03116          x = 0;
03117          zt_disable_ec(p);
03118       } else {    
03119          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
03120          x = 1;
03121       }
03122       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
03123          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
03124       break;
03125    case AST_OPTION_OPRMODE:  /* Operator services mode */
03126       oprmode = (struct oprmode *) data;
03127       pp = oprmode->peer->tech_pvt;
03128       p->oprmode = pp->oprmode = 0;
03129       /* setup peers */
03130       p->oprpeer = pp;
03131       pp->oprpeer = p;
03132       /* setup modes, if any */
03133       if (oprmode->mode) 
03134       {
03135          pp->oprmode = oprmode->mode;
03136          p->oprmode = -oprmode->mode;
03137       }
03138       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
03139          oprmode->mode, chan->name,oprmode->peer->name);;
03140       break;
03141    case AST_OPTION_ECHOCAN:
03142       cp = (char *) data;
03143       if (*cp) {
03144          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
03145          zt_enable_ec(p);
03146       } else {
03147          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
03148          zt_disable_ec(p);
03149       }
03150       break;
03151    }
03152    errno = 0;
03153 
03154    return 0;
03155 }
03156 
03157 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03158 {
03159    struct zt_pvt *p = chan->tech_pvt;
03160    
03161    if (!strcasecmp(data, "rxgain")) {
03162       ast_mutex_lock(&p->lock);
03163       snprintf(buf, len, "%f", p->rxgain);
03164       ast_mutex_unlock(&p->lock);   
03165    } else if (!strcasecmp(data, "txgain")) {
03166       ast_mutex_lock(&p->lock);
03167       snprintf(buf, len, "%f", p->txgain);
03168       ast_mutex_unlock(&p->lock);   
03169    } else {
03170       ast_copy_string(buf, "", len);
03171    }
03172    return 0;
03173 }
03174 
03175 
03176 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03177 {
03178    /* Unlink a specific slave or all slaves/masters from a given master */
03179    int x;
03180    int hasslaves;
03181    if (!master)
03182       return;
03183    if (needlock) {
03184       ast_mutex_lock(&master->lock);
03185       if (slave) {
03186          while (ast_mutex_trylock(&slave->lock)) {
03187             DEADLOCK_AVOIDANCE(&master->lock);
03188          }
03189       }
03190    }
03191    hasslaves = 0;
03192    for (x = 0; x < MAX_SLAVES; x++) {
03193       if (master->slaves[x]) {
03194          if (!slave || (master->slaves[x] == slave)) {
03195             /* Take slave out of the conference */
03196             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03197             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03198             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03199             master->slaves[x]->master = NULL;
03200             master->slaves[x] = NULL;
03201          } else
03202             hasslaves = 1;
03203       }
03204       if (!hasslaves)
03205          master->inconference = 0;
03206    }
03207    if (!slave) {
03208       if (master->master) {
03209          /* Take master out of the conference */
03210          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03211          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03212          hasslaves = 0;
03213          for (x = 0; x < MAX_SLAVES; x++) {
03214             if (master->master->slaves[x] == master)
03215                master->master->slaves[x] = NULL;
03216             else if (master->master->slaves[x])
03217                hasslaves = 1;
03218          }
03219          if (!hasslaves)
03220             master->master->inconference = 0;
03221       }
03222       master->master = NULL;
03223    }
03224    update_conf(master);
03225    if (needlock) {
03226       if (slave)
03227          ast_mutex_unlock(&slave->lock);
03228       ast_mutex_unlock(&master->lock);
03229    }
03230 }
03231 
03232 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03233    int x;
03234    if (!slave || !master) {
03235       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03236       return;
03237    }
03238    for (x = 0; x < MAX_SLAVES; x++) {
03239       if (!master->slaves[x]) {
03240          master->slaves[x] = slave;
03241          break;
03242       }
03243    }
03244    if (x >= MAX_SLAVES) {
03245       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03246       master->slaves[MAX_SLAVES - 1] = slave;
03247    }
03248    if (slave->master) 
03249       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03250    slave->master = master;
03251    
03252    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03253 }
03254 
03255 static void disable_dtmf_detect(struct zt_pvt *p)
03256 {
03257 #ifdef ZT_TONEDETECT
03258    int val;
03259 #endif
03260 
03261    p->ignoredtmf = 1;
03262 
03263 #ifdef ZT_TONEDETECT
03264    val = 0;
03265    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03266 #endif      
03267    if (!p->hardwaredtmf && p->dsp) {
03268       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03269       ast_dsp_set_features(p->dsp, p->dsp_features);
03270    }
03271 }
03272 
03273 static void enable_dtmf_detect(struct zt_pvt *p)
03274 {
03275 #ifdef ZT_TONEDETECT
03276    int val;
03277 #endif
03278 
03279    if (p->channel == CHAN_PSEUDO)
03280       return;
03281 
03282    p->ignoredtmf = 0;
03283 
03284 #ifdef ZT_TONEDETECT
03285    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03286    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03287 #endif      
03288    if (!p->hardwaredtmf && p->dsp) {
03289       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03290       ast_dsp_set_features(p->dsp, p->dsp_features);
03291    }
03292 }
03293 
03294 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)
03295 {
03296    struct ast_channel *who;
03297    struct zt_pvt *p0, *p1, *op0, *op1;
03298    struct zt_pvt *master = NULL, *slave = NULL;
03299    struct ast_frame *f;
03300    int inconf = 0;
03301    int nothingok = 1;
03302    int ofd0, ofd1;
03303    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03304    int os0 = -1, os1 = -1;
03305    int priority = 0;
03306    struct ast_channel *oc0, *oc1;
03307    enum ast_bridge_result res;
03308 
03309 #ifdef PRI_2BCT
03310    int triedtopribridge = 0;
03311    q931_call *q931c0 = NULL, *q931c1 = NULL;
03312 #endif
03313 
03314    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03315       There is code below to handle it properly until DTMF is actually seen,
03316       but due to currently unresolved issues it's ignored...
03317    */
03318 
03319    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03320       return AST_BRIDGE_FAILED_NOWARN;
03321 
03322    ast_mutex_lock(&c0->lock);
03323    while (ast_mutex_trylock(&c1->lock)) {
03324       DEADLOCK_AVOIDANCE(&c0->lock);
03325    }
03326 
03327    p0 = c0->tech_pvt;
03328    p1 = c1->tech_pvt;
03329    /* cant do pseudo-channels here */
03330    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03331       ast_mutex_unlock(&c0->lock);
03332       ast_mutex_unlock(&c1->lock);
03333       return AST_BRIDGE_FAILED_NOWARN;
03334    }
03335 
03336    oi0 = zt_get_index(c0, p0, 0);
03337    oi1 = zt_get_index(c1, p1, 0);
03338    if ((oi0 < 0) || (oi1 < 0)) {
03339       ast_mutex_unlock(&c0->lock);
03340       ast_mutex_unlock(&c1->lock);
03341       return AST_BRIDGE_FAILED;
03342    }
03343 
03344    op0 = p0 = c0->tech_pvt;
03345    op1 = p1 = c1->tech_pvt;
03346    ofd0 = c0->fds[0];
03347    ofd1 = c1->fds[0];
03348    oc0 = p0->owner;
03349    oc1 = p1->owner;
03350 
03351    if (ast_mutex_trylock(&p0->lock)) {
03352       /* Don't block, due to potential for deadlock */
03353       ast_mutex_unlock(&c0->lock);
03354       ast_mutex_unlock(&c1->lock);
03355       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03356       return AST_BRIDGE_RETRY;
03357    }
03358    if (ast_mutex_trylock(&p1->lock)) {
03359       /* Don't block, due to potential for deadlock */
03360       ast_mutex_unlock(&p0->lock);
03361       ast_mutex_unlock(&c0->lock);
03362       ast_mutex_unlock(&c1->lock);
03363       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03364       return AST_BRIDGE_RETRY;
03365    }
03366 
03367    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03368       if (p0->owner && p1->owner) {
03369          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03370          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03371             master = p0;
03372             slave = p1;
03373             inconf = 1;
03374          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03375             master = p1;
03376             slave = p0;
03377             inconf = 1;
03378          } else {
03379             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03380             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03381                p0->channel,
03382                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03383                p0->subs[SUB_REAL].inthreeway, p0->channel,
03384                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03385                p1->subs[SUB_REAL].inthreeway);
03386          }
03387          nothingok = 0;
03388       }
03389    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03390       if (p1->subs[SUB_THREEWAY].inthreeway) {
03391          master = p1;
03392          slave = p0;
03393          nothingok = 0;
03394       }
03395    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03396       if (p0->subs[SUB_THREEWAY].inthreeway) {
03397          master = p0;
03398          slave = p1;
03399          nothingok = 0;
03400       }
03401    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03402       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03403          don't put us in anything */
03404       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03405          master = p1;
03406          slave = p0;
03407          nothingok = 0;
03408       }
03409    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03410       /* Same as previous */
03411       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03412          master = p0;
03413          slave = p1;
03414          nothingok = 0;
03415       }
03416    }
03417    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03418       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03419    if (master && slave) {
03420       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03421          in an active threeway call with a channel that is ringing, we should
03422          indicate ringing. */
03423       if ((oi1 == SUB_THREEWAY) && 
03424           p1->subs[SUB_THREEWAY].inthreeway && 
03425           p1->subs[SUB_REAL].owner && 
03426           p1->subs[SUB_REAL].inthreeway && 
03427           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03428          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03429          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03430          os1 = p1->subs[SUB_REAL].owner->_state;
03431       } else {
03432          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03433          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03434       }
03435       if ((oi0 == SUB_THREEWAY) && 
03436           p0->subs[SUB_THREEWAY].inthreeway && 
03437           p0->subs[SUB_REAL].owner && 
03438           p0->subs[SUB_REAL].inthreeway && 
03439           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03440          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03441          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03442          os0 = p0->subs[SUB_REAL].owner->_state;
03443       } else {
03444          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03445          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03446       }
03447       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03448          if (!p0->echocanbridged || !p1->echocanbridged) {
03449             /* Disable echo cancellation if appropriate */
03450             zt_disable_ec(p0);
03451             zt_disable_ec(p1);
03452          }
03453       }
03454       zt_link(slave, master);
03455       master->inconference = inconf;
03456    } else if (!nothingok)
03457       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03458 
03459    update_conf(p0);
03460    update_conf(p1);
03461    t0 = p0->subs[SUB_REAL].inthreeway;
03462    t1 = p1->subs[SUB_REAL].inthreeway;
03463 
03464    ast_mutex_unlock(&p0->lock);
03465    ast_mutex_unlock(&p1->lock);
03466 
03467    ast_mutex_unlock(&c0->lock);
03468    ast_mutex_unlock(&c1->lock);
03469 
03470    /* Native bridge failed */
03471    if ((!master || !slave) && !nothingok) {
03472       zt_enable_ec(p0);
03473       zt_enable_ec(p1);
03474       return AST_BRIDGE_FAILED;
03475    }
03476    
03477    if (option_verbose > 2) 
03478       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03479 
03480    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03481       disable_dtmf_detect(op0);
03482 
03483    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03484       disable_dtmf_detect(op1);
03485 
03486    for (;;) {
03487       struct ast_channel *c0_priority[2] = {c0, c1};
03488       struct ast_channel *c1_priority[2] = {c1, c0};
03489 
03490       /* Here's our main loop...  Start by locking things, looking for private parts, 
03491          and then balking if anything is wrong */
03492       ast_mutex_lock(&c0->lock);
03493       while (ast_mutex_trylock(&c1->lock)) {
03494          DEADLOCK_AVOIDANCE(&c0->lock);
03495       }
03496 
03497       p0 = c0->tech_pvt;
03498       p1 = c1->tech_pvt;
03499 
03500       if (op0 == p0)
03501          i0 = zt_get_index(c0, p0, 1);
03502       if (op1 == p1)
03503          i1 = zt_get_index(c1, p1, 1);
03504       ast_mutex_unlock(&c0->lock);
03505       ast_mutex_unlock(&c1->lock);
03506 
03507       if (!timeoutms || 
03508           (op0 != p0) ||
03509           (op1 != p1) || 
03510           (ofd0 != c0->fds[0]) || 
03511           (ofd1 != c1->fds[0]) ||
03512           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03513           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03514           (oc0 != p0->owner) || 
03515           (oc1 != p1->owner) ||
03516           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03517           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03518           (oi0 != i0) ||
03519           (oi1 != i1)) {
03520          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03521             op0->channel, oi0, op1->channel, oi1);
03522          res = AST_BRIDGE_RETRY;
03523          goto return_from_bridge;
03524       }
03525 
03526 #ifdef PRI_2BCT
03527       q931c0 = p0->call;
03528       q931c1 = p1->call;
03529       if (p0->transfer && p1->transfer 
03530           && q931c0 && q931c1 
03531           && !triedtopribridge) {
03532          pri_channel_bridge(q931c0, q931c1);
03533          triedtopribridge = 1;
03534       }
03535 #endif
03536 
03537       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03538       if (!who) {
03539          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03540          continue;
03541       }
03542       f = ast_read(who);
03543       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03544          *fo = f;
03545          *rc = who;
03546          res = AST_BRIDGE_COMPLETE;
03547          goto return_from_bridge;
03548       }
03549       if (f->frametype == AST_FRAME_DTMF) {
03550          if ((who == c0) && p0->pulsedial) {
03551             ast_write(c1, f);
03552          } else if ((who == c1) && p1->pulsedial) {
03553             ast_write(c0, f);
03554          } else {
03555             *fo = f;
03556             *rc = who;
03557             res = AST_BRIDGE_COMPLETE;
03558             goto return_from_bridge;
03559          }
03560       }
03561       ast_frfree(f);
03562       
03563       /* Swap who gets priority */
03564       priority = !priority;
03565    }
03566 
03567 return_from_bridge:
03568    if (op0 == p0)
03569       zt_enable_ec(p0);
03570 
03571    if (op1 == p1)
03572       zt_enable_ec(p1);
03573 
03574    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03575       enable_dtmf_detect(op0);
03576 
03577    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03578       enable_dtmf_detect(op1);
03579 
03580    zt_unlink(slave, master, 1);
03581 
03582    return res;
03583 }
03584 
03585 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03586 {
03587    struct zt_pvt *p = newchan->tech_pvt;
03588    int x;
03589    if (newchan && newchan->tech_pvt) {
03590        p = newchan->tech_pvt;
03591    }
03592    if (!p) {
03593        if (newchan) {
03594       ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name);
03595        }
03596        return 0;
03597    }
03598    ast_mutex_lock(&p->lock);
03599    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03600    if (p->owner == oldchan) {
03601       p->owner = newchan;
03602    }
03603    for (x = 0; x < 3; x++)
03604       if (p->subs[x].owner == oldchan) {
03605          if (!x)
03606             zt_unlink(NULL, p, 0);
03607          p->subs[x].owner = newchan;
03608       }
03609    if (newchan->_state == AST_STATE_RINGING) 
03610       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03611    update_conf(p);
03612    ast_mutex_unlock(&p->lock);
03613    return 0;
03614 }
03615 
03616 static int zt_ring_phone(struct zt_pvt *p)
03617 {
03618    int x;
03619    int res;
03620    /* Make sure our transmit state is on hook */
03621    x = 0;
03622    x = ZT_ONHOOK;
03623    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03624    do {
03625       x = ZT_RING;
03626       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03627       if (res) {
03628          switch (errno) {
03629          case EBUSY:
03630          case EINTR:
03631             /* Wait just in case */
03632             usleep(10000);
03633             continue;
03634          case EINPROGRESS:
03635             res = 0;
03636             break;
03637          default:
03638             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03639             res = 0;
03640          }
03641       }
03642    } while (res);
03643    return res;
03644 }
03645 
03646 static void *ss_thread(void *data);
03647 
03648 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03649 
03650 static int attempt_transfer(struct zt_pvt *p)
03651 {
03652    /* In order to transfer, we need at least one of the channels to
03653       actually be in a call bridge.  We can't conference two applications
03654       together (but then, why would we want to?) */
03655    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03656       /* The three-way person we're about to transfer to could still be in MOH, so
03657          stop if now if appropriate */
03658       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03659          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03660       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03661          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03662       }
03663       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03664          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03665       }
03666       if (p->subs[SUB_REAL].owner->cdr) {
03667          /* Move CDR from second channel to current one */
03668          p->subs[SUB_THREEWAY].owner->cdr =
03669             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03670          p->subs[SUB_REAL].owner->cdr = NULL;
03671       }
03672       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03673          /* Move CDR from second channel's bridge to current one */
03674          p->subs[SUB_THREEWAY].owner->cdr =
03675             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03676          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03677       }
03678        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03679          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03680                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03681          return -1;
03682       }
03683       /* Orphan the channel after releasing the lock */
03684       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03685       unalloc_sub(p, SUB_THREEWAY);
03686    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03687       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03688       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03689          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03690       }
03691       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03692          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03693       }
03694       if (p->subs[SUB_THREEWAY].owner->cdr) {
03695          /* Move CDR from second channel to current one */
03696          p->subs[SUB_REAL].owner->cdr = 
03697             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03698          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03699       }
03700       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03701          /* Move CDR from second channel's bridge to current one */
03702          p->subs[SUB_REAL].owner->cdr = 
03703             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03704          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03705       }
03706       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03707          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03708                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03709          return -1;
03710       }
03711       /* Three-way is now the REAL */
03712       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03713       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03714       unalloc_sub(p, SUB_THREEWAY);
03715       /* Tell the caller not to hangup */
03716       return 1;
03717    } else {
03718       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03719                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03720       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03721       return -1;
03722    }
03723    return 0;
03724 }
03725 
03726 static int check_for_conference(struct zt_pvt *p)
03727 {
03728    ZT_CONFINFO ci;
03729    /* Fine if we already have a master, etc */
03730    if (p->master || (p->confno > -1))
03731       return 0;
03732    memset(&ci, 0, sizeof(ci));
03733    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03734       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03735       return 0;
03736    }
03737    /* If we have no master and don't have a confno, then 
03738       if we're in a conference, it's probably a MeetMe room or
03739       some such, so don't let us 3-way out! */
03740    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03741       if (option_verbose > 2) 
03742          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03743       return 1;
03744    }
03745    return 0;
03746 }
03747 
03748 static int get_alarms(struct zt_pvt *p)
03749 {
03750    int res;
03751    ZT_SPANINFO zi;
03752    memset(&zi, 0, sizeof(zi));
03753    zi.spanno = p->span;
03754    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03755    if (res < 0) {
03756       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03757       return 0;
03758    }
03759    return zi.alarms;
03760 }
03761 
03762 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03763 {
03764    struct zt_pvt *p = ast->tech_pvt;
03765    struct ast_frame *f = *dest;
03766 
03767    if (option_debug)
03768       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03769 
03770    if (p->confirmanswer) {
03771       if (option_debug)
03772          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03773       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03774          of a DTMF digit */
03775       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03776       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03777       *dest = &p->subs[index].f;
03778       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03779       p->confirmanswer = 0;
03780    } else if (p->callwaitcas) {
03781       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03782          if (option_debug)
03783             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03784          if (p->cidspill)
03785             free(p->cidspill);
03786          send_cwcidspill(p);
03787       }
03788       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03789          p->callwaitcas = 0;
03790       p->subs[index].f.frametype = AST_FRAME_NULL;
03791       p->subs[index].f.subclass = 0;
03792       *dest = &p->subs[index].f;
03793    } else if (f->subclass == 'f') {
03794       /* Fax tone -- Handle and return NULL */
03795       if ((p->callprogress & 0x6) && !p->faxhandled) {
03796          p->faxhandled++;
03797          if (strcmp(ast->exten, "fax")) {
03798             const char *target_context = S_OR(ast->macrocontext, ast->context);
03799 
03800             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03801                if (option_verbose > 2)
03802                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03803                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03804                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03805                if (ast_async_goto(ast, target_context, "fax", 1))
03806                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03807             } else {
03808                 if (option_verbose > 2)
03809                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03810             }
03811          } else if (option_debug)
03812             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03813       } else if (option_debug)
03814             ast_log(LOG_DEBUG, "Fax already handled\n");
03815       zt_confmute(p, 0);
03816       p->subs[index].f.frametype = AST_FRAME_NULL;
03817       p->subs[index].f.subclass = 0;
03818       *dest = &p->subs[index].f;
03819    } else if (f->subclass == 'm') {
03820       /* Confmute request */
03821       zt_confmute(p, 1);
03822       p->subs[index].f.frametype = AST_FRAME_NULL;
03823       p->subs[index].f.subclass = 0;
03824       *dest = &p->subs[index].f;    
03825    } else if (f->subclass == 'u') {
03826       /* Unmute */
03827       zt_confmute(p, 0);
03828       p->subs[index].f.frametype = AST_FRAME_NULL;
03829       p->subs[index].f.subclass = 0;
03830       *dest = &p->subs[index].f;    
03831    } else
03832       zt_confmute(p, 0);
03833 }
03834          
03835 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03836 {
03837    int res, x;
03838    int index, mysig;
03839    char *c;
03840    struct zt_pvt *p = ast->tech_pvt;
03841    pthread_t threadid;
03842    pthread_attr_t attr;
03843    struct ast_channel *chan;
03844    struct ast_frame *f;
03845 
03846    index = zt_get_index(ast, p, 0);
03847    mysig = p->sig;
03848    if (p->outsigmod > -1)
03849       mysig = p->outsigmod;
03850    p->subs[index].f.frametype = AST_FRAME_NULL;
03851    p->subs[index].f.subclass = 0;
03852    p->subs[index].f.datalen = 0;
03853    p->subs[index].f.samples = 0;
03854    p->subs[index].f.mallocd = 0;
03855    p->subs[index].f.offset = 0;
03856    p->subs[index].f.src = "zt_handle_event";
03857    p->subs[index].f.data = NULL;
03858    f = &p->subs[index].f;
03859 
03860    if (index < 0)
03861       return &p->subs[index].f;
03862    if (p->fake_event) {
03863       res = p->fake_event;
03864       p->fake_event = 0;
03865    } else
03866       res = zt_get_event(p->subs[index].zfd);
03867 
03868    if (option_debug)
03869       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03870 
03871    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03872       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
03873 
03874       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
03875 #ifdef HAVE_PRI
03876       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
03877          /* absorb event */
03878       } else {
03879 #endif
03880          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
03881          p->subs[index].f.subclass = res & 0xff;
03882 #ifdef HAVE_PRI
03883       }
03884 #endif
03885       zt_handle_dtmfup(ast, index, &f);
03886       return f;
03887    }
03888 
03889    if (res & ZT_EVENT_DTMFDOWN) {
03890       if (option_debug)
03891          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
03892       /* Mute conference */
03893       zt_confmute(p, 1);
03894       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
03895       p->subs[index].f.subclass = res & 0xff;
03896       return &p->subs[index].f;
03897    }
03898 
03899    switch (res) {
03900 #ifdef ZT_EVENT_EC_DISABLED
03901       case ZT_EVENT_EC_DISABLED:
03902          if (option_verbose > 2) 
03903             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
03904          p->echocanon = 0;
03905          break;
03906 #endif
03907       case ZT_EVENT_BITSCHANGED:
03908          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
03909       case ZT_EVENT_PULSE_START:
03910          /* Stop tone if there's a pulse start and the PBX isn't started */
03911          if (!ast->pbx)
03912             tone_zone_play_tone(p->subs[index].zfd, -1);
03913          break;   
03914       case ZT_EVENT_DIALCOMPLETE:
03915          if (p->inalarm) break;
03916          if ((p->radio || (p->oprmode < 0))) break;
03917          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
03918             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
03919             return NULL;
03920          }
03921          if (!x) { /* if not still dialing in driver */
03922             zt_enable_ec(p);
03923             if (p->echobreak) {
03924                zt_train_ec(p);
03925                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
03926                p->dop.op = ZT_DIAL_OP_REPLACE;
03927                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
03928                p->echobreak = 0;
03929             } else {
03930                p->dialing = 0;
03931                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
03932                   /* if thru with dialing after offhook */
03933                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
03934                      ast_setstate(ast, AST_STATE_UP);
03935                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03936                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03937                      break;
03938                   } else { /* if to state wait for offhook to dial rest */
03939                      /* we now wait for off hook */
03940                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
03941                   }
03942                }
03943                if (ast->_state == AST_STATE_DIALING) {
03944                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
03945                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
03946                   } 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)))) {
03947                      ast_setstate(ast, AST_STATE_RINGING);
03948                   } else if (!p->answeronpolarityswitch) {
03949                      ast_setstate(ast, AST_STATE_UP);
03950                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
03951                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03952                      /* If aops=0 and hops=1, this is necessary */
03953                      p->polarity = POLARITY_REV;
03954                   } else {
03955                      /* Start clean, so we can catch the change to REV polarity when party answers */
03956                      p->polarity = POLARITY_IDLE;
03957                   }
03958                }
03959             }
03960          }
03961          break;
03962       case ZT_EVENT_ALARM:
03963 #ifdef HAVE_PRI
03964          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
03965             /* T309 is not enabled : hangup calls when alarm occurs */
03966             if (p->call) {
03967                if (p->pri && p->pri->pri) {
03968                   if (!pri_grab(p, p->pri)) {
03969                      pri_hangup(p->pri->pri, p->call, -1, -1);
03970                      pri_destroycall(p->pri->pri, p->call);
03971                      p->call = NULL;
03972                      pri_rel(p->pri);
03973                   } else
03974                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
03975                } else
03976                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
03977             }
03978             if (p->owner)
03979                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
03980          }
03981          if (p->bearer)
03982             p->bearer->inalarm = 1;
03983          else
03984 #endif
03985          p->inalarm = 1;
03986          res = get_alarms(p);
03987          do {
03988             const char *alarm_str = alarm2str(res);
03989 
03990             /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
03991              * doesn't know what to do with it.  Don't confuse users with log messages. */
03992             if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
03993                p->unknown_alarm = 1;
03994                break;
03995             } else {
03996                p->unknown_alarm = 0;
03997             }
03998                
03999             ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
04000             manager_event(EVENT_FLAG_SYSTEM, "Alarm",
04001                "Alarm: %s\r\n"
04002                "Channel: %d\r\n",
04003                alarm_str, p->channel);
04004          } while (0);
04005 #ifdef HAVE_LIBPRI
04006          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
04007             /* fall through intentionally */
04008          } else {
04009             break;
04010          }
04011 #endif
04012       case ZT_EVENT_ONHOOK:
04013          if (p->radio) {
04014             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04015             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04016             break;
04017          }
04018          if (p->oprmode < 0)
04019          {
04020             if (p->oprmode != -1) break;
04021             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04022             {
04023                /* Make sure it starts ringing */
04024                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04025                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
04026                save_conference(p->oprpeer);
04027                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04028             }
04029             break;
04030          }
04031          switch (p->sig) {
04032          case SIG_FXOLS:
04033          case SIG_FXOGS:
04034          case SIG_FXOKS:
04035             p->onhooktime = time(NULL);
04036             p->msgstate = -1;
04037             /* Check for some special conditions regarding call waiting */
04038             if (index == SUB_REAL) {
04039                /* The normal line was hung up */
04040                if (p->subs[SUB_CALLWAIT].owner) {
04041                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
04042                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
04043                   if (option_verbose > 2) 
04044                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
04045                   unalloc_sub(p, SUB_CALLWAIT); 
04046 #if 0
04047                   p->subs[index].needanswer = 0;
04048                   p->subs[index].needringing = 0;
04049 #endif                  
04050                   p->callwaitingrepeat = 0;
04051                   p->cidcwexpire = 0;
04052                   p->owner = NULL;
04053                   /* Don't start streaming audio yet if the incoming call isn't up yet */
04054                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
04055                      p->dialing = 1;
04056                   zt_ring_phone(p);
04057                } else if (p->subs[SUB_THREEWAY].owner) {
04058                   unsigned int mssinceflash;
04059                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
04060                      the private structure -- not especially easy or clean */
04061                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
04062                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
04063                      ast_mutex_unlock(&p->lock);
04064                      DEADLOCK_AVOIDANCE(&ast->lock);
04065                      /* We can grab ast and p in that order, without worry.  We should make sure
04066                         nothing seriously bad has happened though like some sort of bizarre double
04067                         masquerade! */
04068                      ast_mutex_lock(&p->lock);
04069                      if (p->owner != ast) {
04070                         ast_log(LOG_WARNING, "This isn't good...\n");
04071                         return NULL;
04072                      }
04073                   }
04074                   if (!p->subs[SUB_THREEWAY].owner) {
04075                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
04076                      return NULL;
04077                   }
04078                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
04079                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
04080                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
04081                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
04082                         hanging up.  Hangup both channels now */
04083                      if (p->subs[SUB_THREEWAY].owner)
04084                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
04085                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04086                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
04087                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04088                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
04089                      if (p->transfer) {
04090                         /* In any case this isn't a threeway call anymore */
04091                         p->subs[SUB_REAL].inthreeway = 0;
04092                         p->subs[SUB_THREEWAY].inthreeway = 0;
04093                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
04094                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
04095                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04096                            /* Swap subs and dis-own channel */
04097                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
04098                            p->owner = NULL;
04099                            /* Ring the phone */
04100                            zt_ring_phone(p);
04101                         } else {
04102                            if ((res = attempt_transfer(p)) < 0) {
04103                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04104                               if (p->subs[SUB_THREEWAY].owner)
04105                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04106                            } else if (res) {
04107                               /* Don't actually hang up at this point */
04108                               if (p->subs[SUB_THREEWAY].owner)
04109                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04110                               break;
04111                            }
04112                         }
04113                      } else {
04114                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04115                         if (p->subs[SUB_THREEWAY].owner)
04116                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04117                      }
04118                   } else {
04119                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04120                      /* Swap subs and dis-own channel */
04121                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04122                      p->owner = NULL;
04123                      /* Ring the phone */
04124                      zt_ring_phone(p);
04125                   }
04126                }
04127             } else {
04128                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
04129             }
04130             /* Fall through */
04131          default:
04132             zt_disable_ec(p);
04133             return NULL;
04134          }
04135          break;
04136       case ZT_EVENT_RINGOFFHOOK:
04137          if (p->inalarm) break;
04138          if (p->oprmode < 0)
04139          {
04140             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04141             {
04142                /* Make sure it stops ringing */
04143                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04144                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
04145                restore_conference(p->oprpeer);
04146             }
04147             break;
04148          }
04149          if (p->radio)
04150          {
04151             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04152             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04153             break;
04154          }
04155          /* for E911, its supposed to wait for offhook then dial
04156             the second half of the dial string */
04157          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04158             c = strchr(p->dialdest, '/');
04159             if (c)
04160                c++;
04161             else
04162                c = p->dialdest;
04163             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04164             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04165             if (strlen(p->dop.dialstr) > 4) {
04166                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04167                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04168                p->echorest[sizeof(p->echorest) - 1] = '\0';
04169                p->echobreak = 1;
04170                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04171             } else
04172                p->echobreak = 0;
04173             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
04174                x = ZT_ONHOOK;
04175                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
04176                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
04177                return NULL;
04178                }
04179             p->dialing = 1;
04180             return &p->subs[index].f;
04181          }
04182          switch (p->sig) {
04183          case SIG_FXOLS:
04184          case SIG_FXOGS:
04185          case SIG_FXOKS:
04186             switch (ast->_state) {
04187             case AST_STATE_RINGING:
04188                zt_enable_ec(p);
04189                zt_train_ec(p);
04190                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04191                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04192                /* Make sure it stops ringing */
04193                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04194                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04195                if (p->cidspill) {
04196                   /* Cancel any running CallerID spill */
04197                   free(p->cidspill);
04198                   p->cidspill = NULL;
04199                }
04200                p->dialing = 0;
04201                p->callwaitcas = 0;
04202                if (p->confirmanswer) {
04203                   /* Ignore answer if "confirm answer" is enabled */
04204                   p->subs[index].f.frametype = AST_FRAME_NULL;
04205                   p->subs[index].f.subclass = 0;
04206                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04207                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04208                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04209                   if (res < 0) {
04210                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04211                      p->dop.dialstr[0] = '\0';
04212                      return NULL;
04213                   } else {
04214                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04215                      p->subs[index].f.frametype = AST_FRAME_NULL;
04216                      p->subs[index].f.subclass = 0;
04217                      p->dialing = 1;
04218                   }
04219                   p->dop.dialstr[0] = '\0';
04220                   ast_setstate(ast, AST_STATE_DIALING);
04221                } else
04222                   ast_setstate(ast, AST_STATE_UP);
04223                return &p->subs[index].f;
04224             case AST_STATE_DOWN:
04225                ast_setstate(ast, AST_STATE_RING);
04226                ast->rings = 1;
04227                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04228                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04229                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04230                return &p->subs[index].f;
04231             case AST_STATE_UP:
04232                /* Make sure it stops ringing */
04233                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04234                /* Okay -- probably call waiting*/
04235                if (ast_bridged_channel(p->owner))
04236                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04237                p->subs[index].needunhold = 1;
04238                break;
04239             case AST_STATE_RESERVED:
04240                /* Start up dialtone */
04241                if (has_voicemail(p))
04242                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04243                else
04244                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04245                break;
04246             default:
04247                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04248             }
04249             break;
04250          case SIG_FXSLS:
04251          case SIG_FXSGS:
04252          case SIG_FXSKS:
04253             if (ast->_state == AST_STATE_RING) {
04254                p->ringt = p->ringt_base;
04255             }
04256 
04257             /* Fall through */
04258          case SIG_EM:
04259          case SIG_EM_E1:
04260          case SIG_EMWINK:
04261          case SIG_FEATD:
04262          case SIG_FEATDMF:
04263          case SIG_FEATDMF_TA:
04264          case SIG_E911:
04265          case SIG_FGC_CAMA:
04266          case SIG_FGC_CAMAMF:
04267          case SIG_FEATB:
04268          case SIG_SF:
04269          case SIG_SFWINK:
04270          case SIG_SF_FEATD:
04271          case SIG_SF_FEATDMF:
04272          case SIG_SF_FEATB:
04273             if (ast->_state == AST_STATE_PRERING)
04274                ast_setstate(ast, AST_STATE_RING);
04275             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04276                if (option_debug)
04277                   ast_log(LOG_DEBUG, "Ring detected\n");
04278                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04279                p->subs[index].f.subclass = AST_CONTROL_RING;
04280             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04281                if (option_debug)
04282                   ast_log(LOG_DEBUG, "Line answered\n");
04283                if (p->confirmanswer) {
04284                   p->subs[index].f.frametype = AST_FRAME_NULL;
04285                   p->subs[index].f.subclass = 0;
04286                } else {
04287                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04288                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04289                   ast_setstate(ast, AST_STATE_UP);
04290                }
04291             } else if (ast->_state != AST_STATE_RING)
04292                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04293             break;
04294          default:
04295             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04296          }
04297          break;
04298 #ifdef ZT_EVENT_RINGBEGIN
04299       case ZT_EVENT_RINGBEGIN:
04300          switch (p->sig) {
04301          case SIG_FXSLS:
04302          case SIG_FXSGS:
04303          case SIG_FXSKS:
04304             if (ast->_state == AST_STATE_RING) {
04305                p->ringt = p->ringt_base;
04306             }
04307             break;
04308          }
04309          break;
04310 #endif         
04311       case ZT_EVENT_RINGEROFF:
04312          if (p->inalarm) break;
04313          if ((p->radio || (p->oprmode < 0))) break;
04314          ast->rings++;
04315          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04316             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04317             free(p->cidspill);
04318             p->cidspill = NULL;
04319             p->callwaitcas = 0;
04320          }
04321          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04322          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04323          break;
04324       case ZT_EVENT_RINGERON:
04325          break;
04326       case ZT_EVENT_NOALARM:
04327          p->inalarm = 0;
04328 #ifdef HAVE_PRI
04329          /* Extremely unlikely but just in case */
04330          if (p->bearer)
04331             p->bearer->inalarm = 0;
04332 #endif            
04333          if (!p->unknown_alarm) {
04334             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04335             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04336                "Channel: %d\r\n", p->channel);
04337          } else {
04338             p->unknown_alarm = 0;
04339          }
04340          break;
04341       case ZT_EVENT_WINKFLASH:
04342          if (p->inalarm) break;
04343          if (p->radio) break;
04344          if (p->oprmode < 0) break;
04345          if (p->oprmode > 1)
04346          {
04347             struct zt_params par;
04348 
04349             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04350             {
04351                if (!par.rxisoffhook)
04352                {
04353                   /* Make sure it stops ringing */
04354                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04355                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04356                   save_conference(p);
04357                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04358                }
04359             }
04360             break;
04361          }
04362          /* Remember last time we got a flash-hook */
04363          gettimeofday(&p->flashtime, NULL);
04364          switch (mysig) {
04365          case SIG_FXOLS:
04366          case SIG_FXOGS:
04367          case SIG_FXOKS:
04368             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04369                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04370             p->callwaitcas = 0;
04371 
04372             if (index != SUB_REAL) {
04373                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04374                goto winkflashdone;
04375             }
04376             
04377             if (p->subs[SUB_CALLWAIT].owner) {
04378                /* Swap to call-wait */
04379                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04380                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04381                p->owner = p->subs[SUB_REAL].owner;
04382                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04383                if (p->owner->_state == AST_STATE_RINGING) {
04384                   ast_setstate(p->owner, AST_STATE_UP);
04385                   p->subs[SUB_REAL].needanswer = 1;
04386                }
04387                p->callwaitingrepeat = 0;
04388                p->cidcwexpire = 0;
04389                /* Start music on hold if appropriate */
04390                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04391                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04392                      S_OR(p->mohsuggest, NULL),
04393                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04394                }
04395                p->subs[SUB_CALLWAIT].needhold = 1;
04396                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04397                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04398                      S_OR(p->mohsuggest, NULL),
04399                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04400                }
04401                p->subs[SUB_REAL].needunhold = 1;
04402             } else if (!p->subs[SUB_THREEWAY].owner) {
04403                char cid_num[256];
04404                char cid_name[256];
04405 
04406                if (!p->threewaycalling) {
04407                   /* Just send a flash if no 3-way calling */
04408                   p->subs[SUB_REAL].needflash = 1;
04409                   goto winkflashdone;
04410                } else if (!check_for_conference(p)) {
04411                   if (p->zaptrcallerid && p->owner) {
04412                      if (p->owner->cid.cid_num)
04413                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04414                      if (p->owner->cid.cid_name)
04415                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04416                   }
04417                   /* XXX This section needs much more error checking!!! XXX */
04418                   /* Start a 3-way call if feasible */
04419                   if (!((ast->pbx) ||
04420                         (ast->_state == AST_STATE_UP) ||
04421                         (ast->_state == AST_STATE_RING))) {
04422                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04423                         goto winkflashdone;
04424                   }
04425                   if (alloc_sub(p, SUB_THREEWAY)) {
04426                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04427                      goto winkflashdone;
04428                   }
04429                   /* Make new channel */
04430                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04431                   if (p->zaptrcallerid) {
04432                      if (!p->origcid_num)
04433                         p->origcid_num = ast_strdup(p->cid_num);
04434                      if (!p->origcid_name)
04435                         p->origcid_name = ast_strdup(p->cid_name);
04436                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04437                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04438                   }
04439                   /* Swap things around between the three-way and real call */
04440                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04441                   /* Disable echo canceller for better dialing */
04442                   zt_disable_ec(p);
04443                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04444                   if (res)
04445                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04446                   p->owner = chan;
04447                   pthread_attr_init(&attr);
04448                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04449                   if (!chan) {
04450                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04451                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04452                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04453                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04454                      zt_enable_ec(p);
04455                      ast_hangup(chan);
04456                   } else {
04457                      if (option_verbose > 2) 
04458                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04459                      /* Start music on hold if appropriate */
04460                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04461                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04462                            S_OR(p->mohsuggest, NULL),
04463                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04464                      }
04465                      p->subs[SUB_THREEWAY].needhold = 1;
04466                   }
04467                   pthread_attr_destroy(&attr);
04468                }
04469             } else {
04470                /* Already have a 3 way call */
04471                if (p->subs[SUB_THREEWAY].inthreeway) {
04472                   /* Call is already up, drop the last person */
04473                   if (option_debug)
04474                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04475                   /* If the primary call isn't answered yet, use it */
04476                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04477                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04478                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04479                      p->owner = p->subs[SUB_REAL].owner;
04480                   }
04481                   /* Drop the last call and stop the conference */
04482                   if (option_verbose > 2)
04483                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04484                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04485                   p->subs[SUB_REAL].inthreeway = 0;
04486                   p->subs[SUB_THREEWAY].inthreeway = 0;
04487                } else {
04488                   /* Lets see what we're up to */
04489                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04490                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04491                      int otherindex = SUB_THREEWAY;
04492 
04493                      if (option_verbose > 2)
04494                         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);
04495                      /* Put them in the threeway, and flip */
04496                      p->subs[SUB_THREEWAY].inthreeway = 1;
04497                      p->subs[SUB_REAL].inthreeway = 1;
04498                      if (ast->_state == AST_STATE_UP) {
04499                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04500                         otherindex = SUB_REAL;
04501                      }
04502                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04503                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04504                      p->subs[otherindex].needunhold = 1;
04505                      p->owner = p->subs[SUB_REAL].owner;
04506                      if (ast->_state == AST_STATE_RINGING) {
04507                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04508                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04509                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04510                      }
04511                   } else {
04512                      if (option_verbose > 2)
04513                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04514                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04515                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04516                      p->owner = p->subs[SUB_REAL].owner;
04517                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04518                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04519                      p->subs[SUB_REAL].needunhold = 1;
04520                      zt_enable_ec(p);
04521                   }
04522                      
04523                }
04524             }
04525          winkflashdone:              
04526             update_conf(p);
04527             break;
04528          case SIG_EM:
04529          case SIG_EM_E1:
04530          case SIG_EMWINK:
04531          case SIG_FEATD:
04532          case SIG_SF:
04533          case SIG_SFWINK:
04534          case SIG_SF_FEATD:
04535          case SIG_FXSLS:
04536          case SIG_FXSGS:
04537             if (p->dialing)
04538                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04539             else
04540                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04541             break;
04542          case SIG_FEATDMF_TA:
04543             switch (p->whichwink) {
04544             case 0:
04545                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04546                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04547                break;
04548             case 1:
04549                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04550                break;
04551             case 2:
04552                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04553                return NULL;
04554             }
04555             p->whichwink++;
04556             /* Fall through */
04557          case SIG_FEATDMF:
04558          case SIG_E911:
04559          case SIG_FGC_CAMAMF:
04560          case SIG_FGC_CAMA:
04561          case SIG_FEATB:
04562          case SIG_SF_FEATDMF:
04563          case SIG_SF_FEATB:
04564             /* FGD MF *Must* wait for wink */
04565             if (!ast_strlen_zero(p->dop.dialstr)) {
04566                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04567                if (res < 0) {
04568                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04569                   p->dop.dialstr[0] = '\0';
04570                   return NULL;
04571                } else 
04572                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04573             }
04574             p->dop.dialstr[0] = '\0';
04575             break;
04576          default:
04577             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04578          }
04579          break;
04580       case ZT_EVENT_HOOKCOMPLETE:
04581          if (p->inalarm) break;
04582          if ((p->radio || (p->oprmode < 0))) break;
04583          switch (mysig) {
04584          case SIG_FXSLS:  /* only interesting for FXS */
04585          case SIG_FXSGS:
04586          case SIG_FXSKS:
04587          case SIG_EM:
04588          case SIG_EM_E1:
04589          case SIG_EMWINK:
04590          case SIG_FEATD:
04591          case SIG_SF:
04592          case SIG_SFWINK:
04593          case SIG_SF_FEATD:
04594             if (!ast_strlen_zero(p->dop.dialstr)) {
04595                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04596                if (res < 0) {
04597                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04598                   p->dop.dialstr[0] = '\0';
04599                   return NULL;
04600                } else 
04601                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04602             }
04603             p->dop.dialstr[0] = '\0';
04604             p->dop.op = ZT_DIAL_OP_REPLACE;
04605             break;
04606          case SIG_FEATDMF:
04607          case SIG_FEATDMF_TA:
04608          case SIG_E911:
04609          case SIG_FGC_CAMA:
04610          case SIG_FGC_CAMAMF:
04611          case SIG_FEATB:
04612          case SIG_SF_FEATDMF:
04613          case SIG_SF_FEATB:
04614             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04615             break;
04616          default:
04617             break;
04618          }
04619          break;
04620       case ZT_EVENT_POLARITY:
04621          /*
04622           * If we get a Polarity Switch event, check to see
04623           * if we should change the polarity state and
04624           * mark the channel as UP or if this is an indication
04625           * of remote end disconnect.
04626           */
04627          if (p->polarity == POLARITY_IDLE) {
04628             p->polarity = POLARITY_REV;
04629             if (p->answeronpolarityswitch &&
04630                 ((ast->_state == AST_STATE_DIALING) ||
04631                 (ast->_state == AST_STATE_RINGING))) {
04632                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04633                ast_setstate(p->owner, AST_STATE_UP);
04634                if (p->hanguponpolarityswitch) {
04635                   gettimeofday(&p->polaritydelaytv, NULL);
04636                }
04637             } else
04638                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04639          } 
04640          /* Removed else statement from here as it was preventing hangups from ever happening*/
04641          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04642          if (p->hanguponpolarityswitch &&
04643             (p->polarityonanswerdelay > 0) &&
04644                 (p->polarity == POLARITY_REV) &&
04645             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04646                                 /* Added log_debug information below to provide a better indication of what is going on */
04647             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) );
04648          
04649             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04650                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04651                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04652                p->polarity = POLARITY_IDLE;
04653             } else {
04654                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);
04655             }
04656          } else {
04657             p->polarity = POLARITY_IDLE;
04658             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04659          }
04660                         /* Added more log_debug information below to provide a better indication of what is going on */
04661          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) );
04662          break;
04663       default:
04664          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04665    }
04666    return &p->subs[index].f;
04667 }
04668 
04669 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04670 {
04671    struct zt_pvt *p = ast->tech_pvt;
04672    int res;
04673    int usedindex=-1;
04674    int index;
04675    struct ast_frame *f;
04676 
04677 
04678    index = zt_get_index(ast, p, 1);
04679    
04680    p->subs[index].f.frametype = AST_FRAME_NULL;
04681    p->subs[index].f.datalen = 0;
04682    p->subs[index].f.samples = 0;
04683    p->subs[index].f.mallocd = 0;
04684    p->subs[index].f.offset = 0;
04685    p->subs[index].f.subclass = 0;
04686    p->subs[index].f.delivery = ast_tv(0,0);
04687    p->subs[index].f.src = "zt_exception";
04688    p->subs[index].f.data = NULL;
04689    
04690    
04691    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04692       /* If nobody owns us, absorb the event appropriately, otherwise
04693          we loop indefinitely.  This occurs when, during call waiting, the
04694          other end hangs up our channel so that it no longer exists, but we
04695          have neither FLASH'd nor ONHOOK'd to signify our desire to
04696          change to the other channel. */
04697       if (p->fake_event) {
04698          res = p->fake_event;
04699          p->fake_event = 0;
04700       } else
04701          res = zt_get_event(p->subs[SUB_REAL].zfd);
04702       /* Switch to real if there is one and this isn't something really silly... */
04703       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04704          (res != ZT_EVENT_HOOKCOMPLETE)) {
04705          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04706          p->owner = p->subs[SUB_REAL].owner;
04707          if (p->owner && ast_bridged_channel(p->owner))
04708             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04709          p->subs[SUB_REAL].needunhold = 1;
04710       }
04711       switch (res) {
04712       case ZT_EVENT_ONHOOK:
04713          zt_disable_ec(p);
04714          if (p->owner) {
04715             if (option_verbose > 2) 
04716                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04717             zt_ring_phone(p);
04718             p->callwaitingrepeat = 0;
04719             p->cidcwexpire = 0;
04720          } else
04721             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04722          update_conf(p);
04723          break;
04724       case ZT_EVENT_RINGOFFHOOK:
04725          zt_enable_ec(p);
04726          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04727          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04728             p->subs[SUB_REAL].needanswer = 1;
04729             p->dialing = 0;
04730          }
04731          break;
04732       case ZT_EVENT_HOOKCOMPLETE:
04733       case ZT_EVENT_RINGERON:
04734       case ZT_EVENT_RINGEROFF:
04735          /* Do nothing */
04736          break;
04737       case ZT_EVENT_WINKFLASH:
04738          gettimeofday(&p->flashtime, NULL);
04739          if (p->owner) {
04740             if (option_verbose > 2) 
04741                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04742             if (p->owner->_state != AST_STATE_UP) {
04743                /* Answer if necessary */
04744                usedindex = zt_get_index(p->owner, p, 0);
04745                if (usedindex > -1) {
04746                   p->subs[usedindex].needanswer = 1;
04747                }
04748                ast_setstate(p->owner, AST_STATE_UP);
04749             }
04750             p->callwaitingrepeat = 0;
04751             p->cidcwexpire = 0;
04752             if (ast_bridged_channel(p->owner))
04753                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04754             p->subs[SUB_REAL].needunhold = 1;
04755          } else
04756             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04757          update_conf(p);
04758          break;
04759       default:
04760          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04761       }
04762       f = &p->subs[index].f;
04763       return f;
04764    }
04765    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04766       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04767    /* If it's not us, return NULL immediately */
04768    if (ast != p->owner) {
04769       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04770       f = &p->subs[index].f;
04771       return f;
04772    }
04773    f = zt_handle_event(ast);
04774    return f;
04775 }
04776 
04777 static struct ast_frame *zt_exception(struct ast_channel *ast)
04778 {
04779    struct zt_pvt *p = ast->tech_pvt;
04780    struct ast_frame *f;
04781    ast_mutex_lock(&p->lock);
04782    f = __zt_exception(ast);
04783    ast_mutex_unlock(&p->lock);
04784    return f;
04785 }
04786 
04787 static struct ast_frame  *zt_read(struct ast_channel *ast)
04788 {
04789    struct zt_pvt *p = ast->tech_pvt;
04790    int res;
04791    int index;
04792    void *readbuf;
04793    struct ast_frame *f;
04794    
04795 
04796    ast_mutex_lock(&p->lock);
04797    
04798    index = zt_get_index(ast, p, 0);
04799    
04800    /* Hang up if we don't really exist */
04801    if (index < 0) {
04802       ast_log(LOG_WARNING, "We dont exist?\n");
04803       ast_mutex_unlock(&p->lock);
04804       return NULL;
04805    }
04806    
04807    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04808 
04809    p->subs[index].f.frametype = AST_FRAME_NULL;
04810    p->subs[index].f.datalen = 0;
04811    p->subs[index].f.samples = 0;
04812    p->subs[index].f.mallocd = 0;
04813    p->subs[index].f.offset = 0;
04814    p->subs[index].f.subclass = 0;
04815    p->subs[index].f.delivery = ast_tv(0,0);
04816    p->subs[index].f.src = "zt_read";
04817    p->subs[index].f.data = NULL;
04818    
04819    /* make sure it sends initial key state as first frame */
04820    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04821    {
04822       ZT_PARAMS ps;
04823 
04824       ps.channo = p->channel;
04825       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04826          ast_mutex_unlock(&p->lock);
04827          return NULL;
04828       }
04829       p->firstradio = 1;
04830       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04831       if (ps.rxisoffhook)
04832       {
04833          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04834       }
04835       else
04836       {
04837          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04838       }
04839       ast_mutex_unlock(&p->lock);
04840       return &p->subs[index].f;
04841    }
04842    if (p->ringt == 1) {
04843       ast_mutex_unlock(&p->lock);
04844       return NULL;
04845    }
04846    else if (p->ringt > 0) 
04847       p->ringt--;
04848 
04849    if (p->subs[index].needringing) {
04850       /* Send ringing frame if requested */
04851       p->subs[index].needringing = 0;
04852       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04853       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04854       ast_setstate(ast, AST_STATE_RINGING);
04855       ast_mutex_unlock(&p->lock);
04856       return &p->subs[index].f;
04857    }
04858 
04859    if (p->subs[index].needbusy) {
04860       /* Send busy frame if requested */
04861       p->subs[index].needbusy = 0;
04862       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04863       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04864       ast_mutex_unlock(&p->lock);
04865       return &p->subs[index].f;
04866    }
04867 
04868    if (p->subs[index].needcongestion) {
04869       /* Send congestion frame if requested */
04870       p->subs[index].needcongestion = 0;
04871       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04872       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04873       ast_mutex_unlock(&p->lock);
04874       return &p->subs[index].f;
04875    }
04876 
04877    if (p->subs[index].needcallerid) {
04878       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04879                      S_OR(p->lastcid_name, NULL),
04880                      S_OR(p->lastcid_num, NULL)
04881                      );
04882       p->subs[index].needcallerid = 0;
04883    }
04884    
04885    if (p->subs[index].needanswer) {
04886       /* Send answer frame if requested */
04887       p->subs[index].needanswer = 0;
04888       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04889       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04890       ast_mutex_unlock(&p->lock);
04891       return &p->subs[index].f;
04892    }  
04893    
04894    if (p->subs[index].needflash) {
04895       /* Send answer frame if requested */
04896       p->subs[index].needflash = 0;
04897       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04898       p->subs[index].f.subclass = AST_CONTROL_FLASH;
04899       ast_mutex_unlock(&p->lock);
04900       return &p->subs[index].f;
04901    }  
04902    
04903    if (p->subs[index].needhold) {
04904       /* Send answer frame if requested */
04905       p->subs[index].needhold = 0;
04906       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04907       p->subs[index].f.subclass = AST_CONTROL_HOLD;
04908       ast_mutex_unlock(&p->lock);
04909       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
04910       return &p->subs[index].f;
04911    }  
04912    
04913    if (p->subs[index].needunhold) {
04914       /* Send answer frame if requested */
04915       p->subs[index].needunhold = 0;
04916       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04917       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
04918       ast_mutex_unlock(&p->lock);
04919       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
04920       return &p->subs[index].f;
04921    }  
04922    
04923    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
04924       if (!p->subs[index].linear) {
04925          p->subs[index].linear = 1;
04926          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04927          if (res) 
04928             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
04929       }
04930    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
04931          (ast->rawreadformat == AST_FORMAT_ALAW)) {
04932       if (p->subs[index].linear) {
04933          p->subs[index].linear = 0;
04934          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
04935          if (res) 
04936             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
04937       }
04938    } else {
04939       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
04940       ast_mutex_unlock(&p->lock);
04941       return NULL;
04942    }
04943    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
04944    CHECK_BLOCKING(ast);
04945    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04946    ast_clear_flag(ast, AST_FLAG_BLOCKING);
04947    /* Check for hangup */
04948    if (res < 0) {
04949       f = NULL;
04950       if (res == -1)  {
04951          if (errno == EAGAIN) {
04952             /* Return "NULL" frame if there is nobody there */
04953             ast_mutex_unlock(&p->lock);
04954             return &p->subs[index].f;
04955          } else if (errno == ELAST) {
04956             f = __zt_exception(ast);
04957          } else
04958             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
04959       }
04960       ast_mutex_unlock(&p->lock);
04961       return f;
04962    }
04963    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
04964       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
04965       f = __zt_exception(ast);
04966       ast_mutex_unlock(&p->lock);
04967       return f;
04968    }
04969    if (p->tdd) { /* if in TDD mode, see if we receive that */
04970       int c;
04971 
04972       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
04973       if (c < 0) {
04974          ast_log(LOG_DEBUG,"tdd_feed failed\n");
04975          ast_mutex_unlock(&p->lock);
04976          return NULL;
04977       }
04978       if (c) { /* if a char to return */
04979          p->subs[index].f.subclass = 0;
04980          p->subs[index].f.frametype = AST_FRAME_TEXT;
04981          p->subs[index].f.mallocd = 0;
04982          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
04983          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
04984          p->subs[index].f.datalen = 1;
04985          *((char *) p->subs[index].f.data) = c;
04986          ast_mutex_unlock(&p->lock);
04987          return &p->subs[index].f;
04988       }
04989    }
04990    /* Ensure the CW timer decrements only on a single subchannel */
04991    if (p->callwaitingrepeat && zt_get_index(ast, p, 1) == SUB_REAL) {
04992       p->callwaitingrepeat--;
04993    }
04994    if (p->cidcwexpire)
04995       p->cidcwexpire--;
04996    /* Repeat callwaiting */
04997    if (p->callwaitingrepeat == 1) {
04998       p->callwaitrings++;
04999       zt_callwait(ast);
05000    }
05001    /* Expire CID/CW */
05002    if (p->cidcwexpire == 1) {
05003       if (option_verbose > 2)
05004          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
05005       restore_conference(p);
05006    }
05007    if (p->subs[index].linear) {
05008       p->subs[index].f.datalen = READ_SIZE * 2;
05009    } else 
05010       p->subs[index].f.datalen = READ_SIZE;
05011 
05012    /* Handle CallerID Transmission */
05013    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
05014       send_callerid(p);
05015    }
05016 
05017    p->subs[index].f.frametype = AST_FRAME_VOICE;
05018    p->subs[index].f.subclass = ast->rawreadformat;
05019    p->subs[index].f.samples = READ_SIZE;
05020    p->subs[index].f.mallocd = 0;
05021    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05022    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
05023 #if 0
05024    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
05025 #endif   
05026    if (p->dialing || /* Transmitting something */
05027       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
05028       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
05029       ) {
05030       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
05031          don't send anything */
05032       p->subs[index].f.frametype = AST_FRAME_NULL;
05033       p->subs[index].f.subclass = 0;
05034       p->subs[index].f.samples = 0;
05035       p->subs[index].f.mallocd = 0;
05036       p->subs[index].f.offset = 0;
05037       p->subs[index].f.data = NULL;
05038       p->subs[index].f.datalen= 0;
05039    }
05040    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
05041       /* Perform busy detection. etc on the zap line */
05042       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
05043       if (f) {
05044          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
05045             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
05046                /* Treat this as a "hangup" instead of a "busy" on the assumption that
05047                   a busy  */
05048                f = NULL;
05049             }
05050          } else if (f->frametype == AST_FRAME_DTMF) {
05051 #ifdef HAVE_PRI
05052             if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) {
05053                /* Don't accept in-band DTMF when in overlap dial mode
05054                   or when in non-overlap overlapdialing mode ... */
05055                f->frametype = AST_FRAME_NULL;
05056                f->subclass = 0;
05057             }
05058 #endif            
05059             /* DSP clears us of being pulse */
05060             p->pulsedial = 0;
05061          }
05062       }
05063    } else 
05064       f = &p->subs[index].f; 
05065 
05066    if (f && (f->frametype == AST_FRAME_DTMF))
05067       zt_handle_dtmfup(ast, index, &f);
05068 
05069    /* If we have a fake_event, trigger exception to handle it */
05070    if (p->fake_event)
05071       ast_set_flag(ast, AST_FLAG_EXCEPTION);
05072 
05073    ast_mutex_unlock(&p->lock);
05074    return f;
05075 }
05076 
05077 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
05078 {
05079    int sent=0;
05080    int size;
05081    int res;
05082    int fd;
05083    fd = p->subs[index].zfd;
05084    while (len) {
05085       size = len;
05086       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
05087          size = (linear ? READ_SIZE * 2 : READ_SIZE);
05088       res = write(fd, buf, size);
05089       if (res != size) {
05090          if (option_debug)
05091             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
05092          return sent;
05093       }
05094       len -= size;
05095       buf += size;
05096    }
05097    return sent;
05098 }
05099 
05100 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
05101 {
05102    struct zt_pvt *p = ast->tech_pvt;
05103    int res;
05104    int index;
05105    index = zt_get_index(ast, p, 0);
05106    if (index < 0) {
05107       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
05108       return -1;
05109    }
05110 
05111 #if 0
05112 #ifdef HAVE_PRI
05113    ast_mutex_lock(&p->lock);
05114    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05115       if (p->pri->pri) {      
05116          if (!pri_grab(p, p->pri)) {
05117                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05118                pri_rel(p->pri);
05119          } else
05120                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05121       }
05122       p->proceeding=1;
05123    }
05124    ast_mutex_unlock(&p->lock);
05125 #endif
05126 #endif
05127    /* Write a frame of (presumably voice) data */
05128    if (frame->frametype != AST_FRAME_VOICE) {
05129       if (frame->frametype == AST_FRAME_TEXT) {
05130          ast_log(LOG_NOTICE, "text\n");
05131       } else if (frame->frametype != AST_FRAME_IMAGE)
05132          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
05133       return 0;
05134    }
05135    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
05136        (frame->subclass != AST_FORMAT_ULAW) &&
05137        (frame->subclass != AST_FORMAT_ALAW)) {
05138       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
05139       return -1;
05140    }
05141    if (p->dialing) {
05142       if (option_debug)
05143          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
05144       return 0;
05145    }
05146    if (!p->owner) {
05147       if (option_debug)
05148          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
05149       return 0;
05150    }
05151    if (p->cidspill) {
05152       if (option_debug)
05153          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
05154       return 0;
05155    }
05156    /* Return if it's not valid data */
05157    if (!frame->data || !frame->datalen)
05158       return 0;
05159 
05160    if (frame->subclass == AST_FORMAT_SLINEAR) {
05161       if (!p->subs[index].linear) {
05162          p->subs[index].linear = 1;
05163          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05164          if (res)
05165             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05166       }
05167       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05168    } else {
05169       /* x-law already */
05170       if (p->subs[index].linear) {
05171          p->subs[index].linear = 0;
05172          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05173          if (res)
05174             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05175       }
05176       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05177    }
05178    if (res < 0) {
05179       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05180       return -1;
05181    } 
05182    return 0;
05183 }
05184 
05185 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05186 {
05187    struct zt_pvt *p = chan->tech_pvt;
05188    int res=-1;
05189    int index;
05190    int func = ZT_FLASH;
05191    ast_mutex_lock(&p->lock);
05192    index = zt_get_index(chan, p, 0);
05193    if (option_debug)
05194       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05195    if (index == SUB_REAL) {
05196       switch (condition) {
05197       case AST_CONTROL_BUSY:
05198 #ifdef HAVE_PRI
05199          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05200             chan->hangupcause = AST_CAUSE_USER_BUSY;
05201             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05202             res = 0;
05203          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05204             if (p->pri->pri) {      
05205                if (!pri_grab(p, p->pri)) {
05206                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05207                   pri_rel(p->pri);
05208                }
05209                else
05210                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05211             }
05212             p->progress = 1;
05213             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05214          } else
05215 #endif
05216             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05217          break;
05218       case AST_CONTROL_RINGING:
05219 #ifdef HAVE_PRI
05220          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05221             if (p->pri->pri) {      
05222                if (!pri_grab(p, p->pri)) {
05223                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05224                   pri_rel(p->pri);
05225                }
05226                else
05227                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05228             }
05229             p->alerting = 1;
05230          }
05231 #endif
05232          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05233          if (chan->_state != AST_STATE_UP) {
05234             if ((chan->_state != AST_STATE_RING) ||
05235                ((p->sig != SIG_FXSKS) &&
05236                 (p->sig != SIG_FXSLS) &&
05237                 (p->sig != SIG_FXSGS)))
05238                ast_setstate(chan, AST_STATE_RINGING);
05239          }
05240          break;
05241       case AST_CONTROL_PROCEEDING:
05242          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05243 #ifdef HAVE_PRI
05244          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05245             if (p->pri->pri) {      
05246                if (!pri_grab(p, p->pri)) {
05247                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05248                   pri_rel(p->pri);
05249                }
05250                else
05251                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05252             }
05253             p->proceeding = 1;
05254          }
05255 #endif
05256          /* don't continue in ast_indicate */
05257          res = 0;
05258          break;
05259       case AST_CONTROL_PROGRESS:
05260          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05261 #ifdef HAVE_PRI
05262          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05263          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05264             if (p->pri->pri) {      
05265                if (!pri_grab(p, p->pri)) {
05266                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05267                   pri_rel(p->pri);
05268                }
05269                else
05270                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05271             }
05272             p->progress = 1;
05273          }
05274 #endif
05275          /* don't continue in ast_indicate */
05276          res = 0;
05277          break;
05278       case AST_CONTROL_CONGESTION:
05279          chan->hangupcause = AST_CAUSE_CONGESTION;
05280 #ifdef HAVE_PRI
05281          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05282             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05283             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05284             res = 0;
05285          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05286             if (p->pri) {     
05287                if (!pri_grab(p, p->pri)) {
05288                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05289                   pri_rel(p->pri);
05290                } else
05291                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05292             }
05293             p->progress = 1;
05294             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05295          } else
05296 #endif
05297             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05298          break;
05299       case AST_CONTROL_HOLD:
05300 #ifdef HAVE_PRI
05301          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05302             if (!pri_grab(p, p->pri)) {
05303                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05304                pri_rel(p->pri);
05305             } else
05306                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05307          } else
05308 #endif
05309             ast_moh_start(chan, data, p->mohinterpret);
05310          break;
05311       case AST_CONTROL_UNHOLD:
05312 #ifdef HAVE_PRI
05313          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05314             if (!pri_grab(p, p->pri)) {
05315                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05316                pri_rel(p->pri);
05317             } else
05318                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05319          } else
05320 #endif
05321             ast_moh_stop(chan);
05322          break;
05323       case AST_CONTROL_RADIO_KEY:
05324          if (p->radio) 
05325              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05326          res = 0;
05327          break;
05328       case AST_CONTROL_RADIO_UNKEY:
05329          if (p->radio)
05330              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05331          res = 0;
05332          break;
05333       case AST_CONTROL_FLASH:
05334          /* flash hookswitch */
05335          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05336             /* Clear out the dial buffer */
05337             p->dop.dialstr[0] = '\0';
05338             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05339                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05340                   chan->name, strerror(errno));
05341             } else
05342                res = 0;
05343          } else
05344             res = 0;
05345          break;
05346       case AST_CONTROL_SRCUPDATE:
05347          res = 0;
05348          break;
05349       case -1:
05350          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05351          break;
05352       }
05353    } else
05354       res = 0;
05355    ast_mutex_unlock(&p->lock);
05356    return res;
05357 }
05358 
05359 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05360 {
05361    struct ast_channel *tmp;
05362    int deflaw;
05363    int res;
05364    int x,y;
05365    int features;
05366    char *b2 = NULL;
05367    ZT_PARAMS ps;
05368    if (i->subs[index].owner) {
05369       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05370       return NULL;
05371    }
05372    y = 1;
05373    do {
05374       if (b2)
05375          free(b2);
05376 #ifdef HAVE_PRI
05377       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05378          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05379       else
05380 #endif
05381       if (i->channel == CHAN_PSEUDO)
05382          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05383       else  
05384          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05385       for (x = 0; x < 3; x++) {
05386          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05387             break;
05388       }
05389       y++;
05390    } while (x < 3);
05391    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05392    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05393       free(b2);
05394    if (!tmp)
05395       return NULL;
05396    tmp->tech = &zap_tech;
05397    ps.channo = i->channel;
05398    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05399    if (res) {
05400       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05401       ps.curlaw = ZT_LAW_MULAW;
05402    }
05403    if (ps.curlaw == ZT_LAW_ALAW)
05404       deflaw = AST_FORMAT_ALAW;
05405    else
05406       deflaw = AST_FORMAT_ULAW;
05407    if (law) {
05408       if (law == ZT_LAW_ALAW)
05409          deflaw = AST_FORMAT_ALAW;
05410       else
05411          deflaw = AST_FORMAT_ULAW;
05412    }
05413    tmp->fds[0] = i->subs[index].zfd;
05414    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05415    /* Start out assuming ulaw since it's smaller :) */
05416    tmp->rawreadformat = deflaw;
05417    tmp->readformat = deflaw;
05418    tmp->rawwriteformat = deflaw;
05419    tmp->writeformat = deflaw;
05420    i->subs[index].linear = 0;
05421    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05422    features = 0;
05423    if (index == SUB_REAL) {
05424       if (i->busydetect && CANBUSYDETECT(i))
05425          features |= DSP_FEATURE_BUSY_DETECT;
05426       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05427          features |= DSP_FEATURE_CALL_PROGRESS;
05428       if ((!i->outgoing && (i->callprogress & 4)) || 
05429           (i->outgoing && (i->callprogress & 2))) {
05430          features |= DSP_FEATURE_FAX_DETECT;
05431       }
05432 #ifdef ZT_TONEDETECT
05433       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05434       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05435 #endif      
05436          i->hardwaredtmf = 0;
05437          features |= DSP_FEATURE_DTMF_DETECT;
05438 #ifdef ZT_TONEDETECT
05439       } else if (NEED_MFDETECT(i)) {
05440          i->hardwaredtmf = 1;
05441          features |= DSP_FEATURE_DTMF_DETECT;
05442       }
05443 #endif
05444    }
05445    if (features) {
05446       if (i->dsp) {
05447          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05448       } else {
05449          if (i->channel != CHAN_PSEUDO)
05450             i->dsp = ast_dsp_new();
05451          else
05452             i->dsp = NULL;
05453          if (i->dsp) {
05454             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05455 #ifdef HAVE_PRI
05456             /* We cannot do progress detection until receives PROGRESS message */
05457             if (i->outgoing && (i->sig == SIG_PRI)) {
05458                /* Remember requested DSP features, don't treat
05459                   talking as ANSWER */
05460                features = 0;
05461             }
05462 #endif
05463             ast_dsp_set_features(i->dsp, features);
05464             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05465             if (!ast_strlen_zero(progzone))
05466                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05467             if (i->busydetect && CANBUSYDETECT(i)) {
05468                ast_dsp_set_busy_count(i->dsp, i->busycount);
05469                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05470             }
05471          }
05472       }
05473    }
05474       
05475    if (state == AST_STATE_RING)
05476       tmp->rings = 1;
05477    tmp->tech_pvt = i;
05478 #ifdef HAVE_PRI
05479    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) {
05480 #else
05481    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05482 #endif
05483       /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */
05484       tmp->callgroup = i->callgroup;
05485       tmp->pickupgroup = i->pickupgroup;
05486    }
05487    if (!ast_strlen_zero(i->language))
05488       ast_string_field_set(tmp, language, i->language);
05489    if (!i->owner)
05490       i->owner = tmp;
05491    if (!ast_strlen_zero(i->accountcode))
05492       ast_string_field_set(tmp, accountcode, i->accountcode);
05493    if (i->amaflags)
05494       tmp->amaflags = i->amaflags;
05495    i->subs[index].owner = tmp;
05496    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05497    ast_string_field_set(tmp, call_forward, i->call_forward);
05498    /* If we've been told "no ADSI" then enforce it */
05499    if (!i->adsi)
05500       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05501    if (!ast_strlen_zero(i->exten))
05502       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05503    if (!ast_strlen_zero(i->rdnis))
05504       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05505    if (!ast_strlen_zero(i->dnid))
05506       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05507 
05508    /* Don't use ast_set_callerid() here because it will
05509     * generate a needless NewCallerID event */
05510 #ifdef PRI_ANI
05511    if (!ast_strlen_zero(i->cid_ani))
05512       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05513    else  
05514       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05515 #else
05516    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05517 #endif
05518    tmp->cid.cid_pres = i->callingpres;
05519    tmp->cid.cid_ton = i->cid_ton;
05520 #ifdef HAVE_PRI
05521    tmp->transfercapability = transfercapability;
05522    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05523    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05524       i->digital = 1;
05525    /* Assume calls are not idle calls unless we're told differently */
05526    i->isidlecall = 0;
05527    i->alreadyhungup = 0;
05528 #endif
05529    /* clear the fake event in case we posted one before we had ast_channel */
05530    i->fake_event = 0;
05531    /* Assure there is no confmute on this channel */
05532    zt_confmute(i, 0);
05533    /* Configure the new channel jb */
05534    ast_jb_configure(tmp, &global_jbconf);
05535    if (startpbx) {
05536       if (ast_pbx_start(tmp)) {
05537          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05538          ast_hangup(tmp);
05539          i->owner = NULL;
05540          return NULL;
05541       }
05542    }
05543 
05544    ast_module_ref(ast_module_info->self);
05545    
05546    return tmp;
05547 }
05548 
05549 
05550 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05551 {
05552    char c;
05553 
05554    *str = 0; /* start with empty output buffer */
05555    for (;;)
05556    {
05557       /* Wait for the first digit (up to specified ms). */
05558       c = ast_waitfordigit(chan, ms);
05559       /* if timeout, hangup or error, return as such */
05560       if (c < 1)
05561          return c;
05562       *str++ = c;
05563       *str = 0;
05564       if (strchr(term, c))
05565          return 1;
05566    }
05567 }
05568 
05569 static int zt_wink(struct zt_pvt *p, int index)
05570 {
05571    int j;
05572    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05573    for (;;)
05574    {
05575          /* set bits of interest */
05576       j = ZT_IOMUX_SIGEVENT;
05577           /* wait for some happening */
05578       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05579          /* exit loop if we have it */
05580       if (j & ZT_IOMUX_SIGEVENT) break;
05581    }
05582      /* get the event info */
05583    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05584    return 0;
05585 }
05586 
05587 static void *ss_thread(void *data)
05588 {
05589    struct ast_channel *chan = data;
05590    struct zt_pvt *p = chan->tech_pvt;
05591    char exten[AST_MAX_EXTENSION] = "";
05592    char exten2[AST_MAX_EXTENSION] = "";
05593    unsigned char buf[256];
05594    char dtmfcid[300];
05595    char dtmfbuf[300];
05596    struct callerid_state *cs = NULL;
05597    char *name = NULL, *number = NULL;
05598    int distMatches;
05599    int curRingData[3];
05600    int receivedRingT;
05601    int counter1;
05602    int counter;
05603    int samples = 0;
05604    struct ast_smdi_md_message *smdi_msg = NULL;
05605    int flags;
05606    int i;
05607    int timeout;
05608    int getforward = 0;
05609    char *s1, *s2;
05610    int len = 0;
05611    int res;
05612    int index;
05613    int network;
05614 
05615    /* in the bizarre case where the channel has become a zombie before we
05616       even get started here, abort safely
05617    */
05618    if (!p) {
05619       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05620       ast_hangup(chan);
05621       return NULL;
05622    }
05623 
05624    if (option_verbose > 2) 
05625       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05626    index = zt_get_index(chan, p, 1);
05627    if (index < 0) {
05628       ast_log(LOG_WARNING, "Huh?\n");
05629       ast_hangup(chan);
05630       return NULL;
05631    }
05632    if (p->dsp)
05633       ast_dsp_digitreset(p->dsp);
05634    switch (p->sig) {
05635 #ifdef HAVE_PRI
05636    case SIG_PRI:
05637       /* Now loop looking for an extension */
05638       ast_copy_string(exten, p->exten, sizeof(exten));
05639       len = strlen(exten);
05640       res = 0;
05641       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05642          if (len && !ast_ignore_pattern(chan->context, exten)) {
05643             tone_zone_play_tone(p->subs[index].zfd, -1);
05644          } else {
05645             network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP;
05646             if (network) {
05647                 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05648             } else {
05649                 /* cpe be quiet */
05650                 tone_zone_play_tone(p->subs[index].zfd, -1);
05651             }
05652          }
05653          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05654             timeout = matchdigittimeout;
05655          else
05656             timeout = gendigittimeout;
05657          res = ast_waitfordigit(chan, timeout);
05658          if (res < 0) {
05659             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05660             ast_hangup(chan);
05661             return NULL;
05662          } else if (res) {
05663             exten[len++] = res;
05664             exten[len] = '\0';
05665          } else
05666             break;
05667       }
05668       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05669       if (ast_strlen_zero(exten)) {
05670          if (option_verbose > 2)
05671             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05672          exten[0] = 's';
05673          exten[1] = '\0';
05674       }
05675       tone_zone_play_tone(p->subs[index].zfd, -1);
05676       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05677          /* Start the real PBX */
05678          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05679          if (p->dsp) ast_dsp_digitreset(p->dsp);
05680          zt_enable_ec(p);
05681          ast_setstate(chan, AST_STATE_RING);
05682          res = ast_pbx_run(chan);
05683          if (res) {
05684             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05685          }
05686       } else {
05687          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05688          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05689          ast_hangup(chan);
05690          p->exten[0] = '\0';
05691          /* Since we send release complete here, we won't get one */
05692          p->call = NULL;
05693       }
05694       return NULL;
05695       break;
05696 #endif
05697    case SIG_FEATD:
05698    case SIG_FEATDMF:
05699    case SIG_FEATDMF_TA:
05700    case SIG_E911:
05701    case SIG_FGC_CAMAMF:
05702    case SIG_FEATB:
05703    case SIG_EMWINK:
05704    case SIG_SF_FEATD:
05705    case SIG_SF_FEATDMF:
05706    case SIG_SF_FEATB:
05707    case SIG_SFWINK:
05708       if (zt_wink(p, index))  
05709          return NULL;
05710       /* Fall through */
05711    case SIG_EM:
05712    case SIG_EM_E1:
05713    case SIG_SF:
05714    case SIG_FGC_CAMA:
05715       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05716       if (p->dsp)
05717          ast_dsp_digitreset(p->dsp);
05718       /* set digit mode appropriately */
05719       if (p->dsp) {
05720          if (NEED_MFDETECT(p))
05721             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05722          else 
05723             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05724       }
05725       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05726       /* Wait for the first digit only if immediate=no */
05727       if (!p->immediate)
05728          /* Wait for the first digit (up to 5 seconds). */
05729          res = ast_waitfordigit(chan, 5000);
05730       else
05731          res = 0;
05732       if (res > 0) {
05733          /* save first char */
05734          dtmfbuf[0] = res;
05735          switch (p->sig) {
05736          case SIG_FEATD:
05737          case SIG_SF_FEATD:
05738             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05739             if (res > 0)
05740                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05741             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05742             break;
05743          case SIG_FEATDMF_TA:
05744             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05745             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05746             if (zt_wink(p, index)) return NULL;
05747             dtmfbuf[0] = 0;
05748             /* Wait for the first digit (up to 5 seconds). */
05749             res = ast_waitfordigit(chan, 5000);
05750             if (res <= 0) break;
05751             dtmfbuf[0] = res;
05752             /* fall through intentionally */
05753          case SIG_FEATDMF:
05754          case SIG_E911:
05755          case SIG_FGC_CAMAMF:
05756          case SIG_SF_FEATDMF:
05757             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05758             /* if international caca, do it again to get real ANO */
05759             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05760             {
05761                if (zt_wink(p, index)) return NULL;
05762                dtmfbuf[0] = 0;
05763                /* Wait for the first digit (up to 5 seconds). */
05764                res = ast_waitfordigit(chan, 5000);
05765                if (res <= 0) break;
05766                dtmfbuf[0] = res;
05767                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05768             }
05769             if (res > 0) {
05770                /* if E911, take off hook */
05771                if (p->sig == SIG_E911)
05772                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05773                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05774             }
05775             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05776             break;
05777          case SIG_FEATB:
05778          case SIG_SF_FEATB:
05779             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05780             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05781             break;
05782          case SIG_EMWINK:
05783             /* if we received a '*', we are actually receiving Feature Group D
05784                dial syntax, so use that mode; otherwise, fall through to normal
05785                mode
05786             */
05787             if (res == '*') {
05788                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05789                if (res > 0)
05790                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05791                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05792                break;
05793             }
05794          default:
05795             /* If we got the first digit, get the rest */
05796             len = 1;
05797             dtmfbuf[len] = '\0';
05798             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05799                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05800                   timeout = matchdigittimeout;
05801                } else {
05802                   timeout = gendigittimeout;
05803                }
05804                res = ast_waitfordigit(chan, timeout);
05805                if (res < 0) {
05806                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05807                   ast_hangup(chan);
05808                   return NULL;
05809                } else if (res) {
05810                   dtmfbuf[len++] = res;
05811                   dtmfbuf[len] = '\0';
05812                } else {
05813                   break;
05814                }
05815             }
05816             break;
05817          }
05818       }
05819       if (res == -1) {
05820          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05821          ast_hangup(chan);
05822          return NULL;
05823       } else if (res < 0) {
05824          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05825          ast_hangup(chan);
05826          return NULL;
05827       }
05828 
05829       if (p->sig == SIG_FGC_CAMA) {
05830          char anibuf[100];
05831 
05832          if (ast_safe_sleep(chan,1000) == -1) {
05833                            ast_hangup(chan);
05834                            return NULL;
05835          }
05836                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05837                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05838                         res = my_getsigstr(chan, anibuf, "#", 10000);
05839                         if ((res > 0) && (strlen(anibuf) > 2)) {
05840             if (anibuf[strlen(anibuf) - 1] == '#')
05841                anibuf[strlen(anibuf) - 1] = 0;
05842             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05843          }
05844                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05845       }
05846 
05847       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05848       if (ast_strlen_zero(exten))
05849          ast_copy_string(exten, "s", sizeof(exten));
05850       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05851          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05852          if (exten[0] == '*') {
05853             char *stringp=NULL;
05854             ast_copy_string(exten2, exten, sizeof(exten2));
05855             /* Parse out extension and callerid */
05856             stringp=exten2 +1;
05857             s1 = strsep(&stringp, "*");
05858             s2 = strsep(&stringp, "*");
05859             if (s2) {
05860                if (!ast_strlen_zero(p->cid_num))
05861                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05862                else
05863                   ast_set_callerid(chan, s1, NULL, s1);
05864                ast_copy_string(exten, s2, sizeof(exten));
05865             } else
05866                ast_copy_string(exten, s1, sizeof(exten));
05867          } else if (p->sig == SIG_FEATD)
05868             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05869       }
05870       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05871          if (exten[0] == '*') {
05872             char *stringp=NULL;
05873             ast_copy_string(exten2, exten, sizeof(exten2));
05874             /* Parse out extension and callerid */
05875             stringp=exten2 +1;
05876             s1 = strsep(&stringp, "#");
05877             s2 = strsep(&stringp, "#");
05878             if (s2) {
05879                if (!ast_strlen_zero(p->cid_num))
05880                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05881                else
05882                   if (*(s1 + 2))
05883                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05884                ast_copy_string(exten, s2 + 1, sizeof(exten));
05885             } else
05886                ast_copy_string(exten, s1 + 2, sizeof(exten));
05887          } else
05888             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05889       }
05890       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05891          if (exten[0] == '*') {
05892             char *stringp=NULL;
05893             ast_copy_string(exten2, exten, sizeof(exten2));
05894             /* Parse out extension and callerid */
05895             stringp=exten2 +1;
05896             s1 = strsep(&stringp, "#");
05897             s2 = strsep(&stringp, "#");
05898             if (s2 && (*(s2 + 1) == '0')) {
05899                if (*(s2 + 2))
05900                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
05901             }
05902             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
05903             else ast_copy_string(exten, "911", sizeof(exten));
05904          } else
05905             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05906       }
05907       if (p->sig == SIG_FEATB) {
05908          if (exten[0] == '*') {
05909             char *stringp=NULL;
05910             ast_copy_string(exten2, exten, sizeof(exten2));
05911             /* Parse out extension and callerid */
05912             stringp=exten2 +1;
05913             s1 = strsep(&stringp, "#");
05914             ast_copy_string(exten, exten2 + 1, sizeof(exten));
05915          } else
05916             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05917       }
05918       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05919          zt_wink(p, index);
05920                         /* some switches require a minimum guard time between
05921                            the last FGD wink and something that answers
05922                            immediately. This ensures it */
05923                         if (ast_safe_sleep(chan,100)) return NULL;
05924       }
05925       zt_enable_ec(p);
05926       if (NEED_MFDETECT(p)) {
05927          if (p->dsp) {
05928             if (!p->hardwaredtmf)
05929                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
05930             else {
05931                ast_dsp_free(p->dsp);
05932                p->dsp = NULL;
05933             }
05934          }
05935       }
05936 
05937       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
05938          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05939          if (p->dsp) ast_dsp_digitreset(p->dsp);
05940          res = ast_pbx_run(chan);
05941          if (res) {
05942             ast_log(LOG_WARNING, "PBX exited non-zero\n");
05943             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05944          }
05945          return NULL;
05946       } else {
05947          if (option_verbose > 2)
05948             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
05949          sleep(2);
05950          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
05951          if (res < 0)
05952             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
05953          else
05954             sleep(1);
05955          res = ast_streamfile(chan, "ss-noservice", chan->language);
05956          if (res >= 0)
05957             ast_waitstream(chan, "");
05958          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05959          ast_hangup(chan);
05960          return NULL;
05961       }
05962       break;
05963    case SIG_FXOLS:
05964    case SIG_FXOGS:
05965    case SIG_FXOKS:
05966       /* Read the first digit */
05967       timeout = firstdigittimeout;
05968       /* If starting a threeway call, never timeout on the first digit so someone
05969          can use flash-hook as a "hold" feature */
05970       if (p->subs[SUB_THREEWAY].owner) 
05971          timeout = 999999;
05972       while (len < AST_MAX_EXTENSION-1) {
05973          /* Read digit unless it's supposed to be immediate, in which case the
05974             only answer is 's' */
05975          if (p->immediate) 
05976             res = 's';
05977          else
05978             res = ast_waitfordigit(chan, timeout);
05979          timeout = 0;
05980          if (res < 0) {
05981             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05982             res = tone_zone_play_tone(p->subs[index].zfd, -1);
05983             ast_hangup(chan);
05984             return NULL;
05985          } else if (res)  {
05986             exten[len++]=res;
05987             exten[len] = '\0';
05988          }
05989          if (!ast_ignore_pattern(chan->context, exten))
05990             tone_zone_play_tone(p->subs[index].zfd, -1);
05991          else
05992             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05993          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
05994             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05995                if (getforward) {
05996                   /* Record this as the forwarding extension */
05997                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
05998                   if (option_verbose > 2)
05999                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
06000                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06001                   if (res)
06002                      break;
06003                   usleep(500000);
06004                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06005                   sleep(1);
06006                   memset(exten, 0, sizeof(exten));
06007                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
06008                   len = 0;
06009                   getforward = 0;
06010                } else  {
06011                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06012                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06013                   if (!ast_strlen_zero(p->cid_num)) {
06014                      if (!p->hidecallerid)
06015                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
06016                      else
06017                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
06018                   }
06019                   if (!ast_strlen_zero(p->cid_name)) {
06020                      if (!p->hidecallerid)
06021                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
06022                   }
06023                   ast_setstate(chan, AST_STATE_RING);
06024                   zt_enable_ec(p);
06025                   res = ast_pbx_run(chan);
06026                   if (res) {
06027                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
06028                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06029                   }
06030                   return NULL;
06031                }
06032             } else {
06033                /* It's a match, but they just typed a digit, and there is an ambiguous match,
06034                   so just set the timeout to matchdigittimeout and wait some more */
06035                timeout = matchdigittimeout;
06036             }
06037          } else if (res == 0) {
06038             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
06039             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06040             zt_wait_event(p->subs[index].zfd);
06041             ast_hangup(chan);
06042             return NULL;
06043          } else if (p->callwaiting && !strcmp(exten, "*70")) {
06044             if (option_verbose > 2) 
06045                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
06046             /* Disable call waiting if enabled */
06047             p->callwaiting = 0;
06048             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06049             if (res) {
06050                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06051                   chan->name, strerror(errno));
06052             }
06053             len = 0;
06054             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
06055             memset(exten, 0, sizeof(exten));
06056             timeout = firstdigittimeout;
06057                
06058          } else if (!strcmp(exten,ast_pickup_ext())) {
06059             /* Scan all channels and see if there are any
06060              * ringing channels that have call groups
06061              * that equal this channels pickup group  
06062              */
06063             if (index == SUB_REAL) {
06064                /* Switch us from Third call to Call Wait */
06065                if (p->subs[SUB_THREEWAY].owner) {
06066                   /* If you make a threeway call and the *8# a call, it should actually 
06067                      look like a callwait */
06068                   alloc_sub(p, SUB_CALLWAIT);   
06069                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
06070                   unalloc_sub(p, SUB_THREEWAY);
06071                }
06072                zt_enable_ec(p);
06073                if (ast_pickup_call(chan)) {
06074                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
06075                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06076                   zt_wait_event(p->subs[index].zfd);
06077                }
06078                ast_hangup(chan);
06079                return NULL;
06080             } else {
06081                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
06082                ast_hangup(chan);
06083                return NULL;
06084             }
06085             
06086          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
06087             if (option_verbose > 2) 
06088                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
06089             /* Disable Caller*ID if enabled */
06090             p->hidecallerid = 1;
06091             if (chan->cid.cid_num)
06092                free(chan->cid.cid_num);
06093             chan->cid.cid_num = NULL;
06094             if (chan->cid.cid_name)
06095                free(chan->cid.cid_name);
06096             chan->cid.cid_name = NULL;
06097             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06098             if (res) {
06099                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06100                   chan->name, strerror(errno));
06101             }
06102             len = 0;
06103             memset(exten, 0, sizeof(exten));
06104             timeout = firstdigittimeout;
06105          } else if (p->callreturn && !strcmp(exten, "*69")) {
06106             res = 0;
06107             if (!ast_strlen_zero(p->lastcid_num)) {
06108                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
06109             }
06110             if (!res)
06111                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06112             break;
06113          } else if (!strcmp(exten, "*78")) {
06114             /* Do not disturb */
06115             if (option_verbose > 2)
06116                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
06117             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06118                      "Channel: Zap/%d\r\n"
06119                      "Status: enabled\r\n", p->channel);
06120             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06121             p->dnd = 1;
06122             getforward = 0;
06123             memset(exten, 0, sizeof(exten));
06124             len = 0;
06125          } else if (!strcmp(exten, "*79")) {
06126             /* Do not disturb */
06127             if (option_verbose > 2)
06128                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
06129             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06130                      "Channel: Zap/%d\r\n"
06131                      "Status: disabled\r\n", p->channel);
06132             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06133             p->dnd = 0;
06134             getforward = 0;
06135             memset(exten, 0, sizeof(exten));
06136             len = 0;
06137          } else if (p->cancallforward && !strcmp(exten, "*72")) {
06138             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06139             getforward = 1;
06140             memset(exten, 0, sizeof(exten));
06141             len = 0;
06142          } else if (p->cancallforward && !strcmp(exten, "*73")) {
06143             if (option_verbose > 2)
06144                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
06145             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06146             memset(p->call_forward, 0, sizeof(p->call_forward));
06147             getforward = 0;
06148             memset(exten, 0, sizeof(exten));
06149             len = 0;
06150          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
06151                   p->subs[SUB_THREEWAY].owner &&
06152                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
06153             /* This is a three way call, the main call being a real channel, 
06154                and we're parking the first call. */
06155             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
06156             if (option_verbose > 2)
06157                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
06158             break;
06159          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
06160             if (option_verbose > 2)
06161                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
06162             res = ast_db_put("blacklist", p->lastcid_num, "1");
06163             if (!res) {
06164                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06165                memset(exten, 0, sizeof(exten));
06166                len = 0;
06167             }
06168          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
06169             if (option_verbose > 2) 
06170                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
06171             /* Enable Caller*ID if enabled */
06172             p->hidecallerid = 0;
06173             if (chan->cid.cid_num)
06174                free(chan->cid.cid_num);
06175             chan->cid.cid_num = NULL;
06176             if (chan->cid.cid_name)
06177                free(chan->cid.cid_name);
06178             chan->cid.cid_name = NULL;
06179             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
06180             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06181             if (res) {
06182                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06183                   chan->name, strerror(errno));
06184             }
06185             len = 0;
06186             memset(exten, 0, sizeof(exten));
06187             timeout = firstdigittimeout;
06188          } else if (!strcmp(exten, "*0")) {
06189             struct ast_channel *nbridge = 
06190                p->subs[SUB_THREEWAY].owner;
06191             struct zt_pvt *pbridge = NULL;
06192               /* set up the private struct of the bridged one, if any */
06193             if (nbridge && ast_bridged_channel(nbridge)) 
06194                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06195             if (nbridge && pbridge && 
06196                 (nbridge->tech == &zap_tech) && 
06197                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06198                 ISTRUNK(pbridge)) {
06199                int func = ZT_FLASH;
06200                /* Clear out the dial buffer */
06201                p->dop.dialstr[0] = '\0';
06202                /* flash hookswitch */
06203                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06204                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06205                      nbridge->name, strerror(errno));
06206                }
06207                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06208                unalloc_sub(p, SUB_THREEWAY);
06209                p->owner = p->subs[SUB_REAL].owner;
06210                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06211                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06212                ast_hangup(chan);
06213                return NULL;
06214             } else {
06215                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06216                zt_wait_event(p->subs[index].zfd);
06217                tone_zone_play_tone(p->subs[index].zfd, -1);
06218                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06219                unalloc_sub(p, SUB_THREEWAY);
06220                p->owner = p->subs[SUB_REAL].owner;
06221                ast_hangup(chan);
06222                return NULL;
06223             }              
06224          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06225                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06226             if (option_debug)
06227                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);
06228             break;
06229          }
06230          if (!timeout)
06231             timeout = gendigittimeout;
06232          if (len && !ast_ignore_pattern(chan->context, exten))
06233             tone_zone_play_tone(p->subs[index].zfd, -1);
06234       }
06235       break;
06236    case SIG_FXSLS:
06237    case SIG_FXSGS:
06238    case SIG_FXSKS:
06239 #ifdef HAVE_PRI
06240       if (p->pri) {
06241          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06242          struct ast_frame *f;
06243          int res;
06244          time_t start;
06245 
06246          time(&start);
06247          ast_setstate(chan, AST_STATE_RING);
06248          while (time(NULL) < start + 3) {
06249             res = ast_waitfor(chan, 1000);
06250             if (res) {
06251                f = ast_read(chan);
06252                if (!f) {
06253                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06254                   ast_hangup(chan);
06255                   return NULL;
06256                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06257                   res = 1;
06258                } else
06259                   res = 0;
06260                ast_frfree(f);
06261                if (res) {
06262                   ast_log(LOG_DEBUG, "Got ring!\n");
06263                   res = 0;
06264                   break;
06265                }
06266             }
06267          }
06268       }
06269 #endif
06270       /* check for SMDI messages */
06271       if (p->use_smdi && p->smdi_iface) {
06272          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06273 
06274          if (smdi_msg != NULL) {
06275             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06276 
06277             if (smdi_msg->type == 'B')
06278                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06279             else if (smdi_msg->type == 'N')
06280                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06281 
06282             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06283          } else {
06284             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06285          }
06286       }
06287 
06288       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06289             number = smdi_msg->calling_st;
06290 
06291       /* If we want caller id, we're in a prering state due to a polarity reversal
06292        * and we're set to use a polarity reversal to trigger the start of caller id,
06293        * grab the caller id and wait for ringing to start... */
06294       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06295          /* If set to use DTMF CID signalling, listen for DTMF */
06296          if (p->cid_signalling == CID_SIG_DTMF) {
06297             int i = 0;
06298             cs = NULL;
06299             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06300                "channel %s\n", chan->name);
06301             zt_setlinear(p->subs[index].zfd, 0);
06302             res = 2000;
06303             for (;;) {
06304                struct ast_frame *f;
06305                res = ast_waitfor(chan, res);
06306                if (res <= 0) {
06307                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06308                      "Exiting simple switch\n");
06309                   ast_hangup(chan);
06310                   return NULL;
06311                } 
06312                f = ast_read(chan);
06313                if (!f)
06314                   break;
06315                if (f->frametype == AST_FRAME_DTMF) {
06316                   dtmfbuf[i++] = f->subclass;
06317                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06318                   res = 2000;
06319                }
06320                ast_frfree(f);
06321                if (chan->_state == AST_STATE_RING ||
06322                    chan->_state == AST_STATE_RINGING) 
06323                   break; /* Got ring */
06324             }
06325             dtmfbuf[i] = '\0';
06326             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06327             /* Got cid and ring. */
06328             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06329             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06330             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06331                dtmfcid, flags);
06332             /* If first byte is NULL, we have no cid */
06333             if (!ast_strlen_zero(dtmfcid)) 
06334                number = dtmfcid;
06335             else
06336                number = NULL;
06337          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06338          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06339             cs = callerid_new(p->cid_signalling);
06340             if (cs) {
06341                samples = 0;
06342 #if 1
06343                bump_gains(p);
06344 #endif            
06345                /* Take out of linear mode for Caller*ID processing */
06346                zt_setlinear(p->subs[index].zfd, 0);
06347                
06348                /* First we wait and listen for the Caller*ID */
06349                for (;;) {  
06350                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06351                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06352                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06353                      callerid_free(cs);
06354                      ast_hangup(chan);
06355                      return NULL;
06356                   }
06357                   if (i & ZT_IOMUX_SIGEVENT) {
06358                      res = zt_get_event(p->subs[index].zfd);
06359                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06360 
06361                      if (p->cid_signalling == CID_SIG_V23_JP) {
06362 #ifdef ZT_EVENT_RINGBEGIN
06363                         if (res == ZT_EVENT_RINGBEGIN) {
06364                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06365                            usleep(1);
06366                         }
06367 #endif
06368                      } else {
06369                         res = 0;
06370                         break;
06371                      }
06372                   } else if (i & ZT_IOMUX_READ) {
06373                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06374                      if (res < 0) {
06375                         if (errno != ELAST) {
06376                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06377                            callerid_free(cs);
06378                            ast_hangup(chan);
06379                            return NULL;
06380                         }
06381                         break;
06382                      }
06383                      samples += res;
06384 
06385                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06386                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06387                      } else {
06388                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06389                      }
06390 
06391                      if (res < 0) {
06392                         ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
06393                         break;
06394                      } else if (res)
06395                         break;
06396                      else if (samples > (8000 * 10))
06397                         break;
06398                   }
06399                }
06400                if (res == 1) {
06401                   callerid_get(cs, &name, &number, &flags);
06402                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06403                }
06404 
06405                if (p->cid_signalling == CID_SIG_V23_JP) {
06406                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06407                   usleep(1);
06408                   res = 4000;
06409                } else {
06410 
06411                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06412                   res = 2000;
06413                }
06414 
06415                for (;;) {
06416                   struct ast_frame *f;
06417                   res = ast_waitfor(chan, res);
06418                   if (res <= 0) {
06419                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06420                         "Exiting simple switch\n");
06421                      ast_hangup(chan);
06422                      return NULL;
06423                   } 
06424                   f = ast_read(chan);
06425                   ast_frfree(f);
06426                   if (chan->_state == AST_STATE_RING ||
06427                       chan->_state == AST_STATE_RINGING) 
06428                      break; /* Got ring */
06429                }
06430    
06431                /* We must have a ring by now, so, if configured, lets try to listen for
06432                 * distinctive ringing */ 
06433                if (p->usedistinctiveringdetection == 1) {
06434                   len = 0;
06435                   distMatches = 0;
06436                   /* Clear the current ring data array so we dont have old data in it. */
06437                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06438                      curRingData[receivedRingT] = 0;
06439                   receivedRingT = 0;
06440                   counter = 0;
06441                   counter1 = 0;
06442                   /* Check to see if context is what it should be, if not set to be. */
06443                   if (strcmp(p->context,p->defcontext) != 0) {
06444                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06445                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06446                   }
06447       
06448                   for (;;) {  
06449                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06450                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06451                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06452                         callerid_free(cs);
06453                         ast_hangup(chan);
06454                         return NULL;
06455                      }
06456                      if (i & ZT_IOMUX_SIGEVENT) {
06457                         res = zt_get_event(p->subs[index].zfd);
06458                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06459                         res = 0;
06460                         /* Let us detect distinctive ring */
06461       
06462                         curRingData[receivedRingT] = p->ringt;
06463       
06464                         if (p->ringt < p->ringt_base/2)
06465                            break;
06466                         /* Increment the ringT counter so we can match it against
06467                            values in zapata.conf for distinctive ring */
06468                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06469                            break;
06470                      } else if (i & ZT_IOMUX_READ) {
06471                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06472                         if (res < 0) {
06473                            if (errno != ELAST) {
06474                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06475                               callerid_free(cs);
06476                               ast_hangup(chan);
06477                               return NULL;
06478                            }
06479                            break;
06480                         }
06481                         if (p->ringt) 
06482                            p->ringt--;
06483                         if (p->ringt == 1) {
06484                            res = -1;
06485                            break;
06486                         }
06487                      }
06488                   }
06489                   if (option_verbose > 2)
06490                      /* this only shows up if you have n of the dring patterns filled in */
06491                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06492    
06493                   for (counter = 0; counter < 3; counter++) {
06494                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06495                      channel */
06496                      distMatches = 0;
06497                      for (counter1 = 0; counter1 < 3; counter1++) {
06498                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06499                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06500                            distMatches++;
06501                         }
06502                      }
06503                      if (distMatches == 3) {
06504                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06505                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06506                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06507                         if (option_verbose > 2)
06508                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06509                         break;
06510                      }
06511                   }
06512                }
06513                /* Restore linear mode (if appropriate) for Caller*ID processing */
06514                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06515 #if 1
06516                restore_gains(p);
06517 #endif            
06518             } else
06519                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06520          } else {
06521             ast_log(LOG_WARNING, "Channel %s in prering "
06522                "state, but I have nothing to do. "
06523                "Terminating simple switch, should be "
06524                "restarted by the actual ring.\n", 
06525                chan->name);
06526             ast_hangup(chan);
06527             return NULL;
06528          }
06529       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06530          /* FSK Bell202 callerID */
06531          cs = callerid_new(p->cid_signalling);
06532          if (cs) {
06533 #if 1
06534             bump_gains(p);
06535 #endif            
06536             samples = 0;
06537             len = 0;
06538             distMatches = 0;
06539             /* Clear the current ring data array so we dont have old data in it. */
06540             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06541                curRingData[receivedRingT] = 0;
06542             receivedRingT = 0;
06543             counter = 0;
06544             counter1 = 0;
06545             /* Check to see if context is what it should be, if not set to be. */
06546             if (strcmp(p->context,p->defcontext) != 0) {
06547                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06548                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06549             }
06550 
06551             /* Take out of linear mode for Caller*ID processing */
06552             zt_setlinear(p->subs[index].zfd, 0);
06553             for (;;) {  
06554                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06555                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06556                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06557                   callerid_free(cs);
06558                   ast_hangup(chan);
06559                   return NULL;
06560                }
06561                if (i & ZT_IOMUX_SIGEVENT) {
06562                   res = zt_get_event(p->subs[index].zfd);
06563                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06564                   /* If we get a PR event, they hung up while processing calerid */
06565                   if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
06566                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
06567                      p->polarity = POLARITY_IDLE;
06568                      callerid_free(cs);
06569                      ast_hangup(chan);
06570                      return NULL;
06571                   }
06572                   res = 0;
06573                   /* Let us detect callerid when the telco uses distinctive ring */
06574 
06575                   curRingData[receivedRingT] = p->ringt;
06576 
06577                   if (p->ringt < p->ringt_base/2)
06578                      break;
06579                   /* Increment the ringT counter so we can match it against
06580                      values in zapata.conf for distinctive ring */
06581                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06582                      break;
06583                } else if (i & ZT_IOMUX_READ) {
06584                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06585                   if (res < 0) {
06586                      if (errno != ELAST) {
06587                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06588                         callerid_free(cs);
06589                         ast_hangup(chan);
06590                         return NULL;
06591                      }
06592                      break;
06593                   }
06594                   if (p->ringt) 
06595                      p->ringt--;
06596                   if (p->ringt == 1) {
06597                      res = -1;
06598                      break;
06599                   }
06600                   samples += res;
06601                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06602                   if (res < 0) {
06603                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06604                      break;
06605                   } else if (res)
06606                      break;
06607                   else if (samples > (8000 * 10))
06608                      break;
06609                }
06610             }
06611             if (res == 1) {
06612                callerid_get(cs, &name, &number, &flags);
06613                if (option_debug)
06614                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06615             }
06616             if (distinctiveringaftercid == 1) {
06617                /* Clear the current ring data array so we dont have old data in it. */
06618                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06619                   curRingData[receivedRingT] = 0;
06620                }
06621                receivedRingT = 0;
06622                if (option_verbose > 2)
06623                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06624                for (;;) {
06625                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06626                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06627                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06628                      callerid_free(cs);
06629                      ast_hangup(chan);
06630                      return NULL;
06631                   }
06632                   if (i & ZT_IOMUX_SIGEVENT) {
06633                      res = zt_get_event(p->subs[index].zfd);
06634                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06635                      res = 0;
06636                      /* Let us detect callerid when the telco uses distinctive ring */
06637 
06638                      curRingData[receivedRingT] = p->ringt;
06639 
06640                      if (p->ringt < p->ringt_base/2)
06641                         break;
06642                      /* Increment the ringT counter so we can match it against
06643                         values in zapata.conf for distinctive ring */
06644                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06645                         break;
06646                   } else if (i & ZT_IOMUX_READ) {
06647                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06648                      if (res < 0) {
06649                         if (errno != ELAST) {
06650                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06651                            callerid_free(cs);
06652                            ast_hangup(chan);
06653                            return NULL;
06654                         }
06655                         break;
06656                      }
06657                   if (p->ringt)
06658                      p->ringt--;
06659                      if (p->ringt == 1) {
06660                         res = -1;
06661                         break;
06662                      }
06663                   }
06664                }
06665             }
06666             if (p->usedistinctiveringdetection == 1) {
06667                if (option_verbose > 2)
06668                   /* this only shows up if you have n of the dring patterns filled in */
06669                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06670 
06671                for (counter = 0; counter < 3; counter++) {
06672                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06673                   channel */
06674                   if (option_verbose > 2)
06675                      /* this only shows up if you have n of the dring patterns filled in */
06676                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06677                         p->drings.ringnum[counter].ring[0],
06678                         p->drings.ringnum[counter].ring[1],
06679                         p->drings.ringnum[counter].ring[2]);
06680                   distMatches = 0;
06681                   for (counter1 = 0; counter1 < 3; counter1++) {
06682                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06683                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06684                         distMatches++;
06685                      }
06686                   }
06687                   if (distMatches == 3) {
06688                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06689                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06690                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06691                      if (option_verbose > 2)
06692                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06693                      break;
06694                   }
06695                }
06696             }
06697             /* Restore linear mode (if appropriate) for Caller*ID processing */
06698             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06699 #if 1
06700             restore_gains(p);
06701 #endif            
06702             if (res < 0) {
06703                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06704             }
06705          } else
06706             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06707       }
06708       else
06709          cs = NULL;
06710 
06711       if (number)
06712          ast_shrink_phone_number(number);
06713       ast_set_callerid(chan, number, name, number);
06714 
06715       if (smdi_msg)
06716          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06717 
06718       if (cs)
06719          callerid_free(cs);
06720 
06721       ast_setstate(chan, AST_STATE_RING);
06722       chan->rings = 1;
06723       p->ringt = p->ringt_base;
06724       res = ast_pbx_run(chan);
06725       if (res) {
06726          ast_hangup(chan);
06727          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06728       }
06729       return NULL;
06730    default:
06731       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06732       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06733       if (res < 0)
06734             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06735    }
06736    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06737    if (res < 0)
06738          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06739    ast_hangup(chan);
06740    return NULL;
06741 }
06742 
06743 /* destroy a zaptel channel, identified by its number */
06744 static int zap_destroy_channel_bynum(int channel)
06745 {
06746    struct zt_pvt *tmp = NULL;
06747    struct zt_pvt *prev = NULL;
06748 
06749    tmp = iflist;
06750    while (tmp) {
06751       if (tmp->channel == channel) {
06752          destroy_channel(prev, tmp, 1);
06753          return RESULT_SUCCESS;
06754       }
06755       prev = tmp;
06756       tmp = tmp->next;
06757    }
06758    return RESULT_FAILURE;
06759 }
06760 
06761 static int handle_init_event(struct zt_pvt *i, int event)
06762 {
06763    int res;
06764    pthread_t threadid;
06765    pthread_attr_t attr;
06766    struct ast_channel *chan;
06767    pthread_attr_init(&attr);
06768    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06769    /* Handle an event on a given channel for the monitor thread. */
06770    switch (event) {
06771    case ZT_EVENT_NONE:
06772    case ZT_EVENT_BITSCHANGED:
06773       break;
06774    case ZT_EVENT_WINKFLASH:
06775    case ZT_EVENT_RINGOFFHOOK:
06776       if (i->inalarm) break;
06777       if (i->radio) break;
06778       /* Got a ring/answer.  What kind of channel are we? */
06779       switch (i->sig) {
06780       case SIG_FXOLS:
06781       case SIG_FXOGS:
06782       case SIG_FXOKS:
06783          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06784          if (res && (errno == EBUSY))
06785             break;
06786          if (i->cidspill) {
06787             /* Cancel VMWI spill */
06788             free(i->cidspill);
06789             i->cidspill = NULL;
06790          }
06791          if (i->immediate) {
06792             zt_enable_ec(i);
06793             /* The channel is immediately up.  Start right away */
06794             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06795             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06796             if (!chan) {
06797                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06798                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06799                if (res < 0)
06800                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06801             }
06802          } else {
06803             /* Check for callerid, digits, etc */
06804             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06805             if (chan) {
06806                if (has_voicemail(i))
06807                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06808                else
06809                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06810                if (res < 0) 
06811                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06812                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06813                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06814                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06815                   if (res < 0)
06816                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06817                   ast_hangup(chan);
06818                }
06819             } else
06820                ast_log(LOG_WARNING, "Unable to create channel\n");
06821          }
06822          break;
06823       case SIG_FXSLS:
06824       case SIG_FXSGS:
06825       case SIG_FXSKS:
06826             i->ringt = i->ringt_base;
06827             /* Fall through */
06828       case SIG_EMWINK:
06829       case SIG_FEATD:
06830       case SIG_FEATDMF:
06831       case SIG_FEATDMF_TA:
06832       case SIG_E911:
06833       case SIG_FGC_CAMA:
06834       case SIG_FGC_CAMAMF:
06835       case SIG_FEATB:
06836       case SIG_EM:
06837       case SIG_EM_E1:
06838       case SIG_SFWINK:
06839       case SIG_SF_FEATD:
06840       case SIG_SF_FEATDMF:
06841       case SIG_SF_FEATB:
06842       case SIG_SF:
06843             /* Check for callerid, digits, etc */
06844             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06845             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06846                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06847                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06848                if (res < 0)
06849                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06850                ast_hangup(chan);
06851             } else if (!chan) {
06852                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06853             }
06854             break;
06855       default:
06856          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06857          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06858          if (res < 0)
06859                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06860          return -1;
06861       }
06862       break;
06863    case ZT_EVENT_NOALARM:
06864       i->inalarm = 0;
06865       if (!i->unknown_alarm) {
06866 #ifdef HAVE_PRI
06867           if (i->pri) {
06868          if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06869              /* dont annoy BRI TE mode users with layer2layer alarms */
06870          } else {
06871 #endif
06872          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06873          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06874             "Channel: %d\r\n", i->channel);
06875 #ifdef HAVE_PRI
06876          }
06877           }
06878 #endif
06879 
06880       } else {
06881          i->unknown_alarm = 0;
06882       }
06883       break;
06884    case ZT_EVENT_ALARM:
06885       i->inalarm = 1;
06886       res = get_alarms(i);
06887       do {
06888 #ifdef HAVE_PRI
06889           if (i->pri) {
06890          if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06891              /* dont annoy BRI TE mode users with layer2layer alarms */
06892          } else {
06893 #endif
06894              const char *alarm_str = alarm2str(res);
06895 
06896          /* hack alert!  Zaptel 1.4 now exposes FXO battery as an alarm, but asterisk 1.4
06897           * doesn't know what to do with it.  Don't confuse users with log messages. */
06898          if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
06899             i->unknown_alarm = 1;
06900             break;
06901          } else {
06902             i->unknown_alarm = 0;
06903          }
06904 
06905          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm_str);
06906          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06907             "Alarm: %s\r\n"
06908             "Channel: %d\r\n",
06909             alarm_str, i->channel);
06910 #ifdef HAVE_PRI
06911          }
06912           }
06913 #endif
06914       } while (0);
06915       /* fall thru intentionally */
06916    case ZT_EVENT_ONHOOK:
06917       if (i->radio)
06918          break;
06919       /* Back on hook.  Hang up. */
06920       switch (i->sig) {
06921       case SIG_FXOLS:
06922       case SIG_FXOGS:
06923       case SIG_FEATD:
06924       case SIG_FEATDMF:
06925       case SIG_FEATDMF_TA:
06926       case SIG_E911:
06927       case SIG_FGC_CAMA:
06928       case SIG_FGC_CAMAMF:
06929       case SIG_FEATB:
06930       case SIG_EM:
06931       case SIG_EM_E1:
06932       case SIG_EMWINK:
06933       case SIG_SF_FEATD:
06934       case SIG_SF_FEATDMF:
06935       case SIG_SF_FEATB:
06936       case SIG_SF:
06937       case SIG_SFWINK:
06938       case SIG_FXSLS:
06939       case SIG_FXSGS:
06940       case SIG_FXSKS:
06941       case SIG_GR303FXSKS:
06942          zt_disable_ec(i);
06943          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06944          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06945          break;
06946       case SIG_GR303FXOKS:
06947       case SIG_FXOKS:
06948          zt_disable_ec(i);
06949          /* Diddle the battery for the zhone */
06950 #ifdef ZHONE_HACK
06951          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06952          usleep(1);
06953 #endif         
06954          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06955          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
06956          break;
06957       case SIG_PRI:
06958          if (event != ZT_EVENT_ALARM) {
06959              zt_disable_ec(i);
06960              res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06961          }
06962          break;
06963       default:
06964          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06965          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
06966          return -1;
06967       }
06968       break;
06969    case ZT_EVENT_POLARITY:
06970       switch (i->sig) {
06971       case SIG_FXSLS:
06972       case SIG_FXSKS:
06973       case SIG_FXSGS:
06974          /* We have already got a PR before the channel was 
06975             created, but it wasn't handled. We need polarity 
06976             to be REV for remote hangup detection to work. 
06977             At least in Spain */
06978          if (i->hanguponpolarityswitch)
06979             i->polarity = POLARITY_REV;
06980 
06981          if (i->cid_start == CID_START_POLARITY) {
06982             i->polarity = POLARITY_REV;
06983             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
06984                    "CID detection on channel %d\n",
06985                    i->channel);
06986             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
06987             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06988                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06989             }
06990          }
06991          break;
06992       default:
06993          ast_log(LOG_WARNING, "handle_init_event detected "
06994             "polarity reversal on non-FXO (SIG_FXS) "
06995             "interface %d\n", i->channel);
06996       }
06997       break;
06998    case ZT_EVENT_REMOVED: /* destroy channel */
06999       ast_log(LOG_NOTICE, 
07000             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
07001             i->channel);
07002       zap_destroy_channel_bynum(i->channel);
07003       break;
07004    }
07005    pthread_attr_destroy(&attr);
07006    return 0;
07007 }
07008 
07009 static void *do_monitor(void *data)
07010 {
07011    int count, res, res2, spoint, pollres=0;
07012    struct zt_pvt *i;
07013    struct zt_pvt *last = NULL;
07014    time_t thispass = 0, lastpass = 0;
07015    int found;
07016    char buf[1024];
07017    struct pollfd *pfds=NULL;
07018    int lastalloc = -1;
07019    /* This thread monitors all the frame relay interfaces which are not yet in use
07020       (and thus do not have a separate thread) indefinitely */
07021    /* From here on out, we die whenever asked */
07022 #if 0
07023    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
07024       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
07025       return NULL;
07026    }
07027    ast_log(LOG_DEBUG, "Monitor starting...\n");
07028 #endif
07029    for (;;) {
07030       /* Lock the interface list */
07031       ast_mutex_lock(&iflock);
07032       if (!pfds || (lastalloc != ifcount)) {
07033          if (pfds) {
07034             free(pfds);
07035             pfds = NULL;
07036          }
07037          if (ifcount) {
07038             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
07039                ast_mutex_unlock(&iflock);
07040                return NULL;
07041             }
07042          }
07043          lastalloc = ifcount;
07044       }
07045       /* Build the stuff we're going to poll on, that is the socket of every
07046          zt_pvt that does not have an associated owner channel */
07047       count = 0;
07048       i = iflist;
07049       while (i) {
07050          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
07051             if (!i->owner && !i->subs[SUB_REAL].owner) {
07052                /* This needs to be watched, as it lacks an owner */
07053                pfds[count].fd = i->subs[SUB_REAL].zfd;
07054                pfds[count].events = POLLPRI;
07055                pfds[count].revents = 0;
07056                /* Message waiting or r2 channels also get watched for reading */
07057                if (i->cidspill)
07058                   pfds[count].events |= POLLIN;
07059                count++;
07060             }
07061          }
07062          i = i->next;
07063       }
07064       /* Okay, now that we know what to do, release the interface lock */
07065       ast_mutex_unlock(&iflock);
07066       
07067       pthread_testcancel();
07068       /* Wait at least a second for something to happen */
07069       res = poll(pfds, count, 1000);
07070       pthread_testcancel();
07071       /* Okay, poll has finished.  Let's see what happened.  */
07072       if (res < 0) {
07073          if ((errno != EAGAIN) && (errno != EINTR))
07074             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
07075          continue;
07076       }
07077       /* Alright, lock the interface list again, and let's look and see what has
07078          happened */
07079       ast_mutex_lock(&iflock);
07080       found = 0;
07081       spoint = 0;
07082       lastpass = thispass;
07083       thispass = time(NULL);
07084       i = iflist;
07085       while (i) {
07086          if (thispass != lastpass) {
07087             if (!found && ((i == last) || ((i == iflist) && !last))) {
07088                last = i;
07089                if (last) {
07090                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
07091                      (last->sig & __ZT_SIG_FXO)) {
07092                      res = ast_app_has_voicemail(last->mailbox, NULL);
07093                      if (last->msgstate != res) {
07094                         int x;
07095                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
07096                         x = ZT_FLUSH_BOTH;
07097                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
07098                         if (res2)
07099                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
07100                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
07101                            /* Turn on on hook transfer for 4 seconds */
07102                            x = 4000;
07103                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
07104                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
07105                            last->cidpos = 0;
07106                            last->msgstate = res;
07107                            last->onhooktime = thispass;
07108                         }
07109                         found ++;
07110                      }
07111                   }
07112                   last = last->next;
07113                }
07114             }
07115          }
07116          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
07117             if (i->radio && !i->owner)
07118             {
07119                res = zt_get_event(i->subs[SUB_REAL].zfd);
07120                if (res)
07121                {
07122                   if (option_debug)
07123                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
07124                   /* Don't hold iflock while handling init events */
07125                   ast_mutex_unlock(&iflock);
07126                   handle_init_event(i, res);
07127                   ast_mutex_lock(&iflock);   
07128                }
07129                i = i->next;
07130                continue;
07131             }              
07132             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
07133             if (pollres & POLLIN) {
07134                if (i->owner || i->subs[SUB_REAL].owner) {
07135 #ifdef HAVE_PRI
07136                   if (!i->pri)
07137 #endif                  
07138                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
07139                   i = i->next;
07140                   continue;
07141                }
07142                if (!i->cidspill) {
07143                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
07144                   i = i->next;
07145                   continue;
07146                }
07147                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
07148                if (res > 0) {
07149                   /* We read some number of bytes.  Write an equal amount of data */
07150                   if (res > i->cidlen - i->cidpos) 
07151                      res = i->cidlen - i->cidpos;
07152                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
07153                   if (res2 > 0) {
07154                      i->cidpos += res2;
07155                      if (i->cidpos >= i->cidlen) {
07156                         free(i->cidspill);
07157                         i->cidspill = 0;
07158                         i->cidpos = 0;
07159                         i->cidlen = 0;
07160                      }
07161                   } else {
07162                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
07163                      i->msgstate = -1;
07164                   }
07165                } else {
07166                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
07167                }
07168             }
07169             if (pollres & POLLPRI) {
07170                if (i->owner || i->subs[SUB_REAL].owner) {
07171 #ifdef HAVE_PRI
07172                   if (!i->pri)
07173 #endif                  
07174                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
07175                   i = i->next;
07176                   continue;
07177                }
07178                res = zt_get_event(i->subs[SUB_REAL].zfd);
07179                if (option_debug)
07180                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07181                /* Don't hold iflock while handling init events */
07182                ast_mutex_unlock(&iflock);
07183                handle_init_event(i, res);
07184                ast_mutex_lock(&iflock);   
07185             }
07186          }
07187          i=i->next;
07188       }
07189       ast_mutex_unlock(&iflock);
07190    }
07191    /* Never reached */
07192    return NULL;
07193    
07194 }
07195 
07196 static int restart_monitor(void)
07197 {
07198    pthread_attr_t attr;
07199    pthread_attr_init(&attr);
07200    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07201    /* If we're supposed to be stopped -- stay stopped */
07202    if (monitor_thread == AST_PTHREADT_STOP)
07203       return 0;
07204    ast_mutex_lock(&monlock);
07205    if (monitor_thread == pthread_self()) {
07206       ast_mutex_unlock(&monlock);
07207       ast_log(LOG_WARNING, "Cannot kill myself\n");
07208       return -1;
07209    }
07210    if (monitor_thread != AST_PTHREADT_NULL) {
07211       /* Wake up the thread */
07212       pthread_kill(monitor_thread, SIGURG);
07213    } else {
07214       /* Start a new monitor */
07215       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
07216          ast_mutex_unlock(&monlock);
07217          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
07218          pthread_attr_destroy(&attr);
07219          return -1;
07220       }
07221    }
07222    ast_mutex_unlock(&monlock);
07223    pthread_attr_destroy(&attr);
07224    return 0;
07225 }
07226 
07227 #ifdef HAVE_PRI
07228 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
07229 {
07230    int x;
07231    int trunkgroup;
07232    /* Get appropriate trunk group if there is one */
07233    trunkgroup = pris[*span].mastertrunkgroup;
07234    if (trunkgroup) {
07235       /* Select a specific trunk group */
07236       for (x = 0; x < NUM_SPANS; x++) {
07237          if (pris[x].trunkgroup == trunkgroup) {
07238             *span = x;
07239             return 0;
07240          }
07241       }
07242       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
07243       *span = -1;
07244    } else {
07245       if (pris[*span].trunkgroup) {
07246          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07247          *span = -1;
07248       } else if (pris[*span].mastertrunkgroup) {
07249          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07250          *span = -1;
07251       } else {
07252          if (si->totalchans == 31) { /* if it's an E1 */
07253             pris[*span].dchannels[0] = 16 + offset;
07254          } else if (si->totalchans == 3) { /* if it's an S0 ZAPBRI */
07255             pris[*span].dchannels[0] = 3 + offset;
07256          } else {
07257             pris[*span].dchannels[0] = 24 + offset;
07258          }
07259          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07260          pris[*span].offset = offset;
07261          pris[*span].span = *span + 1;
07262       }
07263    }
07264    return 0;
07265 }
07266 
07267 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07268 {
07269    struct zt_spaninfo si;
07270    ZT_PARAMS p;
07271    int fd;
07272    int span;
07273    int ospan=0;
07274    int x,y;
07275    for (x = 0; x < NUM_SPANS; x++) {
07276       if (pris[x].trunkgroup == trunkgroup) {
07277          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07278          return -1;
07279       }
07280    }
07281    for (y = 0; y < NUM_DCHANS; y++) {
07282       if (!channels[y]) 
07283          break;
07284       memset(&si, 0, sizeof(si));
07285       memset(&p, 0, sizeof(p));
07286       fd = open("/dev/zap/channel", O_RDWR);
07287       if (fd < 0) {
07288          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07289          return -1;
07290       }
07291       x = channels[y];
07292       if (ioctl(fd, ZT_SPECIFY, &x)) {
07293          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07294          zt_close(fd);
07295          return -1;
07296       }
07297       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07298          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07299          return -1;
07300       }
07301       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07302          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07303          zt_close(fd);
07304          return -1;
07305       }
07306       span = p.spanno - 1;
07307       if (pris[span].trunkgroup) {
07308          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07309          zt_close(fd);
07310          return -1;
07311       }
07312       if (pris[span].pvts[0]) {
07313          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07314          zt_close(fd);
07315          return -1;
07316       }
07317       if (!y) {
07318          pris[span].trunkgroup = trunkgroup;
07319          pris[span].offset = channels[y] - p.chanpos;
07320          ospan = span;
07321       }
07322       pris[ospan].dchannels[y] = channels[y];
07323       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07324       pris[span].span = span + 1;
07325       zt_close(fd);
07326    }
07327    return 0;   
07328 }
07329 
07330 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07331 {
07332    if (pris[span].mastertrunkgroup) {
07333       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);
07334       return -1;
07335    }
07336    pris[span].mastertrunkgroup = trunkgroup;
07337    pris[span].prilogicalspan = logicalspan;
07338    return 0;
07339 }
07340 
07341 #endif
07342 
07343 #ifdef HAVE_GSMAT
07344 static void *gsm_dchannel(void *vgsm);
07345 #endif
07346 
07347 static struct zt_pvt *mkintf(int channel, const struct zt_chan_conf *conf, struct zt_pri *pri, int reloading)
07348 {
07349    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07350    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07351    char fn[80];
07352 #if 1
07353    struct zt_bufferinfo bi;
07354 #endif
07355    struct zt_spaninfo si;
07356    int res;
07357    int span=0;
07358    int here = 0;
07359    int x;
07360    struct zt_pvt **wlist;
07361    struct zt_pvt **wend;
07362    ZT_PARAMS p;
07363 
07364    wlist = &iflist;
07365    wend = &ifend;
07366 
07367 #ifdef HAVE_PRI
07368    if (pri) {
07369       wlist = &pri->crvs;
07370       wend = &pri->crvend;
07371    }
07372 #endif
07373 
07374    tmp2 = *wlist;
07375    prev = NULL;
07376 
07377    while (tmp2) {
07378       if (!tmp2->destroy) {
07379          if (tmp2->channel == channel) {
07380             tmp = tmp2;
07381             here = 1;
07382             break;
07383          }
07384          if (tmp2->channel > channel) {
07385             break;
07386          }
07387       }
07388       prev = tmp2;
07389       tmp2 = tmp2->next;
07390    }
07391 
07392    if (!here && !reloading) {
07393       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07394          destroy_zt_pvt(&tmp);
07395          return NULL;
07396       }
07397       ast_mutex_init(&tmp->lock);
07398       ifcount++;
07399       for (x = 0; x < 3; x++)
07400          tmp->subs[x].zfd = -1;
07401       tmp->channel = channel;
07402    }
07403 
07404    if (tmp) {
07405       int chan_sig = conf->chan.sig;
07406       if (!here) {
07407          if ((channel != CHAN_PSEUDO) && !pri) {
07408             snprintf(fn, sizeof(fn), "%d", channel);
07409             /* Open non-blocking */
07410             if (!here)
07411                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07412             /* Allocate a zapata structure */
07413             if (tmp->subs[SUB_REAL].zfd < 0) {
07414                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);
07415                destroy_zt_pvt(&tmp);
07416                return NULL;
07417             }
07418             memset(&p, 0, sizeof(p));
07419             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07420             if (res < 0) {
07421                ast_log(LOG_ERROR, "Unable to get parameters\n");
07422                destroy_zt_pvt(&tmp);
07423                return NULL;
07424             }
07425             if (p.sigtype != (conf->chan.sig & 0x3ffff)) {
07426                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));
07427                destroy_zt_pvt(&tmp);
07428                return NULL;
07429             }
07430             tmp->law = p.curlaw;
07431             tmp->span = p.spanno;
07432             span = p.spanno - 1;
07433          } else {
07434             if (channel == CHAN_PSEUDO)
07435                chan_sig = 0;
07436             else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) {
07437                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07438                return NULL;
07439             }
07440          }
07441 #ifdef HAVE_PRI
07442          if ((chan_sig == SIG_PRI) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) {
07443             int offset;
07444             int myswitchtype;
07445             int matchesdchan;
07446             int x,y;
07447             offset = 0;
07448             if ((chan_sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07449                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07450                destroy_zt_pvt(&tmp);
07451                return NULL;
07452             }
07453             if (span >= NUM_SPANS) {
07454                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07455                destroy_zt_pvt(&tmp);
07456                return NULL;
07457             } else {
07458                si.spanno = 0;
07459                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07460                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07461                   destroy_zt_pvt(&tmp);
07462                   return NULL;
07463                }
07464                /* Store the logical span first based upon the real span */
07465                tmp->logicalspan = pris[span].prilogicalspan;
07466                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07467                if (span < 0) {
07468                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07469                   destroy_zt_pvt(&tmp);
07470                   return NULL;
07471                }
07472                if (chan_sig == SIG_PRI)
07473                   myswitchtype = conf->pri.switchtype;
07474                else
07475                   myswitchtype = PRI_SWITCH_GR303_TMC;
07476                /* Make sure this isn't a d-channel */
07477                matchesdchan=0;
07478                for (x = 0; x < NUM_SPANS; x++) {
07479                   for (y = 0; y < NUM_DCHANS; y++) {
07480                      if (pris[x].dchannels[y] == tmp->channel) {
07481                         matchesdchan = 1;
07482                         break;
07483                      }
07484                   }
07485                }
07486                offset = p.chanpos;
07487                if (!matchesdchan) {
07488                   if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) {
07489                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07490                      destroy_zt_pvt(&tmp);
07491                      return NULL;
07492                   }
07493                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07494                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07495                      destroy_zt_pvt(&tmp);
07496                      return NULL;
07497                   }
07498                   if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) {
07499                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07500                      destroy_zt_pvt(&tmp);
07501                      return NULL;
07502                   }
07503                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) {
07504                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial);
07505                      destroy_zt_pvt(&tmp);
07506                      return NULL;
07507                   }
07508                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) {
07509                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext);
07510                      destroy_zt_pvt(&tmp);
07511                      return NULL;
07512                   }
07513                                              if ((pris[span].localdialplan) && (pris[span].localdialplan != conf->pri.localdialplan)) {
07514                      ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan));
07515                      destroy_zt_pvt(&tmp);
07516                                                    return NULL;
07517                      }
07518                   if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) {
07519                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused);
07520                      destroy_zt_pvt(&tmp);
07521                      return NULL;
07522                   }
07523                   if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) {
07524                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle);
07525                      destroy_zt_pvt(&tmp);
07526                      return NULL;
07527                   }
07528                   if (pris[span].numchans >= MAX_CHANNELS) {
07529                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07530                         pris[span].trunkgroup);
07531                      destroy_zt_pvt(&tmp);
07532                      return NULL;
07533                   }
07534                   pris[span].nodetype = conf->pri.nodetype;
07535 
07536                   if (conf->pri.nodetype == BRI_NETWORK_PTMP) {
07537                       pris[span].dchanavail[0] =  DCHAN_AVAILABLE;
07538                       pri_find_dchan(&pris[span]);
07539                   }
07540                   pris[span].switchtype = myswitchtype;
07541                   pris[span].nsf = conf->pri.nsf;
07542                   pris[span].dialplan = conf->pri.dialplan;
07543                   pris[span].localdialplan = conf->pri.localdialplan;
07544                   pris[span].pvts[pris[span].numchans++] = tmp;
07545                   pris[span].minunused = conf->pri.minunused;
07546                   pris[span].minidle = conf->pri.minidle;
07547                   pris[span].overlapdial = conf->pri.overlapdial;
07548                   pris[span].usercid = conf->pri.usercid;
07549                   pris[span].suspended_calls = NULL;
07550                   pris[span].facilityenable = conf->pri.facilityenable;
07551                   ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial));
07552                   ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext));
07553                   ast_copy_string(pris[span].nocid, conf->pri.nocid, sizeof(pris[span].nocid));
07554                   ast_copy_string(pris[span].withheldcid, conf->pri.withheldcid, sizeof(pris[span].withheldcid));
07555                   ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix));
07556                   ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix));
07557                   ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix));
07558                   ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix));
07559                   ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix));
07560                   pris[span].resetinterval = conf->pri.resetinterval;
07561                   
07562                   tmp->pri = &pris[span];
07563                   tmp->prioffset = offset;
07564                   tmp->call = NULL;
07565                } else {
07566                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07567                   destroy_zt_pvt(&tmp);
07568                   return NULL;
07569                }
07570             }
07571          } else {
07572             tmp->prioffset = 0;
07573          }
07574 #endif
07575 #ifdef HAVE_GSMAT
07576       if (conf->chan.sig == SIG_GSM) {
07577           struct zt_bufferinfo bi;
07578           ast_mutex_init(&tmp->gsm.lock);
07579           strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1);
07580           strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1);
07581           tmp->gsm.available = 0;
07582           snprintf(fn, sizeof(fn), "%d", channel + 1);
07583           /* Open non-blocking */
07584           tmp->gsm.fd = zt_open(fn);
07585           bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07586           bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07587           bi.numbufs = 16;
07588           bi.bufsize = 1024;
07589           if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) {
07590          ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno));
07591          return NULL;
07592           }
07593           tmp->gsm.pvt = tmp;
07594           tmp->gsm.span = tmp->span;
07595           tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel);
07596           if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) {
07597          ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno));
07598          destroy_zt_pvt(&tmp);
07599          return NULL;
07600           }
07601           if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) {
07602          zt_close(tmp->gsm.fd);
07603           }
07604       }
07605 #endif
07606       } else {
07607          chan_sig = tmp->sig;
07608          memset(&p, 0, sizeof(p));
07609          if (tmp->subs[SUB_REAL].zfd > -1)
07610             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07611       }
07612       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07613       switch (chan_sig) {
07614       case SIG_FXSKS:
07615       case SIG_FXSLS:
07616       case SIG_EM:
07617       case SIG_EM_E1:
07618       case SIG_EMWINK:
07619       case SIG_FEATD:
07620       case SIG_FEATDMF:
07621       case SIG_FEATDMF_TA:
07622       case SIG_FEATB:
07623       case SIG_E911:
07624       case SIG_SF:
07625       case SIG_SFWINK:
07626       case SIG_FGC_CAMA:
07627       case SIG_FGC_CAMAMF:
07628       case SIG_SF_FEATD:
07629       case SIG_SF_FEATDMF:
07630       case SIG_SF_FEATB:
07631          p.starttime = 250;
07632          break;
07633       }
07634 
07635       if (tmp->radio) {
07636          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07637          p.channo = channel;
07638          p.rxwinktime = 1;
07639          p.rxflashtime = 1;
07640          p.starttime = 1;
07641          p.debouncetime = 5;
07642       }
07643       if (!tmp->radio) {
07644          p.channo = channel;
07645          /* Override timing settings based on config file */
07646          if (conf->timing.prewinktime >= 0)
07647             p.prewinktime = conf->timing.prewinktime;
07648          if (conf->timing.preflashtime >= 0)
07649             p.preflashtime = conf->timing.preflashtime;
07650          if (conf->timing.winktime >= 0)
07651             p.winktime = conf->timing.winktime;
07652          if (conf->timing.flashtime >= 0)
07653             p.flashtime = conf->timing.flashtime;
07654          if (conf->timing.starttime >= 0)
07655             p.starttime = conf->timing.starttime;
07656          if (conf->timing.rxwinktime >= 0)
07657             p.rxwinktime = conf->timing.rxwinktime;
07658          if (conf->timing.rxflashtime >= 0)
07659             p.rxflashtime = conf->timing.rxflashtime;
07660          if (conf->timing.debouncetime >= 0)
07661             p.debouncetime = conf->timing.debouncetime;
07662       }
07663       
07664       /* dont set parms on a pseudo-channel (or CRV) */
07665       if (tmp->subs[SUB_REAL].zfd >= 0)
07666       {
07667          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07668          if (res < 0) {
07669             ast_log(LOG_ERROR, "Unable to set parameters\n");
07670             destroy_zt_pvt(&tmp);
07671             return NULL;
07672          }
07673       }
07674 #if 1
07675       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07676          memset(&bi, 0, sizeof(bi));
07677          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07678          if (!res) {
07679             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07680             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07681             bi.numbufs = numbufs;
07682             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07683             if (res < 0) {
07684                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07685             }
07686          } else
07687             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07688       }
07689 #endif
07690       tmp->immediate = conf->chan.immediate;
07691       tmp->transfertobusy = conf->chan.transfertobusy;
07692       tmp->sig = chan_sig;
07693       tmp->outsigmod = conf->chan.outsigmod;
07694       tmp->ringt_base = ringt_base;
07695       tmp->firstradio = 0;
07696       if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
07697          tmp->permcallwaiting = conf->chan.callwaiting;
07698       else
07699          tmp->permcallwaiting = 0;
07700       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07701       tmp->destroy = 0;
07702       tmp->drings = drings;
07703       tmp->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
07704       tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
07705       tmp->threewaycalling = conf->chan.threewaycalling;
07706       tmp->adsi = conf->chan.adsi;
07707       tmp->use_smdi = conf->chan.use_smdi;
07708       tmp->permhidecallerid = conf->chan.hidecallerid;
07709       tmp->callreturn = conf->chan.callreturn;
07710       tmp->echocancel = conf->chan.echocancel;
07711       tmp->echotraining = conf->chan.echotraining;
07712       tmp->pulse = conf->chan.pulse;
07713       if (tmp->echocancel)
07714          tmp->echocanbridged = conf->chan.echocanbridged;
07715       else {
07716          if (conf->chan.echocanbridged)
07717             ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
07718          tmp->echocanbridged = 0;
07719       }
07720       tmp->busydetect = conf->chan.busydetect;
07721       tmp->busycount = conf->chan.busycount;
07722       tmp->busy_tonelength = conf->chan.busy_tonelength;
07723       tmp->busy_quietlength = conf->chan.busy_quietlength;
07724       tmp->callprogress = conf->chan.callprogress;
07725       tmp->cancallforward = conf->chan.cancallforward;
07726       tmp->dtmfrelax = conf->chan.dtmfrelax;
07727       tmp->callwaiting = tmp->permcallwaiting;
07728       tmp->hidecallerid = tmp->permhidecallerid;
07729       tmp->channel = channel;
07730       tmp->stripmsd = conf->chan.stripmsd;
07731       tmp->use_callerid = conf->chan.use_callerid;
07732       tmp->cid_signalling = conf->chan.cid_signalling;
07733       tmp->cid_start = conf->chan.cid_start;
07734       tmp->zaptrcallerid = conf->chan.zaptrcallerid;
07735       tmp->restrictcid = conf->chan.restrictcid;
07736       tmp->use_callingpres = conf->chan.use_callingpres;
07737       tmp->priindication_oob = conf->chan.priindication_oob;
07738       tmp->pritransfer = conf->chan.pritransfer;
07739       tmp->priexclusive = conf->chan.priexclusive;
07740       if (tmp->usedistinctiveringdetection) {
07741          if (!tmp->use_callerid) {
07742             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07743             tmp->use_callerid = 1;
07744          }
07745       }
07746 
07747       if (tmp->cid_signalling == CID_SIG_SMDI) {
07748          if (!tmp->use_smdi) {
07749             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07750             tmp->use_smdi = 1;
07751          }
07752       }
07753       if (tmp->use_smdi) {
07754          tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
07755          if (!(tmp->smdi_iface)) {
07756             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07757             tmp->use_smdi = 0;
07758          }
07759       }
07760 
07761       ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
07762       tmp->amaflags = conf->chan.amaflags;
07763       if (!here) {
07764          tmp->confno = -1;
07765          tmp->propconfno = -1;
07766       }
07767       tmp->canpark = conf->chan.canpark;
07768       tmp->transfer = conf->chan.transfer;
07769       ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
07770       ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
07771       ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
07772       ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
07773       ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
07774       ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
07775       tmp->cid_ton = 0;
07776       ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
07777       ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
07778       tmp->msgstate = -1;
07779       tmp->group = conf->chan.group;
07780       tmp->callgroup = conf->chan.callgroup;
07781       tmp->pickupgroup= conf->chan.pickupgroup;
07782       tmp->rxgain = conf->chan.rxgain;
07783       tmp->txgain = conf->chan.txgain;
07784       tmp->tonezone = conf->chan.tonezone;
07785       tmp->onhooktime = time(NULL);
07786       if (tmp->subs[SUB_REAL].zfd > -1) {
07787          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07788          if (tmp->dsp)
07789             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07790          update_conf(tmp);
07791          if (!here) {
07792             if (chan_sig != SIG_PRI)
07793                /* Hang it up to be sure it's good */
07794                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07795          }
07796          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07797 #ifdef HAVE_PRI
07798          /* the dchannel is down so put the channel in alarm */
07799          if (tmp->pri && !pri_is_up(tmp->pri))
07800             tmp->inalarm = 1;
07801          else
07802             tmp->inalarm = 0;
07803 #endif            
07804          memset(&si, 0, sizeof(si));
07805          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07806             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07807             destroy_zt_pvt(&tmp);
07808             return NULL;
07809          }
07810          if (si.alarms) tmp->inalarm = 1;
07811       }
07812 
07813       tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
07814       tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
07815       tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
07816       tmp->sendcalleridafter = conf->chan.sendcalleridafter;
07817 
07818    }
07819    if (tmp && !here) {
07820       /* nothing on the iflist */
07821       if (!*wlist) {
07822          *wlist = tmp;
07823          tmp->prev = NULL;
07824          tmp->next = NULL;
07825          *wend = tmp;
07826       } else {
07827          /* at least one member on the iflist */
07828          struct zt_pvt *working = *wlist;
07829 
07830          /* check if we maybe have to put it on the begining */
07831          if (working->channel > tmp->channel) {
07832             tmp->next = *wlist;
07833             tmp->prev = NULL;
07834             (*wlist)->prev = tmp;
07835             *wlist = tmp;
07836          } else {
07837          /* go through all the members and put the member in the right place */
07838             while (working) {
07839                /* in the middle */
07840                if (working->next) {
07841                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07842                      tmp->next = working->next;
07843                      tmp->prev = working;
07844                      working->next->prev = tmp;
07845                      working->next = tmp;
07846                      break;
07847                   }
07848                } else {
07849                /* the last */
07850                   if (working->channel < tmp->channel) {
07851                      working->next = tmp;
07852                      tmp->next = NULL;
07853                      tmp->prev = working;
07854                      *wend = tmp;
07855                      break;
07856                   }
07857                }
07858                working = working->next;
07859             }
07860          }
07861       }
07862    }
07863    return tmp;
07864 }
07865 
07866 static inline int available(struct zt_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
07867 {
07868    int res;
07869    ZT_PARAMS par;
07870 
07871    /* First, check group matching */
07872    if (groupmatch) {
07873       if ((p->group & groupmatch) != groupmatch)
07874          return 0;
07875       *groupmatched = 1;
07876    }
07877    /* Check to see if we have a channel match */
07878    if (channelmatch != -1) {
07879       if (p->channel != channelmatch)
07880          return 0;
07881       *channelmatched = 1;
07882    }
07883    /* We're at least busy at this point */
07884    if (busy) {
07885       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07886          *busy = 1;
07887    }
07888    /* If do not disturb, definitely not */
07889    if (p->dnd)
07890       return 0;
07891    /* If guard time, definitely not */
07892    if (p->guardtime && (time(NULL) < p->guardtime)) 
07893       return 0;
07894       
07895    /* If no owner definitely available */
07896    if (!p->owner) {
07897 #ifdef HAVE_PRI
07898       /* Trust PRI */
07899       if (p->pri) {
07900          if (p->resetting || p->call)
07901             return 0;
07902          else
07903             return 1;
07904       }
07905 #endif
07906 #ifdef HAVE_GSMAT
07907       if (p->gsm.modul) {
07908           return gsm_available(p->gsm.modul);
07909       }
07910 
07911 #endif
07912       if (!(p->radio || (p->oprmode < 0)))
07913       {
07914          if (!p->sig || (p->sig == SIG_FXSLS))
07915             return 1;
07916          /* Check hook state */
07917          if (p->subs[SUB_REAL].zfd > -1)
07918             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
07919          else {
07920             /* Assume not off hook on CVRS */
07921             res = 0;
07922             par.rxisoffhook = 0;
07923          }
07924          if (res) {
07925             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
07926          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
07927             /* When "onhook" that means no battery on the line, and thus
07928               it is out of service..., if it's on a TDM card... If it's a channel
07929               bank, there is no telling... */
07930             if (par.rxbits > -1)
07931                return 1;
07932             if (par.rxisoffhook)
07933                return 1;
07934             else
07935 #ifdef ZAP_CHECK_HOOKSTATE
07936                return 0;
07937 #else
07938                return 1;
07939 #endif
07940          } else if (par.rxisoffhook) {
07941             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
07942             /* Not available when the other end is off hook */
07943             return 0;
07944          }
07945       }
07946       return 1;
07947    }
07948 
07949    /* If it's not an FXO, forget about call wait */
07950    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
07951       return 0;
07952 
07953    if (!p->callwaiting) {
07954       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
07955       return 0;
07956    }
07957 
07958    if (p->subs[SUB_CALLWAIT].zfd > -1) {
07959       /* If there is already a call waiting call, then we can't take a second one */
07960       return 0;
07961    }
07962    
07963    if ((p->owner->_state != AST_STATE_UP) &&
07964        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
07965       /* If the current call is not up, then don't allow the call */
07966       return 0;
07967    }
07968    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
07969       /* Can't take a call wait when the three way calling hasn't been merged yet. */
07970       return 0;
07971    }
07972    /* We're cool */
07973    return 1;
07974 }
07975 
07976 static struct zt_pvt *chandup(struct zt_pvt *src)
07977 {
07978    struct zt_pvt *p;
07979    ZT_BUFFERINFO bi;
07980    int res;
07981    
07982    if ((p = ast_malloc(sizeof(*p)))) {
07983       memcpy(p, src, sizeof(struct zt_pvt));
07984       ast_mutex_init(&p->lock);
07985       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
07986       /* Allocate a zapata structure */
07987       if (p->subs[SUB_REAL].zfd < 0) {
07988          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
07989          destroy_zt_pvt(&p);
07990          return NULL;
07991       }
07992       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07993       if (!res) {
07994          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07995          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07996          bi.numbufs = numbufs;
07997          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07998          if (res < 0) {
07999             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
08000          }
08001       } else
08002          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
08003    }
08004    p->destroy = 1;
08005    p->next = iflist;
08006    p->prev = NULL;
08007    iflist = p;
08008    if (iflist->next)
08009       iflist->next->prev = p;
08010    return p;
08011 }
08012    
08013 
08014 #ifdef HAVE_PRI
08015 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
08016 {
08017    int x;
08018    if (backwards)
08019       x = pri->numchans;
08020    else
08021       x = 0;
08022    for (;;) {
08023       if (backwards && (x < 0))
08024          break;
08025       if (!backwards && (x >= pri->numchans))
08026          break;
08027       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner && !pri->pvts[x]->call) {
08028          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
08029             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
08030          return x;
08031       }
08032       if (backwards)
08033          x--;
08034       else
08035          x++;
08036    }
08037    return -1;
08038 }
08039 #endif
08040 
08041 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
08042 {
08043    ast_group_t groupmatch = 0;
08044    int channelmatch = -1;
08045    int roundrobin = 0;
08046    int callwait = 0;
08047    int busy = 0;
08048    struct zt_pvt *p;
08049    struct ast_channel *tmp = NULL;
08050    char *dest=NULL;
08051    int x;
08052    char *s;
08053    char opt=0;
08054    int res=0, y=0;
08055    int backwards = 0;
08056 #ifdef HAVE_PRI
08057    int crv;
08058    int bearer = -1;
08059    int trunkgroup;
08060    struct zt_pri *pri=NULL;
08061 #endif   
08062    struct zt_pvt *exit, *start, *end;
08063    ast_mutex_t *lock;
08064    int channelmatched = 0;
08065    int groupmatched = 0;
08066    
08067    /* Assume we're locking the iflock */
08068    lock = &iflock;
08069    start = iflist;
08070    end = ifend;
08071    if (data) {
08072       dest = ast_strdupa((char *)data);
08073    } else {
08074       ast_log(LOG_WARNING, "Channel requested with no data\n");
08075       return NULL;
08076    }
08077    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
08078       /* Retrieve the group number */
08079       char *stringp=NULL;
08080       stringp=dest + 1;
08081       s = strsep(&stringp, "/");
08082       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08083          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
08084          return NULL;
08085       }
08086       groupmatch = ((ast_group_t) 1 << x);
08087       if (toupper(dest[0]) == 'G') {
08088          if (dest[0] == 'G') {
08089             backwards = 1;
08090             p = ifend;
08091          } else
08092             p = iflist;
08093       } else {
08094          if (dest[0] == 'R') {
08095             backwards = 1;
08096             p = round_robin[x]?round_robin[x]->prev:ifend;
08097             if (!p)
08098                p = ifend;
08099          } else {
08100             p = round_robin[x]?round_robin[x]->next:iflist;
08101             if (!p)
08102                p = iflist;
08103          }
08104          roundrobin = 1;
08105       }
08106    } else {
08107       char *stringp=NULL;
08108       stringp=dest;
08109       s = strsep(&stringp, "/");
08110       p = iflist;
08111       if (!strcasecmp(s, "pseudo")) {
08112          /* Special case for pseudo */
08113          x = CHAN_PSEUDO;
08114          channelmatch = x;
08115       } 
08116 #ifdef HAVE_PRI
08117       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
08118          if ((trunkgroup < 1) || (crv < 1)) {
08119             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
08120             return NULL;
08121          }
08122          res--;
08123          for (x = 0; x < NUM_SPANS; x++) {
08124             if (pris[x].trunkgroup == trunkgroup) {
08125                pri = pris + x;
08126                lock = &pri->lock;
08127                start = pri->crvs;
08128                end = pri->crvend;
08129                break;
08130             }
08131          }
08132          if (!pri) {
08133             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
08134             return NULL;
08135          }
08136          channelmatch = crv;
08137          p = pris[x].crvs;
08138       }
08139 #endif   
08140       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08141          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
08142          return NULL;
08143       } else {
08144          channelmatch = x;
08145       }
08146    }
08147    /* Search for an unowned channel */
08148    ast_mutex_lock(lock);
08149    exit = p;
08150    while (p && !tmp) {
08151       if (roundrobin)
08152          round_robin[x] = p;
08153 #if 0
08154       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
08155 #endif
08156 
08157       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
08158          if (option_debug)
08159             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
08160             if (p->inalarm) 
08161                goto next;
08162 
08163          callwait = (p->owner != NULL);
08164 #ifdef HAVE_PRI
08165          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
08166             if (p->sig != SIG_FXSKS) {
08167                /* Gotta find an actual channel to use for this
08168                   CRV if this isn't a callwait */
08169                bearer = pri_find_empty_chan(pri, 0);
08170                if (bearer < 0) {
08171                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
08172                   p = NULL;
08173                   break;
08174                }
08175                pri_assign_bearer(p, pri, pri->pvts[bearer]);
08176             } else {
08177                if (alloc_sub(p, 0)) {
08178                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
08179                   p = NULL;
08180                   break;
08181                } else
08182                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
08183                p->pri = pri;
08184             }
08185          }
08186 #endif         
08187          if (p->channel == CHAN_PSEUDO) {
08188             p = chandup(p);
08189             if (!p) {
08190                break;
08191             }
08192          }
08193          if (p->owner) {
08194             if (alloc_sub(p, SUB_CALLWAIT)) {
08195                p = NULL;
08196                break;
08197             }
08198          }
08199          p->outgoing = 1;
08200          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
08201 #ifdef HAVE_PRI
08202          if (p->bearer) {
08203             /* Log owner to bearer channel, too */
08204             p->bearer->owner = tmp;
08205          }
08206 #endif         
08207          /* Make special notes */
08208          if (res > 1) {
08209             if (opt == 'c') {
08210                /* Confirm answer */
08211                p->confirmanswer = 1;
08212             } else if (opt == 'r') {
08213                /* Distinctive ring */
08214                if (res < 3)
08215                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
08216                else
08217                   p->distinctivering = y;
08218             } else if (opt == 'd') {
08219                /* If this is an ISDN call, make it digital */
08220                p->digital = 1;
08221                if (tmp)
08222                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
08223             } else if (opt == 'm') {
08224                /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */
08225                p->faxhandled = 1;
08226                if (tmp)
08227                    tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO;
08228             } else {
08229                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
08230             }
08231          }
08232          /* Note if the call is a call waiting call */
08233          if (tmp && callwait)
08234             tmp->cdrflags |= AST_CDR_CALLWAIT;
08235          break;
08236       }
08237 next:
08238       if (backwards) {
08239          p = p->prev;
08240          if (!p)
08241             p = end;
08242       } else {
08243          p = p->next;
08244          if (!p)
08245             p = start;
08246       }
08247       /* stop when you roll to the one that we started from */
08248       if (p == exit)
08249          break;
08250    }
08251    ast_mutex_unlock(lock);
08252    restart_monitor();
08253    if (callwait)
08254       *cause = AST_CAUSE_BUSY;
08255    else if (!tmp) {
08256       if (channelmatched) {
08257          if (busy)
08258             *cause = AST_CAUSE_BUSY;
08259       } else if (groupmatched) {
08260          *cause = AST_CAUSE_CONGESTION;
08261       } else {
08262          *cause = AST_CAUSE_CONGESTION;
08263       }
08264    }
08265       
08266    return tmp;
08267 }
08268 
08269 #ifdef HAVE_GSMAT
08270 static int zt_reset_span(int span, int sleep) {
08271    int ctl;
08272    int res;
08273 
08274    ctl = open("/dev/zap/ctl", O_RDWR);
08275    if (ctl < 0) {
08276       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
08277       return -1;
08278    }
08279    ast_verbose(VERBOSE_PREFIX_2 "Shutting down span %d. Please wait...\n", span);
08280    res = ioctl(ctl, ZT_SHUTDOWN, &span);
08281    if (res) {
08282       ast_log(LOG_WARNING, "error shutting down span %d\n", span);
08283       return -1;
08284    }
08285    usleep(sleep * 1000);
08286    ast_verbose(VERBOSE_PREFIX_2 "Starting up span %d. Please wait...\n", span);
08287    res = ioctl(ctl, ZT_STARTUP, &span);
08288    if (res) {
08289       ast_log(LOG_WARNING, "error starting up span %d\n", span);
08290       return -1;
08291    }
08292    ast_verbose(VERBOSE_PREFIX_2 "Reset of span %d completed.\n", span);
08293    return 0;
08294 }
08295 
08296 
08297 static void handle_gsm_event(struct zt_gsm *gsm, gsm_event *e)
08298 {
08299    struct ast_channel *c = NULL;
08300    int law = ZT_LAW_ALAW;
08301    int res = 0;
08302 
08303    switch(e->e) {
08304    case GSM_EVENT_DCHAN_UP:
08305       if (option_verbose > 2)
08306           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d registered to network!\n", gsm->span);
08307       gsm->available = 1;
08308       break;
08309    case GSM_EVENT_DCHAN_DOWN:
08310       if (option_verbose > 2)
08311           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span);
08312       gsm->available = 0;
08313 /*    ast_mutex_lock(&gsm->pvt->lock);
08314       gsm->pvt->alreadyhungup = 1;
08315       if (gsm->pvt->owner) {
08316           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08317       }
08318       ast_mutex_unlock(&gsm->pvt->lock); */
08319       break;
08320    case GSM_EVENT_RING:
08321       ast_mutex_lock(&gsm->pvt->lock);
08322       if (!ast_strlen_zero(e->ring.callingnum)) {
08323           strncpy(gsm->pvt->cid_num, e->ring.callingnum, sizeof(gsm->pvt->cid_num) - 1);
08324       } else {
08325           strncpy(gsm->pvt->cid_name, "CID withheld", sizeof(gsm->pvt->cid_name));
08326       }
08327       if (!ast_strlen_zero(gsm->exten)) {
08328           strncpy(gsm->pvt->exten, gsm->exten, sizeof(gsm->pvt->exten) - 1);
08329       } else {
08330           gsm->pvt->exten[0] = 's';
08331           gsm->pvt->exten[1] = '\0';
08332       }
08333       c = zt_new(gsm->pvt, AST_STATE_RING, 1, SUB_REAL, ZT_LAW_ALAW, AST_TRANS_CAP_SPEECH);
08334       if (c) {
08335           if (option_verbose > 2)
08336          ast_verbose(VERBOSE_PREFIX_3 "Ring on channel %d (from %s to %s)\n", e->ring.channel, e->ring.callingnum, gsm->exten);
08337           gsm->pvt->owner = c;
08338           if (ioctl(gsm->pvt->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08339          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", gsm->pvt->channel, law);
08340           res = zt_setlaw(gsm->pvt->subs[SUB_REAL].zfd, law);
08341           res = set_actual_gain(gsm->pvt->subs[SUB_REAL].zfd, 0, gsm->pvt->rxgain, gsm->pvt->txgain, law);
08342           if (res < 0) {
08343               ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", gsm->pvt->channel);
08344 //        } else {
08345 //            ast_log(LOG_NOTICE, "tx gain %f rx gain %f law %d pvt->law %d\n", gsm->pvt->txgain, gsm->pvt->rxgain, law, gsm->pvt->law);
08346           }
08347       }
08348       ast_mutex_unlock(&gsm->pvt->lock);
08349       break;
08350    case GSM_EVENT_HANGUP:
08351       ast_verbose(VERBOSE_PREFIX_3 "Got hang up on channel %d\n", e->hangup.channel);
08352       ast_mutex_lock(&gsm->pvt->lock);
08353       gsm->pvt->alreadyhungup = 1;
08354       if (gsm->pvt->owner) {
08355           gsm->pvt->owner->hangupcause = e->hangup.cause;
08356           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08357       }
08358       ast_mutex_unlock(&gsm->pvt->lock);
08359       break;
08360    case GSM_EVENT_ERROR:
08361       ast_log(LOG_WARNING, "Got error on channel\n");
08362       ast_mutex_lock(&gsm->pvt->lock);
08363       gsm->pvt->alreadyhungup = 1;
08364       if (gsm->pvt->owner) {
08365           gsm->pvt->owner->hangupcause = e->error.cause;
08366           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08367       }
08368       ast_mutex_unlock(&gsm->pvt->lock);
08369       if (e->error.hard) {
08370 //        gsm_poweroff(gsm->modul);
08371           zt_reset_span(gsm->span, 8000);
08372 //        gsm_restart(gsm->modul, 10000);
08373       } else {
08374 //        gsm_poweroff(gsm->modul);
08375           zt_reset_span(gsm->span, 8000);
08376 //        gsm_restart(gsm->modul, 10000);
08377       }
08378       break;
08379    case GSM_EVENT_ALERTING:
08380       ast_mutex_lock(&gsm->pvt->lock);
08381       gsm->pvt->subs[SUB_REAL].needringing =1;
08382       ast_mutex_unlock(&gsm->pvt->lock);
08383       break;
08384    case GSM_EVENT_ANSWER:
08385       ast_mutex_lock(&gsm->pvt->lock);
08386       gsm->pvt->dialing = 0;
08387       gsm->pvt->subs[SUB_REAL].needanswer =1;
08388       gsm->pvt->ignoredtmf = 0;
08389       ast_mutex_unlock(&gsm->pvt->lock);
08390       break;
08391    case GSM_EVENT_PIN_REQUIRED:
08392       gsm_send_pin(gsm->modul, gsm->pin);
08393       break;
08394    case GSM_EVENT_SM_RECEIVED:
08395       ast_verbose(VERBOSE_PREFIX_3 "SMS from %s received on span %d. (Text: %s) (PDU: %s)\n", e->sm_received.sender, gsm->span, e->sm_received.text, e->sm_received.pdu);
08396       manager_event(EVENT_FLAG_CALL, "Message received",
08397          "Span: %d\r\n"
08398          "Sender: %s\r\n"
08399          "SMSC: %s\r\n"
08400                "Length: %d\r\n"
08401          "Text: %s\r\n"
08402          "PDU: %s\r\n",
08403          gsm->span,
08404          e->sm_received.sender,
08405          e->sm_received.smsc,
08406          e->sm_received.len,
08407          e->sm_received.text,
08408          e->sm_received.pdu);
08409       break;
08410    default:
08411       ast_log(LOG_WARNING,"!! Unknown GSM event %d !!\n", e->e);
08412    }
08413 }
08414 
08415 static void *gsm_dchannel(void *vgsm)
08416 {
08417    struct zt_gsm *gsm = vgsm;
08418    gsm_event *e;
08419    struct timeval tv = {0,0}, *next;
08420    fd_set rfds, efds;
08421    int res,x;
08422 
08423    if (!gsm) return NULL;
08424 
08425    if (!gsm->modul) {
08426       fprintf(stderr, "No gsm_mod\n");
08427       return NULL;
08428    }
08429    gsm_set_debug(gsm->modul, GSM_DEBUG_NONE);
08430    for (;;) {
08431 
08432       /* Run the D-Channel */
08433       FD_ZERO(&rfds);
08434       FD_ZERO(&efds);
08435       FD_SET(gsm->fd, &rfds);
08436       FD_SET(gsm->fd, &efds);
08437 
08438       if ((next = gsm_schedule_next(gsm->modul))) {
08439          gettimeofday(&tv, NULL);
08440          tv.tv_sec = next->tv_sec - tv.tv_sec;
08441          tv.tv_usec = next->tv_usec - tv.tv_usec;
08442          if (tv.tv_usec < 0) {
08443             tv.tv_usec += 1000000;
08444             tv.tv_sec -= 1;
08445          }
08446          if (tv.tv_sec < 0) {
08447             tv.tv_sec = 0;
08448             tv.tv_usec = 0;
08449          }
08450       }
08451       res = select(gsm->fd + 1, &rfds, NULL, &efds, next ? &tv : NULL);
08452       e = NULL;
08453 
08454       ast_mutex_lock(&gsm->lock);
08455       if (!res) {
08456          e = gsm_schedule_run(gsm->modul);
08457       } else if (res > 0) {
08458          e = gsm_check_event(gsm->modul, 1);
08459       } else if (errno == ELAST) {
08460          res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08461          printf("Got Zaptel event: %d\n", x);
08462       } else if (errno != EINTR)
08463          fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno));
08464 
08465       if (!e) {
08466           e = gsm_check_event(gsm->modul, 0);
08467       }
08468 
08469       if (e) {
08470          handle_gsm_event(gsm, e);
08471       }
08472       ast_mutex_unlock(&gsm->lock);
08473 
08474       res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08475 
08476       if (!res && x) {
08477          switch (x) {
08478              case ZT_EVENT_NOALARM:
08479             ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", gsm->span);
08480             usleep(1000);
08481             gsm_restart(gsm->modul, 10000);
08482              break;
08483              case ZT_EVENT_ALARM:
08484             ast_log(LOG_NOTICE, "Alarm detected on span %d\n", gsm->span);
08485              break;
08486              default:
08487             fprintf(stderr, "Got event on GSM interface: %d\n", x);
08488          }
08489       }
08490 
08491 
08492    }
08493    return NULL;
08494 }
08495 
08496 #endif
08497 
08498 #ifdef HAVE_PRI
08499 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
08500 {
08501    struct zt_pvt *p;
08502    p = pri->crvs;
08503    while (p) {
08504       if (p->channel == crv)
08505          return p;
08506       p = p->next;
08507    }
08508    return NULL;
08509 }
08510 
08511 
08512 static int pri_find_principle(struct zt_pri *pri, int channel)
08513 {
08514    int x;
08515    int span = PRI_SPAN(channel);
08516    int spanfd;
08517    ZT_PARAMS param;
08518    int principle = -1;
08519    int explicit = PRI_EXPLICIT(channel);
08520    channel = PRI_CHANNEL(channel);
08521 
08522    if (!explicit) {
08523       spanfd = pri_active_dchan_fd(pri);
08524       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
08525          return -1;
08526       span = pris[param.spanno - 1].prilogicalspan;
08527    }
08528 
08529    for (x = 0; x < pri->numchans; x++) {
08530       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
08531          principle = x;
08532          break;
08533       }
08534    }
08535    
08536    return principle;
08537 }
08538 
08539 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
08540 {
08541    int x;
08542    int res = 0;
08543    struct zt_pvt *crv;
08544    if (!c) {
08545       if (principle < 0)
08546          return -1;
08547       return principle;
08548    }
08549    if ((principle > -1) && 
08550       (principle < pri->numchans) && 
08551       (pri->pvts[principle]) && 
08552       (pri->pvts[principle]->call == c))
08553       return principle;
08554    /* First, check for other bearers */
08555    for (x = 0; x < pri->numchans; x++) {
08556       if (!pri->pvts[x])
08557          continue;
08558       if (pri->pvts[x]->call == c) {
08559          /* Found our call */
08560          if (principle != x) {
08561             struct zt_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
08562 
08563             if (option_verbose > 2)
08564                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08565                   old->channel, new->channel);
08566             if (new->owner) {
08567                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08568                   old->channel, new->channel, new->channel);
08569                return -1;
08570             }
08571             /* Fix it all up now */
08572             new->owner = old->owner;
08573             new->outgoing = old->outgoing;
08574             old->owner = NULL;
08575             if (new->owner) {
08576                ast_string_field_build(new->owner, name, 
08577                             "Zap/%d:%d-%d", pri->trunkgroup,
08578                             new->channel, 1);
08579                new->owner->tech_pvt = new;
08580                new->owner->fds[0] = new->subs[SUB_REAL].zfd;
08581                new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
08582                old->subs[SUB_REAL].owner = NULL;
08583             } else
08584                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);
08585             new->call = old->call;
08586             old->call = NULL;
08587 
08588             /* Copy any DSP that may be present */
08589             new->dsp = old->dsp;
08590             new->dsp_features = old->dsp_features;
08591             old->dsp = NULL;
08592             old->dsp_features = 0;
08593 
08594             /* Copy faxhandled/digial, alreadyhungup */
08595             new->faxhandled = old->faxhandled;
08596             new->digital = old->digital;
08597             new->alreadyhungup = old->alreadyhungup;
08598 
08599             /* Copy law, gains, etc */
08600             new->law = old->law;
08601             if (ioctl(new->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &new->law) == -1)
08602                 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", new->channel, new->law);
08603             res = zt_setlaw(new->subs[SUB_REAL].zfd, new->law);
08604             if (res < 0)
08605                 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", new->channel);
08606             if (!new->digital) {
08607                 res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, new->rxgain, new->txgain, new->law);
08608             } else {
08609                 res = set_actual_gain(new->subs[SUB_REAL].zfd, 0, 0, 0, new->law);
08610             }
08611             if (res < 0)
08612                 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", new->channel);
08613 
08614             /* Shutdown old channel */
08615             zt_confmute(old, 0);
08616             update_conf(old);
08617             reset_conf(old);
08618             restore_gains(old);
08619             zt_disable_ec(old);
08620             zt_setlinear(old->subs[SUB_REAL].zfd, 0);
08621          }
08622          return principle;
08623       }
08624    }
08625    /* Now check for a CRV with no bearer */
08626    crv = pri->crvs;
08627    while (crv) {
08628       if (crv->call == c) {
08629          /* This is our match...  Perform some basic checks */
08630          if (crv->bearer)
08631             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08632          else if (pri->pvts[principle]->owner) 
08633             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08634          else {
08635             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08636                wakeup the potential sleeper */
08637             zt_close(crv->subs[SUB_REAL].zfd);
08638             pri->pvts[principle]->call = crv->call;
08639             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08640             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08641                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08642                            pri->trunkgroup, crv->channel);
08643             wakeup_sub(crv, SUB_REAL, pri);
08644          }
08645          return principle;
08646       }
08647       crv = crv->next;
08648    }
08649    if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
08650        ast_log(LOG_WARNING, "Call specified, but not found?\n");
08651    }
08652    return -1;
08653 }
08654 
08655 static void *do_idle_thread(void *vchan)
08656 {
08657    struct ast_channel *chan = vchan;
08658    struct zt_pvt *pvt = chan->tech_pvt;
08659    struct ast_frame *f;
08660    char ex[80];
08661    /* Wait up to 30 seconds for an answer */
08662    int newms, ms = 30000;
08663    if (option_verbose > 2) 
08664       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08665    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08666    if (ast_call(chan, ex, 0)) {
08667       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08668       ast_hangup(chan);
08669       return NULL;
08670    }
08671    while ((newms = ast_waitfor(chan, ms)) > 0) {
08672       f = ast_read(chan);
08673       if (!f) {
08674          /* Got hangup */
08675          break;
08676       }
08677       if (f->frametype == AST_FRAME_CONTROL) {
08678          switch (f->subclass) {
08679          case AST_CONTROL_ANSWER:
08680             /* Launch the PBX */
08681             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08682             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08683             chan->priority = 1;
08684             if (option_verbose > 3) 
08685                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08686             ast_pbx_run(chan);
08687             /* It's already hungup, return immediately */
08688             return NULL;
08689          case AST_CONTROL_BUSY:
08690             if (option_verbose > 3) 
08691                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08692             break;
08693          case AST_CONTROL_CONGESTION:
08694             if (option_verbose > 3) 
08695                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08696             break;
08697          };
08698       }
08699       ast_frfree(f);
08700       ms = newms;
08701    }
08702    /* Hangup the channel since nothing happend */
08703    ast_hangup(chan);
08704    return NULL;
08705 }
08706 
08707 #ifndef PRI_RESTART
08708 #error "Upgrade your libpri"
08709 #endif
08710 static void zt_pri_message(char *s, int span)
08711 {
08712    ast_verbose("%d %s", span, s);
08713 }
08714 
08715 static void zt_pri_error(char *s, int span)
08716 {
08717    ast_log(LOG_WARNING, "%d %s", span, s);
08718 }
08719 
08720 #ifdef HAVE_GSMAT
08721 static void zt_gsm_message(char *s, int channel)
08722 {
08723    ast_verbose("GSM %d: %s", channel, s);
08724 }
08725 
08726 static void zt_gsm_error(char *s, int channel)
08727 {
08728    ast_log(LOG_WARNING, "GSM %d: %s", channel, s);
08729 }
08730 #endif
08731 
08732 static int pri_check_restart(struct zt_pri *pri)
08733 {
08734    if ((pri->nodetype != PRI_NETWORK) && (pri->nodetype != PRI_CPE)) {
08735        return 0;
08736    }
08737    do {
08738       pri->resetpos++;
08739    } while ((pri->resetpos < pri->numchans) &&
08740        (!pri->pvts[pri->resetpos] ||
08741         pri->pvts[pri->resetpos]->call ||
08742         pri->pvts[pri->resetpos]->resetting));
08743    if (pri->resetpos < pri->numchans) {
08744       /* Mark the channel as resetting and restart it */
08745       pri->pvts[pri->resetpos]->resetting = 1;
08746       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08747    } else {
08748       pri->resetting = 0;
08749       time(&pri->lastreset);
08750    }
08751    return 0;
08752 }
08753 
08754 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08755 {
08756    int x;
08757    int redo;
08758    ast_mutex_unlock(&pri->lock);
08759    ast_mutex_lock(&p->lock);
08760    do {
08761       redo = 0;
08762       for (x = 0; x < 3; x++) {
08763          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08764             redo++;
08765             DEADLOCK_AVOIDANCE(&p->lock);
08766          }
08767          if (p->subs[x].owner) {
08768             ast_queue_hangup(p->subs[x].owner);
08769             ast_mutex_unlock(&p->subs[x].owner->lock);
08770          }
08771       }
08772    } while (redo);
08773    ast_mutex_unlock(&p->lock);
08774    ast_mutex_lock(&pri->lock);
08775    return 0;
08776 }
08777 
08778 static char * redirectingreason2str(int redirectingreason)
08779 {
08780    switch (redirectingreason) {
08781    case 0:
08782       return "UNKNOWN";
08783    case 1:
08784       return "BUSY";
08785    case 2:
08786       return "NO_REPLY";
08787    case 0xF:
08788       return "UNCONDITIONAL";
08789    default:
08790       return "NOREDIRECT";
08791    }
08792 }
08793 
08794 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08795 {
08796    switch (plan) {
08797    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08798       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08799       break;
08800    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08801       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08802       break;
08803    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08804       snprintf(buf, size, "%s%s", pri->localprefix, number);
08805       break;
08806    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08807       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08808       break;
08809    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08810       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08811       break;
08812    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08813       snprintf(buf, size, "%s", number);
08814       break;
08815    }
08816 }
08817 
08818 static void pri_make_callerid(struct zt_pri *pri, char *callerid, int callerid_len, char *callingnum, int callingnum_len, int callingplan, int callingpres, int stripmsd) {
08819     if (callingnum && (callingnum_len > stripmsd)) {
08820    callingnum += stripmsd;
08821     }
08822     switch (callingplan) {
08823    case PRI_INTERNATIONAL_ISDN:
08824        snprintf(callerid, callerid_len, "%s%s", pri->internationalprefix, callingnum);
08825        break;
08826    case PRI_NATIONAL_ISDN:
08827        snprintf(callerid, callerid_len, "%s%s", pri->nationalprefix, callingnum);
08828        break;
08829    case PRI_LOCAL_ISDN:
08830        snprintf(callerid, callerid_len, "%s%s", pri->localprefix, callingnum);
08831        break;
08832    case PRI_PRIVATE:
08833        snprintf(callerid, callerid_len, "%s%s", pri->privateprefix, callingnum);
08834        break;
08835    case PRI_UNKNOWN:
08836        snprintf(callerid, callerid_len, "%s%s", pri->unknownprefix, callingnum);
08837        break;
08838    default:
08839        snprintf(callerid, callerid_len, "%s", callingnum);
08840        break;
08841     }
08842 }
08843 
08844 static void *pri_dchannel(void *vpri)
08845 {
08846    struct zt_pri *pri = vpri;
08847    pri_event *e;
08848    struct pollfd fds[NUM_DCHANS];
08849    int res;
08850    int chanpos = 0;
08851    int x;
08852    int haveidles;
08853    int activeidles;
08854    int nextidle = -1;
08855    struct ast_channel *c = NULL;
08856    struct timeval tv, lowest, *next;
08857    struct timeval lastidle = { 0, 0 };
08858    int doidling=0;
08859    char *cc;
08860    char idlen[80];
08861    struct ast_channel *idle;
08862    pthread_t p;
08863    time_t t;
08864    int i, which=-1;
08865    int numdchans;
08866    int cause=0;
08867    struct zt_pvt *crv;
08868    pthread_t threadid;
08869    pthread_attr_t attr;
08870    char ani2str[6];
08871    char plancallingnum[256];
08872    char plancallingani[256];
08873    char calledtonstr[10];
08874    
08875    gettimeofday(&lastidle, NULL);
08876    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
08877       /* Need to do idle dialing, check to be sure though */
08878       cc = strchr(pri->idleext, '@');
08879       if (cc) {
08880          *cc = '\0';
08881          cc++;
08882          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
08883 #if 0
08884          /* Extensions may not be loaded yet */
08885          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
08886             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
08887          else
08888 #endif
08889             doidling = 1;
08890       } else
08891          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
08892    }
08893    for (;;) {
08894       for (i = 0; i < NUM_DCHANS; i++) {
08895          if (!pri->dchannels[i])
08896             break;
08897          fds[i].fd = pri->fds[i];
08898          fds[i].events = POLLIN | POLLPRI;
08899          fds[i].revents = 0;
08900       }
08901       numdchans = i;
08902       time(&t);
08903       ast_mutex_lock(&pri->lock);
08904       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
08905          if (pri->resetting && pri_is_up(pri)) {
08906             if (pri->resetpos < 0)
08907                pri_check_restart(pri);
08908          } else {
08909             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
08910                pri->resetting = 1;
08911                pri->resetpos = -1;
08912             }
08913          }
08914       }
08915       /* Look for any idle channels if appropriate */
08916       if (doidling && pri_is_up(pri)) {
08917          nextidle = -1;
08918          haveidles = 0;
08919          activeidles = 0;
08920          for (x = pri->numchans; x >= 0; x--) {
08921             if (pri->pvts[x] && !pri->pvts[x]->owner && 
08922                 !pri->pvts[x]->call) {
08923                if (haveidles < pri->minunused) {
08924                   haveidles++;
08925                } else if (!pri->pvts[x]->resetting) {
08926                   nextidle = x;
08927                   break;
08928                }
08929             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
08930                activeidles++;
08931          }
08932          if (nextidle > -1) {
08933             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
08934                /* Don't create a new idle call more than once per second */
08935                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
08936                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
08937                if (idle) {
08938                   pri->pvts[nextidle]->isidlecall = 1;
08939                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
08940                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
08941                      zt_hangup(idle);
08942                   }
08943                } else
08944                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
08945                gettimeofday(&lastidle, NULL);
08946             }
08947          } else if ((haveidles < pri->minunused) &&
08948                (activeidles > pri->minidle)) {
08949             /* Mark something for hangup if there is something 
08950                that can be hungup */
08951             for (x = pri->numchans; x >= 0; x--) {
08952                /* find a candidate channel */
08953                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
08954                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08955                   haveidles++;
08956                   /* Stop if we have enough idle channels or
08957                     can't spare any more active idle ones */
08958                   if ((haveidles >= pri->minunused) ||
08959                       (activeidles <= pri->minidle))
08960                      break;
08961                } 
08962             }
08963          }
08964       }
08965       /* Start with reasonable max */
08966       lowest = ast_tv(60, 0);
08967       for (i = 0; i < NUM_DCHANS; i++) {
08968          /* Find lowest available d-channel */
08969          if (!pri->dchannels[i])
08970             break;
08971          if ((next = pri_schedule_next(pri->dchans[i]))) {
08972             /* We need relative time here */
08973             tv = ast_tvsub(*next, ast_tvnow());
08974             if (tv.tv_sec < 0) {
08975                tv = ast_tv(0,0);
08976             }
08977             if (doidling || pri->resetting) {
08978                if (tv.tv_sec > 1) {
08979                   tv = ast_tv(1, 0);
08980                }
08981             } else {
08982                if (tv.tv_sec > 60) {
08983                   tv = ast_tv(60, 0);
08984                }
08985             }
08986          } else if (doidling || pri->resetting) {
08987             /* Make sure we stop at least once per second if we're
08988                monitoring idle channels */
08989             tv = ast_tv(1,0);
08990          } else {
08991             /* Don't poll for more than 60 seconds */
08992             tv = ast_tv(60, 0);
08993          }
08994          if (!i || ast_tvcmp(tv, lowest) < 0) {
08995             lowest = tv;
08996          }
08997       }
08998       ast_mutex_unlock(&pri->lock);
08999 
09000       e = NULL;
09001       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
09002 
09003       ast_mutex_lock(&pri->lock);
09004       if (!res) {
09005          for (which = 0; which < NUM_DCHANS; which++) {
09006             if (!pri->dchans[which])
09007                break;
09008             /* Just a timeout, run the scheduler */
09009             e = pri_schedule_run(pri->dchans[which]);
09010             if (e)
09011                break;
09012          }
09013       } else if (res > -1) {
09014          for (which = 0; which < NUM_DCHANS; which++) {
09015             if (!pri->dchans[which])
09016                break;
09017             if (fds[which].revents & POLLPRI) {
09018                /* Check for an event */
09019                x = 0;
09020                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
09021                if ((pri->nodetype != BRI_CPE) && (pri->nodetype != BRI_CPE_PTMP)) {
09022                    /* dont annoy BRI TE mode users with layer2layer alarms */
09023                    if (x)
09024                   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);
09025                }
09026                /* Keep track of alarm state */  
09027                if (x == ZT_EVENT_ALARM) {
09028                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
09029                   pri_find_dchan(pri);
09030                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09031                       if (pri->pri) {
09032                      for (i=0; i<pri->numchans; i++) {
09033                          struct zt_pvt *p = pri->pvts[i];
09034                          if (p) {
09035                         if (p->call) {
09036                             if (p->pri && p->pri->pri) {
09037                               pri_destroycall(p->pri->pri, p->call);
09038                            p->call = NULL;
09039                            p->tei = -1;
09040                             } else
09041                            ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09042                         }
09043                         if (p->owner)
09044                             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09045                         p->inalarm = 1;
09046                          }
09047                      }
09048                      pri_shutdown(pri->pri);
09049                       }
09050                   }
09051                } else if (x == ZT_EVENT_NOALARM) {
09052                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09053                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09054                   //    pri->dchanavail[which] |= DCHAN_UP;
09055                   } else {
09056                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09057                       pri_restart(pri->dchans[which]);
09058                   }
09059                }
09060             
09061                if (option_debug)
09062                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
09063             } else if (fds[which].revents & POLLIN) {
09064                e = pri_check_event(pri->dchans[which]);
09065             }
09066             if (e)
09067                break;
09068          }
09069       } else if (errno != EINTR)
09070          ast_log(LOG_WARNING, "pri_event returned error %d (%s) on span %d\n", errno, strerror(errno), pri->span);
09071       if (e) {
09072          if (pri->debug)
09073             pri_dump_event(pri->dchans[which], e);
09074 
09075          if (e->e != PRI_EVENT_DCHAN_DOWN) {
09076             if (!(pri->dchanavail[which] & DCHAN_UP)) {
09077                if (option_verbose > 1) 
09078                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09079             }
09080             pri->dchanavail[which] |= DCHAN_UP;
09081          } else {
09082             if (pri->dchanavail[which] & DCHAN_UP) {
09083                if (option_verbose > 1) 
09084                   ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
09085             }
09086             pri->dchanavail[which] &= ~DCHAN_UP;
09087          }
09088 
09089          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
09090             /* Must be an NFAS group that has the secondary dchan active */
09091             pri->pri = pri->dchans[which];
09092 
09093          switch (e->e) {
09094          case PRI_EVENT_DCHAN_UP:
09095             if (pri->nodetype == BRI_NETWORK_PTMP) {
09096                 if (option_verbose > 3)
09097                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09098             } else if (pri->nodetype == BRI_CPE_PTMP) {
09099                 if (option_verbose > 3)
09100                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09101             } else {
09102                 if (option_verbose > 1)
09103                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09104             }
09105 
09106             if (!pri->pri) pri_find_dchan(pri);
09107 
09108             /* Note presense of D-channel */
09109             time(&pri->lastreset);
09110 
09111             /* Restart in 5 seconds */
09112             if (pri->resetinterval > -1) {
09113                pri->lastreset -= pri->resetinterval;
09114                pri->lastreset += 5;
09115             }
09116             pri->resetting = 0;
09117             /* Take the channels from inalarm condition */
09118             for (i = 0; i < pri->numchans; i++)
09119                if (pri->pvts[i]) {
09120                   pri->pvts[i]->inalarm = 0;
09121                }
09122             break;
09123          case PRI_EVENT_DCHAN_DOWN:
09124             if (pri->nodetype == BRI_NETWORK_PTMP) {
09125                 if (option_verbose > 3)
09126                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09127                 // PTMP BRIs have N dchans, handled by libpri
09128                 if (e->gen.tei == 0) break;
09129             }
09130             pri_find_dchan(pri);
09131             if (!pri_is_up(pri)) {
09132                pri->resetting = 0;
09133                /* Hangup active channels and put them in alarm mode */
09134                for (i = 0; i < pri->numchans; i++) {
09135                   struct zt_pvt *p = pri->pvts[i];
09136                   if (p) {
09137                       if ((p->tei == e->gen.tei) || (pri->nodetype != BRI_NETWORK_PTMP)) {
09138                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
09139                         /* T309 is not enabled : hangup calls when alarm occurs */
09140                         if (p->call) {
09141                            if (p->pri && p->pri->pri) {
09142                               pri_hangup(p->pri->pri, p->call, -1, -1);
09143                               pri_destroycall(p->pri->pri, p->call);
09144                               p->call = NULL;
09145                            } else
09146                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09147                         }
09148                         p->tei = -1;
09149                         if (p->realcall) {
09150                            pri_hangup_all(p->realcall, pri);
09151                         } else if (p->owner)
09152                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09153                      }
09154                      p->inalarm = 1;
09155                   }
09156                }
09157                 }
09158             }
09159             break;
09160          case PRI_EVENT_RESTART:
09161             if (e->restart.channel > -1) {
09162                chanpos = pri_find_principle(pri, e->restart.channel);
09163                if (chanpos < 0)
09164                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
09165                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09166                else {
09167                   if (option_verbose > 2)
09168                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
09169                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09170                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09171                   if (pri->pvts[chanpos]->call) {
09172                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
09173                      pri->pvts[chanpos]->call = NULL;
09174                   }
09175                   /* Force soft hangup if appropriate */
09176                   if (pri->pvts[chanpos]->realcall) 
09177                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09178                   else if (pri->pvts[chanpos]->owner)
09179                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09180                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09181                }
09182             } else {
09183                if (option_verbose > 2)
09184                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
09185                for (x = 0; x < pri->numchans; x++)
09186                   if (pri->pvts[x]) {
09187                      ast_mutex_lock(&pri->pvts[x]->lock);
09188                      if (pri->pvts[x]->call) {
09189                         pri_destroycall(pri->pri, pri->pvts[x]->call);
09190                         pri->pvts[x]->call = NULL;
09191                      }
09192                      if (pri->pvts[x]->realcall)
09193                         pri_hangup_all(pri->pvts[x]->realcall, pri);
09194                      else if (pri->pvts[x]->owner)
09195                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09196                      ast_mutex_unlock(&pri->pvts[x]->lock);
09197                   }
09198             }
09199             break;
09200          case PRI_EVENT_KEYPAD_DIGIT:
09201             chanpos = pri_find_principle(pri, e->digit.channel);
09202             if (chanpos < 0) {
09203                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
09204                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
09205             } else {
09206                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
09207                if (chanpos > -1) {
09208                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09209                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
09210                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
09211                      /* how to do that */
09212                      int digitlen = strlen(e->digit.digits);
09213                      char digit;
09214                      int i;               
09215                      for (i = 0; i < digitlen; i++) { 
09216                         digit = e->digit.digits[i];
09217                         {
09218                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09219                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09220                         }
09221                      }
09222                   }
09223                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09224                }
09225             }
09226             break;
09227          case PRI_EVENT_INFO_RECEIVED:
09228             chanpos = pri_find_principle(pri, e->ring.channel);
09229             if (chanpos < 0) {
09230                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
09231                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09232             } else {
09233                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
09234                if (chanpos > -1) {
09235 //             ast_log(LOG_NOTICE, "INFO received on  channel %d/%d span %d\n",
09236 //                PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09237                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09238                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
09239                   if (pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
09240                      /* how to do that */
09241                      int digitlen = strlen(e->ring.callednum);
09242                      char digit;
09243                      int i;               
09244                      for (i = 0; i < digitlen; i++) { 
09245                         digit = e->ring.callednum[i];
09246                         {
09247                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09248                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09249                         }
09250                      }
09251                      if (!pri->overlapdial) {
09252                          strncat(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
09253                          if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09254                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09255                          } else {
09256                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09257                          }
09258                      }
09259                   }
09260                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09261                }
09262             }
09263             break;
09264          case PRI_EVENT_RING:
09265             crv = NULL;
09266             if (e->ring.channel == -1) {
09267                /* if no channel specified find one empty */
09268                chanpos = pri_find_empty_chan(pri, 1);
09269             } else {
09270                chanpos = pri_find_principle(pri, e->ring.channel);
09271             }
09272             /* if no channel specified find one empty */
09273             if (chanpos < 0) {
09274                /* no channel specified and no free channel. this is a callwating SETUP */
09275                if (e->ring.channel <= 0) {
09276                    if (option_verbose > 2)
09277                   ast_verbose(VERBOSE_PREFIX_3 "Ignoring callwaiting SETUP on channel %d/%d span %d %d\n", PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span, e->ring.channel);
09278                    pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY, -1);
09279                    break;
09280                }
09281             } else {
09282                /* ok, we got a b channel for this call, lock it */
09283                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09284                if (pri->pvts[chanpos]->owner) {
09285                    /* safety check, for messed up retransmissions? */
09286                    if (pri->pvts[chanpos]->call == e->ring.call) {
09287                   ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
09288                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09289                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09290                   chanpos = -1;
09291                   break;
09292                    } else {
09293                   ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n",
09294                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09295                   if (pri->pvts[chanpos]->realcall) {
09296                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09297                   } else {
09298                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09299                      /* XXX destroy the call here, so we can accept the retransmission as a new call */
09300                      pri_destroycall(pri->pri, e->ring.call);
09301                   }
09302                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09303                   chanpos = -1;
09304                   break;
09305                    }
09306                }
09307                if (chanpos > -1) {
09308                   /* everything is ok with the b channel */
09309                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09310                }
09311             }
09312             /* actually, we already got a valid channel by now */
09313             if (chanpos > -1) {
09314                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09315                /* dont detect dtmfs before the signalling is done */
09316                disable_dtmf_detect(pri->pvts[chanpos]);
09317                /* this channel is owned by this TEI */
09318                pri->pvts[chanpos]->tei = e->ring.tei;
09319                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
09320                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
09321                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
09322                   if (crv)
09323                      ast_mutex_lock(&crv->lock);
09324                   if (!crv || crv->owner) {
09325                      pri->pvts[chanpos]->call = NULL;
09326                      if (crv) {
09327                         if (crv->owner)
09328                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09329                         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);
09330                      } else
09331                         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);
09332                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE, -1);
09333                      if (crv)
09334                         ast_mutex_unlock(&crv->lock);
09335                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09336                      break;
09337                   }
09338                }
09339                /* assign call to b channel */
09340                pri->pvts[chanpos]->call = e->ring.call;
09341                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
09342                if (pri->pvts[chanpos]->use_callerid) {
09343                   ast_shrink_phone_number(plancallingnum);
09344                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
09345 #ifdef PRI_ANI
09346                   if (!ast_strlen_zero(e->ring.callingani)) {
09347                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
09348                      ast_shrink_phone_number(plancallingani);
09349                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
09350                   } else {
09351                      pri->pvts[chanpos]->cid_ani[0] = '\0';
09352                   }
09353 #endif
09354                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
09355                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
09356                } else {
09357                   pri->pvts[chanpos]->cid_num[0] = '\0';
09358                   pri->pvts[chanpos]->cid_ani[0] = '\0';
09359                   pri->pvts[chanpos]->cid_name[0] = '\0';
09360                   pri->pvts[chanpos]->cid_ton = 0;
09361                }
09362                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
09363                           e->ring.redirectingnum, e->ring.callingplanrdnis);
09364                /* get callingpres */
09365                pri->pvts[chanpos]->cid_pres = e->ring.callingpres;
09366                switch (e->ring.callingpres) {
09367                    case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
09368                    case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
09369                    case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
09370                    case PRES_PROHIB_NETWORK_NUMBER:
09371                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->withheldcid, sizeof(pri->pvts[chanpos]->cid_name));
09372                   break;
09373                    case PRES_NUMBER_NOT_AVAILABLE:
09374                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->nocid, sizeof(pri->pvts[chanpos]->cid_name));
09375                   break;
09376                }
09377                /* If immediate=yes go to s|1 */
09378                if (pri->pvts[chanpos]->immediate) {
09379                   if (option_verbose > 2)
09380                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
09381                   pri->pvts[chanpos]->exten[0] = 's';
09382                   pri->pvts[chanpos]->exten[1] = '\0';
09383                } else if (ast_strlen_zero(e->ring.callednum)) {
09384                    /* called party number is empty */
09385                    if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09386                   if (!pri->overlapdial) {
09387                       // be able to set digittimeout for BRI phones
09388                       pri->pvts[chanpos]->exten[0] = 's';
09389                       pri->pvts[chanpos]->exten[1] = '\0';
09390                       tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09391                   } else {
09392                       pri->pvts[chanpos]->exten[0] = '\0';
09393                   }
09394                    } else {
09395                   if (pri->nodetype == BRI_CPE) {
09396                       /* fix for .at p2p bri lines */
09397                       pri->pvts[chanpos]->exten[0] = 's';
09398                       pri->pvts[chanpos]->exten[1] = '\0';
09399                   } else if (pri->overlapdial) {
09400                       pri->pvts[chanpos]->exten[0] = '\0';
09401                   } else {
09402                       /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
09403                       pri->pvts[chanpos]->exten[0] = 's';
09404                       pri->pvts[chanpos]->exten[1] = '\0';
09405                   }
09406                    }
09407                    /* No number yet, but received "sending complete"? */
09408                       if (e->ring.complete) {
09409                   if (option_verbose > 2)
09410                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
09411                   pri->pvts[chanpos]->exten[0] = 's';
09412                   pri->pvts[chanpos]->exten[1] = '\0';
09413                    }
09414                } else {
09415                   /* Get called number */
09416                   pri_make_callerid(pri, pri->pvts[chanpos]->dnid, sizeof(pri->pvts[chanpos]->dnid), e->ring.callednum, sizeof(e->ring.callednum),  e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
09417                   pri_make_callerid(pri, pri->pvts[chanpos]->exten, sizeof(pri->pvts[chanpos]->exten), e->ring.callednum, sizeof(e->ring.callednum), e->ring.calledplan, 0, pri->pvts[chanpos]->stripmsd);
09418                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09419                       /* if we get the next digit we should stop the dialtone */
09420                       if (!pri->overlapdial) {
09421                      // with overlapdial=no the exten is always prefixed by "s"
09422                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09423                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09424                      } else {
09425                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09426                      }
09427                       } else {
09428                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten)) {
09429                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09430                      } else {
09431                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09432                      }
09433                       }
09434                   }
09435                }
09436                /* Part 3: create channel, setup audio... */
09437                /* Set DNID on all incoming calls -- even immediate */
09438                if (!ast_strlen_zero(e->ring.callednum))
09439                   strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1);
09440                /* Make sure extension exists (or in overlap dial mode, can exist) */
09441                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
09442                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09443                   /* Setup law */
09444                   int law;
09445                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
09446                      /* Set to audio mode at this point */
09447                      law = 1;
09448                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
09449                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
09450                   }
09451                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
09452                      law = ZT_LAW_ALAW;
09453                   else
09454                      law = ZT_LAW_MULAW;
09455                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
09456                   if (res < 0) 
09457                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
09458                   if (IS_DIGITAL(e->ring.ctype)) {
09459                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
09460                   } else {
09461                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
09462                   }
09463                   if (res < 0)
09464                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
09465                   if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09466                       if (e->ring.complete || !pri->overlapdial) {
09467                      /* Just announce proceeding */
09468                      pri->pvts[chanpos]->proceeding = 1;
09469                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09470                       } else {
09471                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
09472                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09473                      else
09474                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09475                       }
09476                   } else {
09477                      /* BRI_NETWORK | BRI_NETWORK_PTMP */
09478                      if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) {
09479                          /* send a SETUP_ACKNOWLEDGE */
09480                          pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09481                      } else {
09482                          /* send an ALERTING ??? wtf */
09483                      //    pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09484                          pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09485                      }
09486                   }
09487                   /* overlapdial = yes  and the extension can be valid */
09488                   /* Get the use_callingpres state */
09489                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
09490                
09491                   /* Start PBX */
09492                   if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09493                      /* Release the PRI lock while we create the channel */
09494                      ast_mutex_unlock(&pri->lock);
09495                      if (crv) {
09496                         /* Set bearer and such */
09497                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
09498                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09499                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09500                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09501                         }
09502                         pri->pvts[chanpos]->owner = &inuse;
09503                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
09504                      } else {
09505                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09506                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09507                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09508                         }
09509                         zt_enable_ec(pri->pvts[chanpos]);  /* XXX rethink */
09510                      }
09511 
09512                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09513 
09514                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
09515                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09516                      }
09517                         if (!ast_strlen_zero(e->ring.callingnum)) {
09518                          char tmpstr[256];
09519                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09520                          pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09521                      }
09522                      if (!ast_strlen_zero(e->ring.callingani)) {
09523                          char tmpstr[256];
09524                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09525                          pbx_builtin_setvar_helper(c, "PRI_USER_CID", tmpstr);
09526                      }
09527                      if (e->ring.ani2 >= 0) {
09528                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
09529                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09530                      }
09531 
09532 #ifdef SUPPORT_USERUSER
09533                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
09534                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09535                      }
09536 #endif
09537 
09538                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09539                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09540                      if (e->ring.redirectingreason >= 0)
09541                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09542                   
09543                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09544                      ast_mutex_lock(&pri->lock);
09545 
09546                      pthread_attr_init(&attr);
09547                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09548                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
09549                         if (option_verbose > 2)
09550                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09551                               pri->pvts[chanpos]->digital ? "data" : "voice", plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
09552                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09553                      } else {
09554                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09555                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09556                         if (c)
09557                            ast_hangup(c);
09558                         else {
09559                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09560                            pri->pvts[chanpos]->call = NULL;
09561                         }
09562                      }
09563                      pthread_attr_destroy(&attr);
09564                   } else  {
09565                      /* overlapdial = no */
09566                      ast_mutex_unlock(&pri->lock);
09567                      /* Release PRI lock while we create the channel */
09568                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
09569                      if (c && (e->ring.lowlayercompat[0] > 0)) {
09570                          memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09571                      }
09572                      if (c) {
09573                         char calledtonstr[10];
09574 
09575                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09576 
09577                         if (e->ring.ani2 >= 0) {
09578                            snprintf(ani2str, 5, "%d", e->ring.ani2);
09579                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09580                         }
09581 
09582 #ifdef SUPPORT_USERUSER
09583                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
09584                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09585                         }
09586 #endif
09587 
09588                         if (e->ring.redirectingreason >= 0)
09589                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09590                      
09591                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09592                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09593 
09594                         ast_mutex_lock(&c->lock);
09595                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
09596                         ast_mutex_lock(&pri->lock);
09597 
09598                         if (option_verbose > 2)
09599                            ast_verbose(VERBOSE_PREFIX_3 "Accepting %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09600                               pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten,
09601                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09602                         zt_enable_ec(pri->pvts[chanpos]);
09603                          if(!ast_strlen_zero(e->ring.callingsubaddr)) {
09604                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09605                          }
09606                             if (!ast_strlen_zero(e->ring.callingnum)) {
09607                         char tmpstr[256];
09608                              pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09609                              pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09610                          }
09611                          if (!ast_strlen_zero(e->ring.callingani)) {
09612                         char tmpstr[256];
09613                              pri_make_callerid(pri, tmpstr,sizeof(tmpstr),  e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09614                              pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
09615                          }
09616                          if (!ast_strlen_zero(e->ring.useruserinfo)) {
09617                              pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
09618                          }
09619                      } else {
09620 
09621                         ast_mutex_lock(&pri->lock);
09622 
09623                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09624                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09625                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09626                         pri->pvts[chanpos]->call = NULL;
09627                      }
09628                   }
09629                } else {
09630                /* invalid extension */
09631                   if (option_verbose > 2)
09632                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
09633                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
09634                            pri->pvts[chanpos]->prioffset, pri->span);
09635                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED, -1);
09636                   pri->pvts[chanpos]->call = NULL;
09637                   pri->pvts[chanpos]->exten[0] = '\0';
09638                }
09639                if (crv)
09640                   ast_mutex_unlock(&crv->lock);
09641                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09642                if (c)
09643                   ast_mutex_unlock(&c->lock);
09644             } else {
09645                if (e->ring.flexible)
09646                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, -1);
09647                else
09648                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, -1);
09649             }
09650             break;
09651          case PRI_EVENT_RINGING:
09652             chanpos = pri_find_principle(pri, e->ringing.channel);
09653             if (chanpos < 0) {
09654                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
09655                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09656             } else {
09657                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
09658                if (chanpos < 0) {
09659                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
09660                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09661                } else {
09662                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09663                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09664                   // XXX   zt_enable_ec(pri->pvts[chanpos]);
09665                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
09666                      pri->pvts[chanpos]->alerting = 1;
09667                   } else
09668                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
09669 #ifdef PRI_PROGRESS_MASK
09670                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09671 #else
09672                   if (e->ringing.progress == 8) {
09673 #endif
09674                      /* Now we can do call progress detection */
09675                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09676                         /* RINGING detection isn't required because we got ALERTING signal */
09677                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
09678                         pri->pvts[chanpos]->dsp_features = 0;
09679                      }
09680                   }
09681 
09682 #ifdef SUPPORT_USERUSER
09683                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
09684                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09685                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09686                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
09687                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09688                   }
09689 #endif
09690 
09691                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09692                }
09693             }
09694             break;
09695          case PRI_EVENT_PROGRESS:
09696             /* Get chan value if e->e is not PRI_EVENT_RINGING */
09697             chanpos = pri_find_principle(pri, e->proceeding.channel);
09698             if (chanpos > -1) {
09699                 if ((pri->pvts[chanpos]->priindication_oob == 2) && (e->proceeding.cause == PRI_CAUSE_USER_BUSY)) {
09700                /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */
09701                if (pri->pvts[chanpos]->owner) {
09702                    pri->pvts[chanpos]->owner->hangupcause = AST_CAUSE_USER_BUSY;
09703                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09704                }
09705                 } else {
09706 #ifdef PRI_PROGRESS_MASK
09707                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
09708 #else
09709                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
09710 #endif
09711                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
09712 
09713                   if (e->proceeding.cause > -1) {
09714                      if (option_verbose > 2)
09715                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
09716 
09717                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
09718                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
09719                         if (pri->pvts[chanpos]->owner) {
09720                            if (option_verbose > 2)
09721                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
09722 
09723                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
09724                            f.subclass = AST_CONTROL_BUSY;
09725                         }
09726                      }
09727                   }
09728                   
09729                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09730                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
09731                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09732                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09733 #ifdef PRI_PROGRESS_MASK
09734                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09735 #else
09736                   if (e->proceeding.progress == 8) {
09737 #endif
09738                      /* Now we can do call progress detection */
09739                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09740                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09741                         pri->pvts[chanpos]->dsp_features = 0;
09742                      }
09743                   }
09744                   pri->pvts[chanpos]->progress = 1;
09745                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09746                }
09747                 }
09748             }
09749             break;
09750          case PRI_EVENT_PROCEEDING:
09751             chanpos = pri_find_principle(pri, e->proceeding.channel);
09752             if (chanpos > -1) {
09753                 chanpos = pri_fixup_principle(pri, chanpos, e->proceeding.call);
09754                 if (chanpos < 0) {
09755                ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n",
09756                   PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
09757                chanpos = -1;
09758                 } else {
09759                if (!pri->pvts[chanpos]->proceeding) {
09760                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
09761                   
09762                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09763                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
09764                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09765                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09766 #ifdef PRI_PROGRESS_MASK
09767                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09768 #else
09769                   if (e->proceeding.progress == 8) {
09770 #endif
09771                      /* Now we can do call progress detection */
09772                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09773                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09774                         pri->pvts[chanpos]->dsp_features = 0;
09775                      }
09776                      /* Bring voice path up */
09777                      f.subclass = AST_CONTROL_PROGRESS;
09778                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
09779                   }
09780                   pri->pvts[chanpos]->proceeding = 1;
09781                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09782                }
09783                 }
09784             }
09785             break;
09786          case PRI_EVENT_FACNAME:
09787             chanpos = pri_find_principle(pri, e->facname.channel);
09788             if (chanpos < 0) {
09789                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09790                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09791             } else {
09792                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09793                if (chanpos < 0) {
09794                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09795                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09796                } else {
09797                   /* Re-use *69 field for PRI */
09798                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09799                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09800                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09801                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09802                   zt_enable_ec(pri->pvts[chanpos]);
09803                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09804                }
09805             }
09806             break;            
09807          case PRI_EVENT_SUSPEND_REQ:
09808             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09809                 pri_suspend_reject(pri->pri, e->suspend_req.call, "");
09810                 break;
09811             }
09812             chanpos = pri_find_principle(pri, e->suspend_req.channel);
09813             if (chanpos < 0)  {
09814                ast_log(LOG_WARNING, "Suspend requested on unconfigured channel %d span %d\n", chanpos, pri->span);
09815                chanpos = -1;
09816             }
09817 
09818             if (chanpos > -1) {
09819                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
09820                 if (pri->pvts[chanpos]->owner) {
09821                if (ast_bridged_channel(pri->pvts[chanpos]->owner)) {
09822                    struct zt_suspended_call *zpc;
09823                    char tmpstr[256];
09824                    zpc = malloc(sizeof(struct zt_suspended_call));
09825                    if (!zpc) {
09826                   ast_log(LOG_ERROR, "unable to malloc zt_suspended_call\n");
09827                   break;
09828                    }
09829                    strncpy(zpc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zpc->msn));
09830                    strncpy(zpc->callid,  e->suspend_req.callid, sizeof(zpc->callid));
09831                    ast_masq_park_call(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, 0, &zpc->parked_at);
09832                    zpc->next = pri->suspended_calls;
09833                    pri->suspended_calls = zpc;
09834                    snprintf(tmpstr, sizeof(tmpstr), "Parked at %d", zpc->parked_at);
09835                    pri_suspend_acknowledge(pri->pri, e->suspend_req.call,tmpstr);
09836                    pri->pvts[chanpos]->call = NULL;
09837                    pri->pvts[chanpos]->tei = -1;
09838                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09839                } else {
09840                    pri_suspend_reject(pri->pri, e->suspend_req.call, "cant park a non-bridge");
09841                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09842                    break;
09843                }
09844                 } else {
09845                pri_suspend_reject(pri->pri, e->suspend_req.call, "");
09846                 }
09847                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09848             }
09849             break;
09850          case PRI_EVENT_RESUME_REQ:
09851             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09852                 break;
09853             }
09854             chanpos = pri_find_empty_chan(pri, 1);
09855             if (chanpos < 0) {
09856                pri_resume_reject(pri->pri, e->resume_req.call,"All channels busy");
09857                ast_log(LOG_WARNING, "Resume requested on odd channel number %d span %d\n", chanpos, pri->span);
09858                chanpos = -1;
09859             } else if (!pri->pvts[chanpos]) {
09860                pri_resume_reject(pri->pri, e->resume_req.call,"General protection fault in module 0x0BRI");
09861                chanpos = -1;
09862             }
09863 
09864             if (chanpos > -1) {
09865                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
09866                 if (!pri->pvts[chanpos]->owner) {
09867                struct zt_suspended_call *zpc, *zpcl;
09868                int unparked=0;
09869                char extenstr[255], temp[255];
09870                zpc = NULL;
09871                zpcl = pri->suspended_calls;
09872                while (zpcl) {
09873                //    ast_log(LOG_NOTICE, "zpc->parked_at %d zpcl->callid %s\n",zpcl->parked_at, zpcl->callid);
09874                    if (((strlen(zpcl->callid) == 0) && (strlen(e->resume_req.callid)==0)) || (!strcmp(zpcl->callid,e->resume_req.callid))) {
09875                   int law;
09876                   // found a parked call
09877                   snprintf(extenstr, sizeof(extenstr), "%d", zpcl->parked_at);
09878                   strncpy(pri->pvts[chanpos]->exten, extenstr, sizeof(pri->pvts[chanpos]->exten));
09879                // strncpy(pri->pvts[chanpos]->context, ast_parking_con(), sizeof(pri->pvts[chanpos]->context));
09880                        pri->pvts[chanpos]->call = e->resume_req.call;
09881                        law = 1;
09882                        if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
09883                          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
09884                // uhh ohh...what shall we do without the bearer cap???
09885                   law = ZT_LAW_ALAW;
09886                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
09887                   if (res < 0)
09888                       ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
09889                   if (!pri->pvts[chanpos]->digital) {
09890                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
09891                   } else {
09892                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
09893                   }
09894                   if (res < 0)
09895                       ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
09896                   /* Start PBX */
09897                   c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 1, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
09898                   if (c) {
09899                       pri->pvts[chanpos]->owner = c;
09900                       pri->pvts[chanpos]->call = e->resume_req.call;
09901                       zt_enable_ec(pri->pvts[chanpos]);
09902                       zt_train_ec(pri->pvts[chanpos]);
09903                   } else {
09904                       ast_log(LOG_ERROR, "unable to start pbx\n");
09905                   }
09906 
09907                   if (zpc) {
09908                       zpc->next = zpcl->next;
09909                       free(zpcl);
09910                       zpcl = zpc->next;
09911                   } else {
09912                       // remove head
09913                       pri->suspended_calls = zpcl->next;
09914                       free(zpcl);
09915                       zpcl = pri->suspended_calls;
09916                       zpc = NULL;
09917                   }
09918                   unparked = 1;
09919                   snprintf(temp, sizeof(temp), "Unparked %s", extenstr);
09920                   pri_resume_acknowledge(pri->pri, e->resume_req.call, chanpos + 1, temp);
09921                        break;
09922                    }
09923                    zpc = zpcl;
09924                    if (zpcl) zpcl = zpcl->next;
09925                }
09926                if (!unparked)
09927                    pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
09928                 } else {
09929                pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
09930                 }
09931                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09932             }
09933             break;
09934          case PRI_EVENT_HOLD_REQ:
09935             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09936                 pri_hold_reject(pri->pri, e->hold_req.call);
09937                 break;
09938             }
09939             /* holded calls are not implemented yet */
09940             pri_hold_reject(pri->pri, e->hold_req.call);
09941             break;
09942          case PRI_EVENT_RETRIEVE_REQ:
09943             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09944                 pri_retrieve_reject(pri->pri, e->retrieve_req.call);
09945                 break;
09946             }
09947             /* Holded calls are currently not supported */
09948             pri_retrieve_reject(pri->pri, e->retrieve_req.call);
09949             chanpos = -1;
09950             break;
09951          case PRI_EVENT_DISPLAY_RECEIVED:
09952             ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text);
09953             chanpos = pri_find_principle(pri, e->display.channel);
09954             if (chanpos < 0) {
09955                 ast_log(LOG_WARNING, "odd channel number %d span %d\n", chanpos, pri->span);
09956                 chanpos = -1;
09957             }
09958             if (chanpos > -1) {
09959                 if (pri->pvts[chanpos]->owner) {
09960          //    ast_sendtext(pri->pvt[chanpos]->owner, e->display.text);
09961                 }
09962             }
09963             break;
09964          case PRI_EVENT_ANSWER:
09965             chanpos = pri_find_principle(pri, e->answer.channel);
09966             if (chanpos < 0) {
09967                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
09968                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09969             } else {
09970                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
09971                if (chanpos < 0) {
09972                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
09973                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
09974                } else {
09975                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09976                   pri->pvts[chanpos]->tei = e->answer.tei;
09977                   /* Now we can do call progress detection */
09978 
09979                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
09980                    * By this time, we need DTMF detection and other features that were previously disabled
09981                    * -- Matt F */
09982                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09983                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09984                      pri->pvts[chanpos]->dsp_features = 0;
09985                   }
09986                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
09987                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
09988                      x = ZT_START;
09989                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
09990                      if (res < 0) {
09991                         if (errno != EINPROGRESS) {
09992                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
09993                         }
09994                      }
09995                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09996                      pri->pvts[chanpos]->dialing = 1;
09997                      /* Send any "w" waited stuff */
09998                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
09999                      if (res < 0) {
10000                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
10001                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
10002                      } else 
10003                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
10004                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
10005                   } else if (pri->pvts[chanpos]->confirmanswer) {
10006                      ast_log(LOG_DEBUG, "Waiting for answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
10007                      enable_dtmf_detect(pri->pvts[chanpos]);
10008                   } else {
10009                      pri->pvts[chanpos]->dialing = 0;
10010                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
10011                      /* Enable echo cancellation if it's not on already */
10012                      zt_enable_ec(pri->pvts[chanpos]);
10013                      zt_train_ec(pri->pvts[chanpos]);
10014                      /* stop ignoring inband dtmf */
10015                      enable_dtmf_detect(pri->pvts[chanpos]);
10016                   }
10017 
10018 #ifdef SUPPORT_USERUSER
10019                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
10020                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10021                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10022                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
10023                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10024                   }
10025 #endif
10026 
10027                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10028                }
10029             }
10030             break;            
10031          case PRI_EVENT_HANGUP:
10032             chanpos = pri_find_principle(pri, e->hangup.channel);
10033             if (chanpos < 0) {
10034                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
10035                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10036             } else {
10037                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10038                if (chanpos > -1) {
10039                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10040                   if (!pri->pvts[chanpos]->alreadyhungup) {
10041                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
10042                      pri->pvts[chanpos]->alreadyhungup = 1;
10043                      if (pri->pvts[chanpos]->realcall) 
10044                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10045                      else if (pri->pvts[chanpos]->owner) {
10046                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
10047                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10048                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10049                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10050                         else {
10051                            switch (e->hangup.cause) {
10052                               case PRI_CAUSE_USER_BUSY:
10053                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10054                                  break;
10055                               case PRI_CAUSE_CALL_REJECTED:
10056                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10057                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10058                               case PRI_CAUSE_SWITCH_CONGESTION:
10059                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10060                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10061                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10062                                  break;
10063                               default:
10064                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10065                            }
10066                         }
10067                      }
10068                      if (option_verbose > 2) 
10069                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
10070                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
10071                   } else {
10072                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10073                      pri->pvts[chanpos]->call = NULL;
10074                      pri->pvts[chanpos]->tei = -1;
10075                   }
10076                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10077                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10078                          if (option_verbose > 2)
10079                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
10080                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10081                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10082                          pri->pvts[chanpos]->resetting = 1;
10083                      }
10084                   }
10085                   if (e->hangup.aoc_units > -1) {
10086                      if (pri->pvts[chanpos]->owner) {
10087                          char tmpstr[256];
10088                          snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10089                          pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10090                      }
10091                      if (option_verbose > 2)
10092                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10093                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10094                   }
10095 
10096 #ifdef SUPPORT_USERUSER
10097                   if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
10098                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10099                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10100                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10101                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10102                   }
10103 #endif
10104 
10105                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10106                } else {
10107                   ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
10108                   ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
10109                         PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10110                }
10111             } 
10112             break;
10113 #ifndef PRI_EVENT_HANGUP_REQ
10114 #error please update libpri
10115 #endif
10116          case PRI_EVENT_HANGUP_REQ:
10117             chanpos = pri_find_principle(pri, e->hangup.channel);
10118             if (chanpos < 0) {
10119                if (pri->nodetype == BRI_NETWORK_PTMP) {
10120                    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
10121                } else {
10122                    ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
10123                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10124                }
10125             } else if ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing)) {
10126                             /* dont hang up if we want to hear inband call progress */
10127                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10128                if (chanpos > -1) {
10129                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10130                   if (pri->pvts[chanpos]->realcall) 
10131                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10132                   else if (pri->pvts[chanpos]->owner) {
10133                      char tmpstr[256];
10134                      snprintf(tmpstr, sizeof(tmpstr), "%d", e->hangup.cause);
10135                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_CAUSE", tmpstr);
10136                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10137                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10138                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10139                      else {
10140                         switch (e->hangup.cause) {
10141                            case PRI_CAUSE_USER_BUSY:
10142                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10143                               break;
10144                            case PRI_CAUSE_CALL_REJECTED:
10145                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10146                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10147                            case PRI_CAUSE_SWITCH_CONGESTION:
10148                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10149                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10150                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10151                               break;
10152                            default:
10153                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10154                         }
10155                      }
10156                      if (option_verbose > 2) 
10157                         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);
10158                      if (e->hangup.aoc_units > -1)
10159                         if (option_verbose > 2)
10160                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10161                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10162                      if (e->hangup.aoc_units > -1) {
10163                          if (pri->pvts[chanpos]->owner) {
10164                         char tmpstr[256];
10165                         snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10166                         pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10167                          }
10168                          if (option_verbose > 2)
10169                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10170                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10171                      }
10172                      if (pri->nodetype == BRI_NETWORK_PTMP) {
10173                         pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10174                         pri->pvts[chanpos]->call = NULL;
10175                         pri->pvts[chanpos]->tei = -1;
10176                      }
10177                   } else {
10178                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10179                      pri->pvts[chanpos]->call = NULL;
10180                      pri->pvts[chanpos]->tei = -1;
10181                   }
10182                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10183                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10184                          if (option_verbose > 2)
10185                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
10186                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10187                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10188                          pri->pvts[chanpos]->resetting = 1;
10189                      }
10190                   }
10191 
10192 #ifdef SUPPORT_USERUSER
10193                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10194                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10195                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10196                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10197                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10198                   }
10199 #endif
10200 
10201                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10202                } else {
10203                   if (pri->nodetype != BRI_NETWORK_PTMP) {
10204                       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);
10205                   } else {
10206                      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);
10207                   }
10208                }
10209             } 
10210             if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) {
10211                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10212                if (e->hangup.aoc_units > -1) {
10213                    char tmpstr[256];
10214                    snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10215                    pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10216                    if (option_verbose > 2)
10217                   ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10218                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10219                }
10220                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10221                ast_channel_setwhentohangup(pri->pvts[chanpos]->owner, 5);
10222                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10223             }
10224             break;
10225          case PRI_EVENT_HANGUP_ACK:
10226             chanpos = pri_find_principle(pri, e->hangup.channel);
10227             if (chanpos < 0) {
10228                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
10229                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10230             } else {
10231                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10232                if (chanpos > -1) {
10233                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10234                   pri->pvts[chanpos]->call = NULL;
10235                   pri->pvts[chanpos]->tei = -1;
10236                   pri->pvts[chanpos]->resetting = 0;
10237                   if (pri->pvts[chanpos]->owner) {
10238                      if (option_verbose > 2) 
10239                         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);
10240                   }
10241 
10242 #ifdef SUPPORT_USERUSER
10243                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10244                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10245                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10246                      pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
10247                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10248                   }
10249 #endif
10250 
10251                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10252                }
10253             }
10254             break;
10255          case PRI_EVENT_CONFIG_ERR:
10256             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
10257             break;
10258          case PRI_EVENT_RESTART_ACK:
10259             chanpos = pri_find_principle(pri, e->restartack.channel);
10260             if (chanpos < 0) {
10261                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
10262                   channel number, so we have to figure it out...  This must be why
10263                   everybody resets exactly a channel at a time. */
10264                for (x = 0; x < pri->numchans; x++) {
10265                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
10266                      chanpos = x;
10267                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10268                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
10269                            pri->pvts[chanpos]->prioffset, pri->span);
10270                      if (pri->pvts[chanpos]->realcall) 
10271                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10272                      else if (pri->pvts[chanpos]->owner) {
10273                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
10274                            pri->pvts[chanpos]->prioffset, pri->span);
10275                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10276                      }
10277                      pri->pvts[chanpos]->resetting = 0;
10278                      if (option_verbose > 2)
10279                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10280                            pri->pvts[chanpos]->prioffset, pri->span);
10281                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10282                      if (pri->resetting)
10283                         pri_check_restart(pri);
10284                      break;
10285                   }
10286                }
10287                if (chanpos < 0) {
10288                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
10289                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10290                }
10291             } else {
10292                if (pri->pvts[chanpos]) {
10293                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10294                   if (pri->pvts[chanpos]->realcall) 
10295                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10296                   else if (pri->pvts[chanpos]->owner) {
10297                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
10298                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10299                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10300                   }
10301                   pri->pvts[chanpos]->resetting = 0;
10302                   if (option_verbose > 2)
10303                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10304                            pri->pvts[chanpos]->prioffset, pri->span);
10305                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10306                   if (pri->resetting)
10307                      pri_check_restart(pri);
10308                }
10309             }
10310             break;
10311          case PRI_EVENT_SETUP_ACK:
10312             chanpos = pri_find_principle(pri, e->setup_ack.channel);
10313             if (chanpos < 0) {
10314                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
10315                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
10316             } else {
10317                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
10318                if (chanpos > -1) {
10319                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10320                   pri->pvts[chanpos]->setup_ack = 1;
10321                   /* Send any queued digits */
10322                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
10323                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
10324                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
10325                         pri->pvts[chanpos]->dialdest[x]);
10326                   }
10327                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10328                } else
10329                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
10330             }
10331             break;
10332          case PRI_EVENT_NOTIFY:
10333             chanpos = pri_find_principle(pri, e->notify.channel);
10334             if (chanpos < 0) {
10335                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
10336                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
10337             } else {
10338                struct ast_frame f = { AST_FRAME_CONTROL, };
10339                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10340                switch (e->notify.info) {
10341                case PRI_NOTIFY_REMOTE_HOLD:
10342                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10343                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on NETWORK channel. Starting MoH\n");
10344                       ast_moh_start(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, pri->pvts[chanpos]->mohinterpret);
10345                   } else {
10346                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on CPE channel. Not Starting MoH\n");
10347                   }
10348                   f.subclass = AST_CONTROL_HOLD;
10349                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10350                   break;
10351                case PRI_NOTIFY_REMOTE_RETRIEVAL:
10352                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10353                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on NETWORK channel. Stopping MoH\n");
10354                       ast_moh_stop(ast_bridged_channel(pri->pvts[chanpos]->owner));
10355                   } else {
10356                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on CPE channel.\n");
10357                   }
10358                   f.subclass = AST_CONTROL_UNHOLD;
10359                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10360                   break;
10361                }
10362                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10363             }
10364             break;
10365          case PRI_EVENT_FACILITY:
10366                 if (e->facility.operation == 0x0D) {
10367                   struct ast_channel *owner = pri->pvts[chanpos]->owner;
10368 
10369                ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
10370                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10371                    /* transfer */
10372                    if (owner) {
10373                   ast_string_field_build(owner, call_forward, 
10374                         "Local/%s@%s",  e->facility.forwardnum,
10375                         owner->context);
10376                    }
10377                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10378                 } else {
10379                ast_log(LOG_WARNING, "Unknown facility operation %#x requested.\n", e->facility.operation);
10380                 }
10381             break;
10382          default:
10383             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
10384          }
10385       }  
10386       ast_mutex_unlock(&pri->lock);
10387    }
10388    /* Never reached */
10389    return NULL;
10390 }
10391 
10392 static int start_pri(struct zt_pri *pri)
10393 {
10394    int res, x;
10395    ZT_PARAMS p;
10396    ZT_BUFFERINFO bi;
10397    struct zt_spaninfo si;
10398    int i;
10399    
10400    for (i = 0; i < NUM_DCHANS; i++) {
10401       if (!pri->dchannels[i])
10402          break;
10403       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
10404       x = pri->dchannels[i];
10405       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
10406          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
10407          return -1;
10408       }
10409       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
10410       if (res) {
10411          zt_close(pri->fds[i]);
10412          pri->fds[i] = -1;
10413          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
10414          return -1;
10415       }
10416       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
10417          zt_close(pri->fds[i]);
10418          pri->fds[i] = -1;
10419          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
10420          return -1;
10421       }
10422       memset(&si, 0, sizeof(si));
10423       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
10424       if (res) {
10425          zt_close(pri->fds[i]);
10426          pri->fds[i] = -1;
10427          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
10428       }
10429       if (!si.alarms)
10430          pri->dchanavail[i] |= DCHAN_NOTINALARM;
10431       else
10432          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
10433       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
10434       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
10435       bi.numbufs = 32;
10436       bi.bufsize = 1024;
10437       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
10438          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
10439          zt_close(pri->fds[i]);
10440          pri->fds[i] = -1;
10441          return -1;
10442       }
10443       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype, pri->span);
10444       /* Force overlap dial if we're doing GR-303! */
10445       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
10446          pri->overlapdial = 1;
10447       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
10448       /* Enslave to master if appropriate */
10449       if (i)
10450          pri_enslave(pri->dchans[0], pri->dchans[i]);
10451       if (!pri->dchans[i]) {
10452          zt_close(pri->fds[i]);
10453          pri->fds[i] = -1;
10454          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
10455          return -1;
10456       }
10457       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
10458       pri_set_nsf(pri->dchans[i], pri->nsf);
10459 #ifdef PRI_GETSET_TIMERS
10460       for (x = 0; x < PRI_MAX_TIMERS; x++) {
10461          if (pritimers[x] != 0)
10462             pri_set_timer(pri->dchans[i], x, pritimers[x]);
10463       }
10464 #endif
10465    }
10466    /* Assume primary is the one we use */
10467    pri->pri = pri->dchans[0];
10468    pri->resetpos = -1;
10469    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
10470       for (i = 0; i < NUM_DCHANS; i++) {
10471          if (!pri->dchannels[i])
10472             break;
10473          zt_close(pri->fds[i]);
10474          pri->fds[i] = -1;
10475       }
10476       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
10477       return -1;
10478    }
10479    return 0;
10480 }
10481 
10482 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
10483 {
10484    int which, span;
10485    char *ret = NULL;
10486 
10487    if (pos != rpos)
10488       return ret;
10489 
10490    for (which = span = 0; span < NUM_SPANS; span++) {
10491       if (pris[span].pri && ++which > state) {
10492          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
10493          break;
10494       }
10495    }
10496    return ret;
10497 }
10498 
10499 static char *complete_span_4(const char *line, const char *word, int pos, int state)
10500 {
10501    return complete_span_helper(line,word,pos,state,3);
10502 }
10503 
10504 static char *complete_span_5(const char *line, const char *word, int pos, int state)
10505 {
10506    return complete_span_helper(line,word,pos,state,4);
10507 }
10508 
10509 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
10510 {
10511    int myfd, x, d;
10512    int span;
10513 
10514    if (argc < 6)
10515       return RESULT_SHOWUSAGE;
10516 
10517    if (!strncasecmp(argv[1], "set", 3)) {
10518       if (argc < 7)
10519          return RESULT_SHOWUSAGE;
10520 
10521       if (!argv[4] || ast_strlen_zero(argv[4]))
10522          return RESULT_SHOWUSAGE;
10523 
10524       if (!argv[5])
10525          return RESULT_SHOWUSAGE;
10526 
10527       if (!argv[6] || ast_strlen_zero(argv[6]))
10528          return RESULT_SHOWUSAGE;
10529 
10530       span = atoi(argv[6]);
10531       if ((span < 1) && (span > NUM_SPANS)) {
10532          return RESULT_SUCCESS;
10533       }
10534 
10535 
10536       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
10537       if (myfd < 0) {
10538          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
10539          return RESULT_SUCCESS;
10540       }
10541       for (x=0; x < NUM_SPANS; x++) {
10542              ast_mutex_lock(&pris[x].lock);
10543 
10544           if (pris[x].span == span) {
10545          if (pris[x].debugfd >= 0)
10546              close(pris[x].debugfd);
10547          pris[x].debugfd = myfd;
10548          for (d=0; d < NUM_DCHANS; d++) {
10549              if (pris[x].dchans[d])
10550             pri_set_debug_fd(pris[x].dchans[d], myfd);
10551          }
10552           }
10553              ast_mutex_unlock(&pris[x].lock);
10554       }
10555 
10556       ast_cli(fd, "PRI debug output for span %d will be sent to '%s'\n", span, argv[4]);
10557    } else {
10558       if (!argv[5] || ast_strlen_zero(argv[5]))
10559          return RESULT_SHOWUSAGE;
10560       /* Assume it is unset */
10561       span = atoi(argv[5]);
10562       if ((span < 1) && (span > NUM_SPANS)) {
10563          return RESULT_SUCCESS;
10564       }
10565 
10566       for (x=0; x < NUM_SPANS; x++) {
10567              ast_mutex_lock(&pris[x].lock);
10568 
10569           if (pris[x].span == span) {
10570          if (pris[x].debugfd >= 0)
10571              close(pris[x].debugfd);
10572          pris[x].debugfd = -1;
10573          for (d=0; d < NUM_DCHANS; d++) {
10574              if (pris[x].dchans[d])
10575             pri_set_debug_fd(pris[x].dchans[d], -1);
10576          }
10577           }
10578              ast_mutex_unlock(&pris[x].lock);
10579       }
10580 
10581       ast_cli(fd, "PRI debug output to file for span %d disabled\n", span);
10582    }
10583 
10584    return RESULT_SUCCESS;
10585 }
10586 
10587 #ifdef HAVE_PRI_VERSION
10588 static int handle_pri_version(int fd, int agc, char *argv[]) {
10589    ast_cli(fd, "libpri version: %s\n", pri_get_version());
10590    return RESULT_SUCCESS;
10591 }
10592 #endif
10593 
10594 static int handle_pri_debug(int fd, int argc, char *argv[])
10595 {
10596    int span;
10597    int x;
10598    if (argc < 4) {
10599       return RESULT_SHOWUSAGE;
10600    }
10601    span = atoi(argv[3]);
10602    if ((span < 1) || (span > NUM_SPANS)) {
10603       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
10604       return RESULT_SUCCESS;
10605    }
10606    if (!pris[span-1].pri) {
10607       ast_cli(fd, "No PRI running on span %d\n", span);
10608       return RESULT_SUCCESS;
10609    }
10610    for (x = 0; x < NUM_DCHANS; x++) {
10611       if (pris[span-1].dchans[x])
10612          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
10613                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
10614                                                PRI_DEBUG_Q921_STATE);
10615    }
10616    ast_cli(fd, "Enabled debugging on span %d\n", span);
10617    return RESULT_SUCCESS;
10618 }
10619 
10620 
10621 
10622 
10623 static int handle_pri_no_debug(int fd, int argc, char *argv[])
10624 {
10625    int span;
10626    int x;
10627    if (argc < 5)
10628       return RESULT_SHOWUSAGE;
10629    span = atoi(argv[4]);
10630    if ((span < 1) || (span > NUM_SPANS)) {
10631       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
10632       return RESULT_SUCCESS;
10633    }
10634    if (!pris[span-1].pri) {
10635       ast_cli(fd, "No PRI running on span %d\n", span);
10636       return RESULT_SUCCESS;
10637    }
10638    for (x = 0; x < NUM_DCHANS; x++) {
10639       if (pris[span-1].dchans[x])
10640          pri_set_debug(pris[span-1].dchans[x], 0);
10641    }
10642    ast_cli(fd, "Disabled debugging on span %d\n", span);
10643    return RESULT_SUCCESS;
10644 }
10645 
10646 static int handle_pri_really_debug(int fd, int argc, char *argv[])
10647 {
10648    int span;
10649    int x;
10650    if (argc < 5)
10651       return RESULT_SHOWUSAGE;
10652    span = atoi(argv[4]);
10653    if ((span < 1) || (span > NUM_SPANS)) {
10654       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
10655       return RESULT_SUCCESS;
10656    }
10657    if (!pris[span-1].pri) {
10658       ast_cli(fd, "No PRI running on span %d\n", span);
10659       return RESULT_SUCCESS;
10660    }
10661    for (x = 0; x < NUM_DCHANS; x++) {
10662       if (pris[span-1].dchans[x])
10663          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
10664                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
10665                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
10666    }
10667    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
10668    return RESULT_SUCCESS;
10669 }
10670 
10671 static void build_status(char *s, size_t len, int status, int active)
10672 {
10673    if (!s || len < 1) {
10674       return;
10675    }
10676    s[0] = '\0';
10677    if (status & DCHAN_PROVISIONED)
10678       strncat(s, "Provisioned, ", len - strlen(s) - 1);
10679    if (!(status & DCHAN_NOTINALARM))
10680       strncat(s, "In Alarm, ", len - strlen(s) - 1);
10681    if (status & DCHAN_UP)
10682       strncat(s, "Up", len - strlen(s) - 1);
10683    else
10684       strncat(s, "Down", len - strlen(s) - 1);
10685    if (active)
10686       strncat(s, ", Active", len - strlen(s) - 1);
10687    else
10688       strncat(s, ", Standby", len - strlen(s) - 1);
10689    s[len - 1] = '\0';
10690 }
10691 
10692 static int handle_pri_show_spans(int fd, int argc, char *argv[])
10693 {
10694    int span;
10695    int x;
10696    char status[256];
10697    if (argc != 3)
10698       return RESULT_SHOWUSAGE;
10699 
10700    for (span = 0; span < NUM_SPANS; span++) {
10701       if (pris[span].pri) {
10702          for (x = 0; x < NUM_DCHANS; x++) {
10703             if (pris[span].dchannels[x]) {
10704                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
10705                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
10706             }
10707          }
10708       }
10709    }
10710    return RESULT_SUCCESS;
10711 }
10712 
10713 static int handle_pri_show_span(int fd, int argc, char *argv[])
10714 {
10715    int span;
10716    int x;
10717    char status[256];
10718    if (argc < 4)
10719       return RESULT_SHOWUSAGE;
10720    span = atoi(argv[3]);
10721    if ((span < 1) || (span > NUM_SPANS)) {
10722       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
10723       return RESULT_SUCCESS;
10724    }
10725    if (!pris[span-1].pri) {
10726       ast_cli(fd, "No PRI running on span %d\n", span);
10727       return RESULT_SUCCESS;
10728    }
10729    for (x = 0; x < NUM_DCHANS; x++) {
10730       if (pris[span-1].dchannels[x]) {
10731 #ifdef PRI_DUMP_INFO_STR
10732          char *info_str = NULL;
10733 #endif
10734          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
10735          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
10736          ast_cli(fd, "Status: %s\n", status);
10737 #ifdef PRI_DUMP_INFO_STR
10738          info_str = pri_dump_info_str(pris[span-1].pri);
10739          if (info_str) {
10740             ast_cli(fd, "%s", info_str);
10741             free(info_str);
10742          }
10743 #else
10744          pri_dump_info(pris[span-1].pri);
10745 #endif
10746          ast_cli(fd, "\n");
10747       }
10748    }
10749    return RESULT_SUCCESS;
10750 }
10751 
10752 static int handle_pri_show_debug(int fd, int argc, char *argv[])
10753 {
10754    int x;
10755    int span;
10756    int count=0;
10757    int debug=0;
10758 
10759    for (span = 0; span < NUM_SPANS; span++) {
10760            if (pris[span].pri) {
10761          for (x = 0; x < NUM_DCHANS; x++) {
10762             debug = 0;
10763                if (pris[span].dchans[x]) {
10764                   debug = pri_get_debug(pris[span].dchans[x]);
10765                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" );
10766                count++;
10767             }
10768          }
10769       }
10770 
10771    }
10772        
10773    if (!count) 
10774       ast_cli(fd, "No debug set or no PRI running\n");
10775    return RESULT_SUCCESS;
10776 }
10777 
10778 static const char pri_debug_help[] = 
10779    "Usage: pri debug span <span>\n"
10780    "       Enables debugging on a given PRI span\n";
10781    
10782 static const char pri_no_debug_help[] = 
10783    "Usage: pri no debug span <span>\n"
10784    "       Disables debugging on a given PRI span\n";
10785 
10786 static const char pri_really_debug_help[] = 
10787    "Usage: pri intensive debug span <span>\n"
10788    "       Enables debugging down to the Q.921 level\n";
10789 
10790 static const char pri_show_span_help[] = 
10791    "Usage: pri show span <span>\n"
10792    "       Displays PRI Information on a given PRI span\n";
10793 
10794 static const char pri_show_spans_help[] = 
10795    "Usage: pri show spans\n"
10796    "       Displays PRI Information\n";
10797 
10798 static char bri_debug_help[] =
10799    "Usage: bri debug span <span>\n"
10800    "       Enables debugging on a given BRI span\n";
10801 
10802 static char bri_no_debug_help[] =
10803    "Usage: bri no debug span <span>\n"
10804    "       Disables debugging on a given BRI span\n";
10805 
10806 static char bri_really_debug_help[] =
10807    "Usage: bri intensive debug span <span>\n"
10808    "       Enables debugging down to the Q.921 level\n";
10809 
10810 static struct ast_cli_entry zap_pri_cli[] = {
10811    { { "pri", "debug", "span", NULL },
10812    handle_pri_debug, "Enables PRI debugging on a span",
10813    pri_debug_help, complete_span_4 },
10814 
10815    { { "pri", "no", "debug", "span", NULL },
10816    handle_pri_no_debug, "Disables PRI debugging on a span",
10817    pri_no_debug_help, complete_span_5 },
10818 
10819    { { "pri", "intense", "debug", "span", NULL },
10820    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
10821    pri_really_debug_help, complete_span_5 },
10822 
10823    { { "pri", "show", "spans", NULL },
10824    handle_pri_show_spans, "Displays PRI Information",
10825    pri_show_spans_help },
10826 
10827    { { "pri", "show", "span", NULL },
10828    handle_pri_show_span, "Displays PRI Information",
10829    pri_show_span_help, complete_span_4 },
10830 
10831    { { "pri", "show", "debug", NULL },
10832    handle_pri_show_debug, "Displays current PRI debug settings" },
10833 
10834    { { "bri", "debug", "span", NULL }, handle_pri_debug,
10835      "Enables BRI debugging on a span", bri_debug_help, complete_span_4 },
10836 
10837    { { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug,
10838      "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 },
10839 
10840    { { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug,
10841      "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 },
10842 
10843    { { "pri", "set", "debug", "file", NULL },
10844    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
10845 
10846    { { "pri", "unset", "debug", "file", NULL },
10847    handle_pri_set_debug_file, "Ends PRI debug output to file" },
10848 
10849 #ifdef HAVE_PRI_VERSION
10850    { { "pri", "show", "version", NULL },
10851    handle_pri_version, "Displays version of libpri" },
10852 #endif
10853 };
10854 
10855 static char *zapCD_tdesc = "Call Deflection";
10856 static char *zapCD_app = "zapCD";
10857 static char *zapCD_synopsis = "Call Deflection";
10858 
10859 static int app_zapCD(struct ast_channel *chan, void *data)
10860 {
10861  struct zt_pvt *p = chan->tech_pvt;
10862 
10863  if((!p->pri) || (!p->pri->pri)) {
10864    return -1;
10865  }
10866 
10867  if(!data) {
10868      ast_log(LOG_WARNING, "zapCD wants a number to deflect to\n");
10869    return -1;
10870  }
10871  return pri_deflect(p->pri->pri, p->call, data);
10872 }
10873 
10874 static char *zapInband_tdesc = "Inband Call Progress (pre-answer)";
10875 static char *zapInband_app = "zapInband";
10876 static char *zapInband_synopsis = "Inband Call Progress";
10877 
10878 static int app_zapInband(struct ast_channel *chan, void *data)
10879 {
10880  struct zt_pvt *p = chan->tech_pvt;
10881 
10882  return pri_acknowledge(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1);
10883 }
10884 
10885 #endif /* HAVE_PRI */
10886 
10887 #ifdef HAVE_GSMAT
10888 static int handle_zap_reset_span(int fd, int argc, char *argv[])
10889 {
10890    int span;
10891    int sleep = 5000;
10892    if (argc < 4)
10893       return RESULT_SHOWUSAGE;
10894    span = atoi(argv[3]);
10895    if ((span < 1) || (span > NUM_SPANS)) {
10896       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
10897       return RESULT_SUCCESS;
10898    }
10899    if (zt_reset_span(span, sleep)) {
10900        return RESULT_FAILURE;
10901    }
10902    return RESULT_SUCCESS;
10903 }
10904 
10905 static int handle_gsm_debug_helper(int fd, int channel, int debug)
10906 {
10907 /* gsm debug channel <channel> */
10908    struct zt_pvt *pvt = NULL;
10909    if (channel < 1) {
10910       ast_cli(fd, "Invalid channel %d.  Should be a number.\n", channel);
10911       return RESULT_SUCCESS;
10912    }
10913    pvt = iflist;
10914    while (pvt) {
10915        if (pvt->channel == channel) {
10916       ast_mutex_lock(&pvt->lock);
10917       gsm_set_debug(pvt->gsm.modul, debug);
10918       ast_mutex_unlock(&pvt->lock);
10919       ast_cli(fd, "%s debugging on channel %d\n", debug ? "Enabled":"Disabled", channel);
10920       return RESULT_SUCCESS;
10921        }
10922        pvt = pvt->next;
10923    }
10924 
10925    ast_cli(fd, "No GSM running on channel %d\n", channel);
10926    return RESULT_SUCCESS;
10927 }
10928 
10929 
10930 
10931 static int handle_gsm_debug(int fd, int argc, char *argv[])
10932 {
10933 /* gsm debug channel <channel> */
10934  int channel;
10935  if (argc < 4) {
10936    return RESULT_SHOWUSAGE;
10937  }
10938  channel = atoi(argv[3]);
10939  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_AT);
10940 }
10941 
10942 static int handle_gsm_no_debug(int fd, int argc, char *argv[])
10943 {
10944 /* gsm no debug channel <channel> */
10945  int channel;
10946  if (argc < 5) {
10947    return RESULT_SHOWUSAGE;
10948  }
10949  channel = atoi(argv[4]);
10950  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_NONE);
10951 }
10952 
10953 static char zap_reset_help[] =
10954    "Usage: zap reset span <span>\n"
10955    "       Reset/Restart a zaptel span\n";
10956 
10957 static char gsm_debug_help[] =
10958    "Usage: gsm debug channel <channel>\n"
10959    "       Enables debugging on a given GSM channel\n";
10960 
10961 static char gsm_no_debug_help[] =
10962    "Usage: gsm no debug channel <channel>\n"
10963    "       Disables debugging on a given GSM channel\n";
10964 
10965 static struct ast_cli_entry zap_gsm_cli[] = {
10966    { { "zap", "reset", "span", NULL }, handle_zap_reset_span,
10967      "Restart a zaptel span", zap_reset_help, complete_span_4 },
10968    { { "gsm", "debug", "channel", NULL }, handle_gsm_debug,
10969      "Enables GSM debugging on a channel", gsm_debug_help },
10970    { { "gsm", "no", "debug", "channel", NULL }, handle_gsm_no_debug,
10971      "Disables GSM debugging on a channel", gsm_no_debug_help},
10972 };
10973 
10974 
10975 
10976 static char gsm_send_pdu_help[] =
10977    "Usage: gsm send pdu <channel> <pdu>\n"
10978    "       Sends a PDU on a GSM channel\n";
10979 
10980 
10981 
10982 static int handle_gsm_send_pdu(int fd, int argc, char *argv[])
10983 {
10984 /* gsm send sms <channel> <destination> <message> */
10985    int channel;
10986    struct zt_pvt *pvt = NULL;
10987    if (argc < 5) {
10988       return RESULT_SHOWUSAGE;
10989    }
10990    channel = atoi(argv[3]);
10991    if (channel < 1) {
10992       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
10993       return RESULT_SUCCESS;
10994    }
10995    pvt = iflist;
10996    while (pvt) {
10997        if (pvt->channel == channel) {
10998       if (pvt->owner) {
10999           ast_cli(fd, "Channel in use.\n");
11000           return RESULT_FAILURE;
11001       } else {
11002           ast_mutex_lock(&pvt->lock);
11003           gsm_sms_send_pdu(pvt->gsm.modul, argv[4]);
11004           ast_mutex_unlock(&pvt->lock);
11005           return RESULT_SUCCESS;
11006       }
11007        }
11008        pvt = pvt->next;
11009    }
11010 
11011    return RESULT_SUCCESS;
11012 }
11013 
11014 static struct ast_cli_entry gsm_send_pdu = {
11015    { "gsm", "send", "pdu", NULL }, handle_gsm_send_pdu, "Sends a SM on a GSM channel", gsm_send_pdu_help, complete_span_4 };
11016 
11017 
11018 static char gsm_send_sms_help[] =
11019    "Usage: gsm send sms <channel> <destination> <message>\n"
11020    "       Sends a SM on a GSM channel\n";
11021 
11022 
11023 static int handle_gsm_send_sms(int fd, int argc, char *argv[])
11024 {
11025 /* gsm send sms <channel> <destination> <message> */
11026    int channel;
11027    struct zt_pvt *pvt = NULL;
11028    if (argc < 6) {
11029       return RESULT_SHOWUSAGE;
11030    }
11031    channel = atoi(argv[3]);
11032    if (channel < 1) {
11033       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11034       return RESULT_SUCCESS;
11035    }
11036    pvt = iflist;
11037    while (pvt) {
11038        if (pvt->channel == channel) {
11039       if (pvt->owner) {
11040           ast_cli(fd, "Channel in use.\n");
11041           return RESULT_FAILURE;
11042       } else {
11043           ast_mutex_lock(&pvt->lock);
11044           gsm_sms_send_text(pvt->gsm.modul, argv[4], argv[5]);
11045           ast_mutex_unlock(&pvt->lock);
11046           return RESULT_SUCCESS;
11047       }
11048        }
11049        pvt = pvt->next;
11050    }
11051 
11052    return RESULT_SUCCESS;
11053 }
11054 
11055 static int zt_gsm_sendtext(struct ast_channel *chan, const char * dest, const char *text, int ispdu) {
11056      struct zt_pvt *pvt = NULL;
11057      char *c = NULL;
11058      pvt = chan->tech_pvt;
11059 
11060      if (!pvt) return -1;
11061 
11062      /* parse dialstring */
11063      c = strrchr(dest, '/');
11064      if (c)
11065    c++;
11066      else
11067    c = (char *)dest;
11068 
11069      ast_mutex_lock(&pvt->lock);
11070    if (ispdu) {
11071           gsm_sms_send_pdu(pvt->gsm.modul, (char *)text);
11072    } else {
11073           gsm_sms_send_text(pvt->gsm.modul, c, (char *)text);
11074    }
11075      ast_mutex_unlock(&pvt->lock);
11076      gsm_wait(pvt->gsm.modul);
11077      return 0;
11078 }
11079 
11080 static struct ast_cli_entry gsm_send_sms = {
11081    { "gsm", "send", "sms", NULL }, handle_gsm_send_sms, "Sends a SM on a GSM channel", gsm_send_sms_help, complete_span_4 };
11082 
11083 static char gsm_show_status_help[] =
11084    "Usage: gsm show status <channel>>\n"
11085    "       Displays status information about the GSM channel.\n";
11086 
11087 
11088 static int handle_gsm_show_status(int fd, int argc, char *argv[])
11089 {
11090    int channel;
11091    struct zt_pvt *pvt = NULL;
11092    if (argc < 4) {
11093       return RESULT_SHOWUSAGE;
11094    }
11095    channel = atoi(argv[3]);
11096    if (channel < 1) {
11097       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11098       return RESULT_SUCCESS;
11099    }
11100    pvt = iflist;
11101    while (pvt) {
11102        if (pvt->channel == channel) {
11103       if (pvt->owner) {
11104           ast_cli(fd, "Channel in use.\n");
11105           return RESULT_FAILURE;
11106       } else {
11107           ast_mutex_lock(&pvt->lock);
11108           gsm_request_status(pvt->gsm.modul);
11109           ast_mutex_unlock(&pvt->lock);
11110           return RESULT_SUCCESS;
11111       }
11112        }
11113        pvt = pvt->next;
11114    }
11115 
11116    return RESULT_SUCCESS;
11117 }
11118 
11119 static struct ast_cli_entry gsm_show_status = {
11120    { "gsm", "show", "status", NULL }, handle_gsm_show_status, "Displays status information about the GSM channel.", gsm_show_status_help, complete_span_4 };
11121 
11122 #endif /* HAVE_GSMAT */
11123 
11124 static int app_zapEC(struct ast_channel *chan, void *data)
11125 {
11126  int res=-1;
11127  struct zt_pvt *p = NULL;
11128 
11129  if (!data) {
11130    ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n");
11131  }
11132  if (chan && !strcasecmp("ZAP",chan->tech->type)) {
11133    p = chan->tech_pvt;
11134    if (!p) return res;
11135    if (!strcasecmp("on",(char *)data)) {
11136        zt_enable_ec(p);
11137        res = 0;
11138        if (option_verbose > 3) {
11139       ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name);
11140        }
11141    } else if (!strcasecmp("off",(char *)data)) {
11142        zt_disable_ec(p);
11143        res = 0;
11144        if (option_verbose > 3) {
11145       ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name);
11146        }
11147    } else {
11148        ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data);
11149    }
11150  } else {
11151   ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n");
11152   res = 0;
11153  }
11154 
11155  return res;
11156 }
11157 
11158 static char *zapEC_tdesc = "Enable/disable Echo cancelation";
11159 static char *zapEC_app = "zapEC";
11160 static char *zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel";
11161 
11162 static int zap_destroy_channel(int fd, int argc, char **argv)
11163 {
11164    int channel;
11165    
11166    if (argc != 4)
11167       return RESULT_SHOWUSAGE;
11168    
11169    channel = atoi(argv[3]);
11170 
11171    return zap_destroy_channel_bynum(channel);
11172 }
11173 
11174 static int setup_zap(int reload);
11175 static int zap_restart(void)
11176 {
11177    if (option_verbose > 0)
11178       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
11179    while (iflist) {
11180       if (option_debug)
11181          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
11182       /* Also updates iflist: */
11183       destroy_channel(NULL, iflist, 1);
11184    }
11185    if (option_debug)
11186       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
11187    if (setup_zap(0) != 0) {
11188       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
11189       return 1;
11190    }
11191    return 0;
11192 }
11193 
11194 static int zap_restart_cmd(int fd, int argc, char **argv)
11195 {
11196    if (argc != 2) {
11197       return RESULT_SHOWUSAGE;
11198    }
11199 
11200    if (zap_restart() != 0)
11201       return RESULT_FAILURE;
11202    return RESULT_SUCCESS;
11203 }
11204 
11205 static int action_zaprestart(struct mansession *s, const struct message *m)
11206 {
11207    if (zap_restart() != 0) {
11208       astman_send_error(s, m, "Failed rereading zaptel configuration");
11209       return 1;
11210    }
11211    astman_send_ack(s, m, "ZapRestart: Success");
11212    return 0;
11213 }
11214 
11215 static int zap_show_channels(int fd, int argc, char **argv)
11216 {
11217 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11218 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11219    struct zt_pvt *tmp = NULL;
11220    char tmps[20] = "";
11221    ast_mutex_t *lock;
11222    struct zt_pvt *start;
11223 #ifdef HAVE_PRI
11224    int trunkgroup;
11225    struct zt_pri *pri = NULL;
11226    int x;
11227 #endif
11228 
11229    lock = &iflock;
11230    start = iflist;
11231 
11232 #ifdef HAVE_PRI
11233    if (argc == 4) {
11234       if ((trunkgroup = atoi(argv[3])) < 1)
11235          return RESULT_SHOWUSAGE;
11236       for (x = 0; x < NUM_SPANS; x++) {
11237          if (pris[x].trunkgroup == trunkgroup) {
11238             pri = pris + x;
11239             break;
11240          }
11241       }
11242       if (pri) {
11243          start = pri->crvs;
11244          lock = &pri->lock;
11245       } else {
11246          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11247          return RESULT_FAILURE;
11248       }
11249    } else
11250 #endif
11251    if (argc != 3)
11252       return RESULT_SHOWUSAGE;
11253 
11254    ast_mutex_lock(lock);
11255 #ifdef HAVE_PRI
11256    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
11257 #else
11258    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
11259 #endif   
11260    
11261    tmp = start;
11262    while (tmp) {
11263       if (tmp->channel > 0) {
11264          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
11265       } else
11266          ast_copy_string(tmps, "pseudo", sizeof(tmps));
11267       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
11268       tmp = tmp->next;
11269    }
11270    ast_mutex_unlock(lock);
11271    return RESULT_SUCCESS;
11272 #undef FORMAT
11273 #undef FORMAT2
11274 }
11275 
11276 static int zap_show_channel(int fd, int argc, char **argv)
11277 {
11278    int channel;
11279    struct zt_pvt *tmp = NULL;
11280    ZT_CONFINFO ci;
11281    ZT_PARAMS ps;
11282    int x;
11283    ast_mutex_t *lock;
11284    struct zt_pvt *start;
11285 #ifdef HAVE_PRI
11286    char *c;
11287    int trunkgroup;
11288    struct zt_pri *pri=NULL;
11289 #endif
11290 
11291    lock = &iflock;
11292    start = iflist;
11293 
11294    if (argc != 4)
11295       return RESULT_SHOWUSAGE;
11296 #ifdef HAVE_PRI
11297    if ((c = strchr(argv[3], ':'))) {
11298       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
11299          return RESULT_SHOWUSAGE;
11300       if ((trunkgroup < 1) || (channel < 1))
11301          return RESULT_SHOWUSAGE;
11302       for (x = 0; x < NUM_SPANS; x++) {
11303          if (pris[x].trunkgroup == trunkgroup) {
11304             pri = pris + x;
11305             break;
11306          }
11307       }
11308       if (pri) {
11309          start = pri->crvs;
11310          lock = &pri->lock;
11311       } else {
11312          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11313          return RESULT_FAILURE;
11314       }
11315    } else
11316 #endif
11317       channel = atoi(argv[3]);
11318 
11319    ast_mutex_lock(lock);
11320    tmp = start;
11321    while (tmp) {
11322       if (tmp->channel == channel) {
11323 #ifdef HAVE_PRI
11324          if (pri) 
11325             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
11326          else
11327 #endif         
11328          ast_cli(fd, "Channel: %d\n", tmp->channel);
11329          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
11330          ast_cli(fd, "Span: %d\n", tmp->span);
11331          ast_cli(fd, "Extension: %s\n", tmp->exten);
11332          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
11333          ast_cli(fd, "Context: %s\n", tmp->context);
11334          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
11335          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
11336          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
11337          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
11338          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
11339          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
11340          ast_cli(fd, "Radio: %d\n", tmp->radio);
11341          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
11342          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)" : "");
11343          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)" : "");
11344          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)" : "");
11345          ast_cli(fd, "Confno: %d\n", tmp->confno);
11346          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
11347          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
11348          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
11349          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
11350          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
11351          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
11352          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
11353          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
11354          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
11355          if (tmp->master)
11356             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
11357          for (x = 0; x < MAX_SLAVES; x++) {
11358             if (tmp->slaves[x])
11359                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
11360          }
11361 #ifdef HAVE_PRI
11362          if (tmp->pri) {
11363             ast_cli(fd, "PRI Flags: ");
11364             if (tmp->resetting)
11365                ast_cli(fd, "Resetting ");
11366             if (tmp->call)
11367                ast_cli(fd, "Call ");
11368             if (tmp->bearer)
11369                ast_cli(fd, "Bearer ");
11370             ast_cli(fd, "\n");
11371             if (tmp->logicalspan) 
11372                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
11373             else
11374                ast_cli(fd, "PRI Logical Span: Implicit\n");
11375          }
11376             
11377 #endif
11378          memset(&ci, 0, sizeof(ci));
11379          ps.channo = tmp->channel;
11380          if (tmp->subs[SUB_REAL].zfd > -1) {
11381             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
11382                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
11383             }
11384 #ifdef ZT_GETCONFMUTE
11385             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
11386                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
11387             }
11388 #endif
11389             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
11390                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
11391             } else {
11392                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
11393             }
11394          }
11395          ast_mutex_unlock(lock);
11396          return RESULT_SUCCESS;
11397       }
11398       tmp = tmp->next;
11399    }
11400    
11401    ast_cli(fd, "Unable to find given channel %d\n", channel);
11402    ast_mutex_unlock(lock);
11403    return RESULT_FAILURE;
11404 }
11405 
11406 static char zap_show_cadences_help[] =
11407 "Usage: zap show cadences\n"
11408 "       Shows all cadences currently defined\n";
11409 
11410 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
11411 {
11412    int i, j;
11413    for (i = 0; i < num_cadence; i++) {
11414       char output[1024];
11415       char tmp[16], tmp2[64];
11416       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
11417       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
11418 
11419       for (j = 0; j < 16; j++) {
11420          if (cadences[i].ringcadence[j] == 0)
11421             break;
11422          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
11423          if (cidrings[i] * 2 - 1 == j)
11424             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
11425          else
11426             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
11427          if (j != 0)
11428             strncat(output, ",", sizeof(output) - strlen(output) - 1);
11429          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
11430       }
11431       ast_cli(fd,"%s\n",output);
11432    }
11433    return 0;
11434 }
11435 
11436 /* Based on irqmiss.c */
11437 static int zap_show_status(int fd, int argc, char *argv[]) {
11438    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
11439    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
11440 
11441    int span;
11442    int res;
11443    char alarms[50];
11444 
11445    int ctl;
11446    ZT_SPANINFO s;
11447 
11448    ctl = open("/dev/zap/ctl", O_RDWR);
11449    if (ctl < 0) {
11450       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
11451       ast_cli(fd, "No Zaptel interface found.\n");
11452       return RESULT_FAILURE;
11453    }
11454    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
11455 
11456    for (span = 1; span < ZT_MAX_SPANS; ++span) {
11457       s.spanno = span;
11458       res = ioctl(ctl, ZT_SPANSTAT, &s);
11459       if (res) {
11460          continue;
11461       }
11462       alarms[0] = '\0';
11463       if (s.alarms > 0) {
11464          if (s.alarms & ZT_ALARM_BLUE)
11465             strcat(alarms, "BLU/");
11466          if (s.alarms & ZT_ALARM_YELLOW)
11467             strcat(alarms, "YEL/");
11468          if (s.alarms & ZT_ALARM_RED)
11469             strcat(alarms, "RED/");
11470          if (s.alarms & ZT_ALARM_LOOPBACK)
11471             strcat(alarms, "LB/");
11472          if (s.alarms & ZT_ALARM_RECOVER)
11473             strcat(alarms, "REC/");
11474          if (s.alarms & ZT_ALARM_NOTOPEN)
11475             strcat(alarms, "NOP/");
11476          if (!strlen(alarms))
11477             strcat(alarms, "UUU/");
11478          if (strlen(alarms)) {
11479             /* Strip trailing / */
11480             alarms[strlen(alarms) - 1] = '\0';
11481          }
11482       } else {
11483          if (s.numchans)
11484             strcpy(alarms, "OK");
11485          else
11486             strcpy(alarms, "UNCONFIGURED");
11487       }
11488 
11489       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
11490    }
11491    close(ctl);
11492 
11493    return RESULT_SUCCESS;
11494 #undef FORMAT
11495 #undef FORMAT2
11496 }
11497 
11498 static char show_channels_usage[] =
11499    "Usage: zap show channels\n"
11500    "  Shows a list of available channels\n";
11501 
11502 static char show_channel_usage[] =
11503    "Usage: zap show channel <chan num>\n"
11504    "  Detailed information about a given channel\n";
11505 
11506 static char zap_show_status_usage[] =
11507    "Usage: zap show status\n"
11508    "       Shows a list of Zaptel cards with status\n";
11509 
11510 static char destroy_channel_usage[] =
11511    "Usage: zap destroy channel <chan num>\n"
11512    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
11513 
11514 static char zap_restart_usage[] =
11515    "Usage: zap restart\n"
11516    "  Restarts the zaptel channels: destroys them all and then\n"
11517    "  re-reads them from zapata.conf.\n"
11518    "  Note that this will STOP any running CALL on zaptel channels.\n"
11519    "";
11520 
11521 static struct ast_cli_entry zap_cli[] = {
11522    { { "zap", "show", "cadences", NULL },
11523    handle_zap_show_cadences, "List cadences",
11524    zap_show_cadences_help },
11525 
11526    { { "zap", "show", "channels", NULL},
11527    zap_show_channels, "Show active zapata channels",
11528    show_channels_usage },
11529 
11530    { { "zap", "show", "channel", NULL},
11531    zap_show_channel, "Show information on a channel",
11532    show_channel_usage },
11533 
11534    { { "zap", "destroy", "channel", NULL},
11535    zap_destroy_channel, "Destroy a channel",
11536    destroy_channel_usage },
11537 
11538    { { "zap", "restart", NULL},
11539    zap_restart_cmd, "Fully restart zaptel channels",
11540    zap_restart_usage },
11541 
11542    { { "zap", "show", "status", NULL},
11543    zap_show_status, "Show all Zaptel cards status",
11544    zap_show_status_usage },
11545 };
11546 
11547 #define TRANSFER  0
11548 #define HANGUP    1
11549 
11550 static int zap_fake_event(struct zt_pvt *p, int mode)
11551 {
11552    if (p) {
11553       switch (mode) {
11554          case TRANSFER:
11555             p->fake_event = ZT_EVENT_WINKFLASH;
11556             break;
11557          case HANGUP:
11558             p->fake_event = ZT_EVENT_ONHOOK;
11559             break;
11560          default:
11561             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
11562       }
11563    }
11564    return 0;
11565 }
11566 static struct zt_pvt *find_channel(int channel)
11567 {
11568    struct zt_pvt *p = iflist;
11569    while (p) {
11570       if (p->channel == channel) {
11571          break;
11572       }
11573       p = p->next;
11574    }
11575    return p;
11576 }
11577 
11578 static int action_zapdndon(struct mansession *s, const struct message *m)
11579 {
11580    struct zt_pvt *p = NULL;
11581    const char *channel = astman_get_header(m, "ZapChannel");
11582 
11583    if (ast_strlen_zero(channel)) {
11584       astman_send_error(s, m, "No channel specified");
11585       return 0;
11586    }
11587    p = find_channel(atoi(channel));
11588    if (!p) {
11589       astman_send_error(s, m, "No such channel");
11590       return 0;
11591    }
11592    p->dnd = 1;
11593    astman_send_ack(s, m, "DND Enabled");
11594    return 0;
11595 }
11596 
11597 static int action_zapdndoff(struct mansession *s, const struct message *m)
11598 {
11599    struct zt_pvt *p = NULL;
11600    const char *channel = astman_get_header(m, "ZapChannel");
11601 
11602    if (ast_strlen_zero(channel)) {
11603       astman_send_error(s, m, "No channel specified");
11604       return 0;
11605    }
11606    p = find_channel(atoi(channel));
11607    if (!p) {
11608       astman_send_error(s, m, "No such channel");
11609       return 0;
11610    }
11611    p->dnd = 0;
11612    astman_send_ack(s, m, "DND Disabled");
11613    return 0;
11614 }
11615 
11616 static int action_transfer(struct mansession *s, const struct message *m)
11617 {
11618    struct zt_pvt *p = NULL;
11619    const char *channel = astman_get_header(m, "ZapChannel");
11620 
11621    if (ast_strlen_zero(channel)) {
11622       astman_send_error(s, m, "No channel specified");
11623       return 0;
11624    }
11625    p = find_channel(atoi(channel));
11626    if (!p) {
11627       astman_send_error(s, m, "No such channel");
11628       return 0;
11629    }
11630    zap_fake_event(p,TRANSFER);
11631    astman_send_ack(s, m, "ZapTransfer");
11632    return 0;
11633 }
11634 
11635 static int action_transferhangup(struct mansession *s, const struct message *m)
11636 {
11637    struct zt_pvt *p = NULL;
11638    const char *channel = astman_get_header(m, "ZapChannel");
11639 
11640    if (ast_strlen_zero(channel)) {
11641       astman_send_error(s, m, "No channel specified");
11642       return 0;
11643    }
11644    p = find_channel(atoi(channel));
11645    if (!p) {
11646       astman_send_error(s, m, "No such channel");
11647       return 0;
11648    }
11649    zap_fake_event(p,HANGUP);
11650    astman_send_ack(s, m, "ZapHangup");
11651    return 0;
11652 }
11653 
11654 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
11655 {
11656    struct zt_pvt *p = NULL;
11657    const char *channel = astman_get_header(m, "ZapChannel");
11658    const char *number = astman_get_header(m, "Number");
11659    int i;
11660 
11661    if (ast_strlen_zero(channel)) {
11662       astman_send_error(s, m, "No channel specified");
11663       return 0;
11664    }
11665    if (ast_strlen_zero(number)) {
11666       astman_send_error(s, m, "No number specified");
11667       return 0;
11668    }
11669    p = find_channel(atoi(channel));
11670    if (!p) {
11671       astman_send_error(s, m, "No such channel");
11672       return 0;
11673    }
11674    if (!p->owner) {
11675       astman_send_error(s, m, "Channel does not have it's owner");
11676       return 0;
11677    }
11678    for (i = 0; i < strlen(number); i++) {
11679       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
11680       zap_queue_frame(p, &f, NULL); 
11681    }
11682    astman_send_ack(s, m, "ZapDialOffhook");
11683    return 0;
11684 }
11685 
11686 static int action_zapshowchannels(struct mansession *s, const struct message *m)
11687 {
11688    struct zt_pvt *tmp = NULL;
11689    const char *id = astman_get_header(m, "ActionID");
11690    char idText[256] = "";
11691 
11692    astman_send_ack(s, m, "Zapata channel status will follow");
11693    if (!ast_strlen_zero(id))
11694       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
11695 
11696    ast_mutex_lock(&iflock);
11697    
11698    tmp = iflist;
11699    while (tmp) {
11700       if (tmp->channel > 0) {
11701          int alarm = get_alarms(tmp);
11702          astman_append(s,
11703             "Event: ZapShowChannels\r\n"
11704             "Channel: %d\r\n"
11705             "Signalling: %s\r\n"
11706             "Context: %s\r\n"
11707             "DND: %s\r\n"
11708             "Alarm: %s\r\n"
11709             "%s"
11710             "\r\n",
11711             tmp->channel, sig2str(tmp->sig), tmp->context, 
11712             tmp->dnd ? "Enabled" : "Disabled",
11713             alarm2str(alarm), idText);
11714       } 
11715 
11716       tmp = tmp->next;
11717    }
11718 
11719    ast_mutex_unlock(&iflock);
11720    
11721    astman_append(s, 
11722       "Event: ZapShowChannelsComplete\r\n"
11723       "%s"
11724       "\r\n", 
11725       idText);
11726    return 0;
11727 }
11728 
11729 static int __unload_module(void)
11730 {
11731    int x;
11732    struct zt_pvt *p, *pl;
11733 
11734 #ifdef HAVE_PRI
11735    int i;
11736    for (i = 0; i < NUM_SPANS; i++) {
11737       if (pris[i].master != AST_PTHREADT_NULL) 
11738          pthread_cancel(pris[i].master);
11739    }
11740    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
11741    ast_unregister_application(zap_send_keypad_facility_app);
11742    ast_unregister_application(zapCD_app);
11743    ast_unregister_application(zapInband_app);
11744 #endif
11745 #ifdef HAVE_GSMAT
11746    ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
11747    ast_cli_unregister(&gsm_send_sms);
11748    ast_cli_unregister(&gsm_send_pdu);
11749    ast_cli_unregister(&gsm_show_status);
11750 #endif
11751    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
11752    ast_unregister_application(zapEC_app);
11753    ast_manager_unregister( "ZapDialOffhook" );
11754    ast_manager_unregister( "ZapHangup" );
11755    ast_manager_unregister( "ZapTransfer" );
11756    ast_manager_unregister( "ZapDNDoff" );
11757    ast_manager_unregister( "ZapDNDon" );
11758    ast_manager_unregister("ZapShowChannels");
11759    ast_manager_unregister("ZapRestart");
11760    ast_channel_unregister(&zap_tech);
11761    ast_mutex_lock(&iflock);
11762    /* Hangup all interfaces if they have an owner */
11763    p = iflist;
11764    while (p) {
11765       if (p->owner)
11766          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
11767       p = p->next;
11768    }
11769    ast_mutex_unlock(&iflock);
11770    ast_mutex_lock(&monlock);
11771    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
11772       pthread_cancel(monitor_thread);
11773       pthread_kill(monitor_thread, SIGURG);
11774       pthread_join(monitor_thread, NULL);
11775    }
11776    monitor_thread = AST_PTHREADT_STOP;
11777    ast_mutex_unlock(&monlock);
11778 
11779    ast_mutex_lock(&iflock);
11780    /* Destroy all the interfaces and free their memory */
11781    p = iflist;
11782    while (p) {
11783       /* Free any callerid */
11784       if (p->cidspill)
11785          free(p->cidspill);
11786       /* Close the zapata thingy */
11787       if (p->subs[SUB_REAL].zfd > -1)
11788          zt_close(p->subs[SUB_REAL].zfd);
11789       pl = p;
11790       p = p->next;
11791       x = pl->channel;
11792       /* Free associated memory */
11793       if (pl)
11794          destroy_zt_pvt(&pl);
11795       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
11796    }
11797    iflist = NULL;
11798    ifcount = 0;
11799    ast_mutex_unlock(&iflock);
11800 #ifdef HAVE_PRI      
11801    for (i = 0; i < NUM_SPANS; i++) {
11802       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
11803          pthread_join(pris[i].master, NULL);
11804       zt_close(pris[i].fds[i]);
11805    }
11806 #endif
11807    return 0;
11808 }
11809 
11810 static int unload_module(void)
11811 {
11812 #ifdef HAVE_PRI      
11813    int y;
11814    for (y = 0; y < NUM_SPANS; y++)
11815       ast_mutex_destroy(&pris[y].lock);
11816 #endif
11817    return __unload_module();
11818 }
11819 
11820 static int build_channels(struct zt_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
11821 {
11822    char *c, *chan;
11823    int x, start, finish;
11824    struct zt_pvt *tmp;
11825 #ifdef HAVE_PRI
11826    struct zt_pri *pri;
11827    int trunkgroup, y;
11828 #endif
11829    
11830    if ((reload == 0) && (conf->chan.sig < 0)) {
11831       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
11832       return -1;
11833    }
11834 
11835    c = ast_strdupa(value);
11836 
11837 #ifdef HAVE_PRI
11838    pri = NULL;
11839    if (iscrv) {
11840       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
11841          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
11842          return -1;
11843       }
11844       if (trunkgroup < 1) {
11845          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
11846          return -1;
11847       }
11848       c += y;
11849       for (y = 0; y < NUM_SPANS; y++) {
11850          if (pris[y].trunkgroup == trunkgroup) {
11851             pri = pris + y;
11852             break;
11853          }
11854       }
11855       if (!pri) {
11856          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
11857          return -1;
11858       }
11859    }
11860 #endif         
11861 
11862    while ((chan = strsep(&c, ","))) {
11863       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
11864          /* Range */
11865       } else if (sscanf(chan, "%d", &start)) {
11866          /* Just one */
11867          finish = start;
11868       } else if (!strcasecmp(chan, "pseudo")) {
11869          finish = start = CHAN_PSEUDO;
11870          if (found_pseudo)
11871             *found_pseudo = 1;
11872       } else {
11873          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
11874          return -1;
11875       }
11876       if (finish < start) {
11877          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
11878          x = finish;
11879          finish = start;
11880          start = x;
11881       }
11882 
11883       for (x = start; x <= finish; x++) {
11884 #ifdef HAVE_PRI
11885          tmp = mkintf(x, conf, pri, reload);
11886 #else       
11887          tmp = mkintf(x, conf, NULL, reload);
11888 #endif         
11889 
11890          if (tmp) {
11891             if (option_verbose > 2) {
11892 #ifdef HAVE_PRI
11893                if (pri)
11894                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
11895                else
11896 #endif
11897                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
11898             }
11899          } else {
11900             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
11901                (reload == 1) ? "reconfigure" : "register", value);
11902             return -1;
11903          }
11904       }
11905    }
11906 
11907    return 0;
11908 }
11909 
11910 /** The length of the parameters list of 'zapchan'. 
11911  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
11912 #define MAX_CHANLIST_LEN 80
11913 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
11914 {
11915    struct zt_pvt *tmp;
11916    char *ringc; /* temporary string for parsing the dring number. */
11917    int y;
11918    int found_pseudo = 0;
11919         char zapchan[MAX_CHANLIST_LEN] = {};
11920 
11921    for (; v; v = v->next) {
11922       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
11923          continue;
11924 
11925       /* Create the interface list */
11926       if (!strcasecmp(v->name, "channel")
11927 #ifdef HAVE_PRI
11928           || !strcasecmp(v->name, "crv")
11929 #endif         
11930          ) {
11931          int iscrv;
11932          if (skipchannels)
11933             continue;
11934          iscrv = !strcasecmp(v->name, "crv");
11935          if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
11936                return -1;
11937       } else if (!strcasecmp(v->name, "zapchan")) {
11938          ast_copy_string(zapchan, v->value, sizeof(zapchan));
11939       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
11940          if (ast_true(v->value))
11941             confp->chan.usedistinctiveringdetection = 1;
11942       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
11943          if (ast_true(v->value))
11944             distinctiveringaftercid = 1;
11945       } else if (!strcasecmp(v->name, "dring1context")) {
11946          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
11947       } else if (!strcasecmp(v->name, "dring2context")) {
11948          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
11949       } else if (!strcasecmp(v->name, "dring3context")) {
11950          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
11951       } else if (!strcasecmp(v->name, "dring1")) {
11952          ringc = v->value;
11953          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
11954       } else if (!strcasecmp(v->name, "dring2")) {
11955          ringc = v->value;
11956          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
11957       } else if (!strcasecmp(v->name, "dring3")) {
11958          ringc = v->value;
11959          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
11960       } else if (!strcasecmp(v->name, "usecallerid")) {
11961          confp->chan.use_callerid = ast_true(v->value);
11962       } else if (!strcasecmp(v->name, "cidsignalling")) {
11963          if (!strcasecmp(v->value, "bell"))
11964             confp->chan.cid_signalling = CID_SIG_BELL;
11965          else if (!strcasecmp(v->value, "v23"))
11966             confp->chan.cid_signalling = CID_SIG_V23;
11967          else if (!strcasecmp(v->value, "dtmf"))
11968             confp->chan.cid_signalling = CID_SIG_DTMF;
11969          else if (!strcasecmp(v->value, "smdi"))
11970             confp->chan.cid_signalling = CID_SIG_SMDI;
11971          else if (!strcasecmp(v->value, "v23_jp"))
11972             confp->chan.cid_signalling = CID_SIG_V23_JP;
11973          else if (ast_true(v->value))
11974             confp->chan.cid_signalling = CID_SIG_BELL;
11975       } else if (!strcasecmp(v->name, "cidstart")) {
11976          if (!strcasecmp(v->value, "ring"))
11977             confp->chan.cid_start = CID_START_RING;
11978          else if (!strcasecmp(v->value, "polarity"))
11979             confp->chan.cid_start = CID_START_POLARITY;
11980          else if (ast_true(v->value))
11981             confp->chan.cid_start = CID_START_RING;
11982       } else if (!strcasecmp(v->name, "threewaycalling")) {
11983          confp->chan.threewaycalling = ast_true(v->value);
11984       } else if (!strcasecmp(v->name, "cancallforward")) {
11985          confp->chan.cancallforward = ast_true(v->value);
11986       } else if (!strcasecmp(v->name, "relaxdtmf")) {
11987          if (ast_true(v->value)) 
11988             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
11989          else
11990             confp->chan.dtmfrelax = 0;
11991       } else if (!strcasecmp(v->name, "mailbox")) {
11992          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
11993       } else if (!strcasecmp(v->name, "adsi")) {
11994          confp->chan.adsi = ast_true(v->value);
11995       } else if (!strcasecmp(v->name, "usesmdi")) {
11996          confp->chan.use_smdi = ast_true(v->value);
11997       } else if (!strcasecmp(v->name, "smdiport")) {
11998          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
11999       } else if (!strcasecmp(v->name, "transfer")) {
12000          confp->chan.transfer = ast_true(v->value);
12001       } else if (!strcasecmp(v->name, "canpark")) {
12002          confp->chan.canpark = ast_true(v->value);
12003       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
12004          confp->chan.echocanbridged = ast_true(v->value);
12005       } else if (!strcasecmp(v->name, "busydetect")) {
12006          confp->chan.busydetect = ast_true(v->value);
12007       } else if (!strcasecmp(v->name, "busycount")) {
12008          confp->chan.busycount = atoi(v->value);
12009       } else if (!strcasecmp(v->name, "busypattern")) {
12010          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
12011             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
12012          }
12013       } else if (!strcasecmp(v->name, "callprogress")) {
12014          if (ast_true(v->value))
12015             confp->chan.callprogress |= 1;
12016          else
12017             confp->chan.callprogress &= ~1;
12018       } else if (!strcasecmp(v->name, "faxdetect")) {
12019          if (!strcasecmp(v->value, "incoming")) {
12020             confp->chan.callprogress |= 4;
12021             confp->chan.callprogress &= ~2;
12022          } else if (!strcasecmp(v->value, "outgoing")) {
12023             confp->chan.callprogress &= ~4;
12024             confp->chan.callprogress |= 2;
12025          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
12026             confp->chan.callprogress |= 6;
12027          else
12028             confp->chan.callprogress &= ~6;
12029       } else if (!strcasecmp(v->name, "echocancel")) {
12030          if (!ast_strlen_zero(v->value)) {
12031             y = atoi(v->value);
12032          } else
12033             y = 0;
12034          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
12035             confp->chan.echocancel = y;
12036          else {
12037             confp->chan.echocancel = ast_true(v->value);
12038             if (confp->chan.echocancel)
12039                confp->chan.echocancel=128;
12040          }
12041       } else if (!strcasecmp(v->name, "echotraining")) {
12042          if (sscanf(v->value, "%d", &y) == 1) {
12043             if ((y < 10) || (y > 4000)) {
12044                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
12045             } else {
12046                confp->chan.echotraining = y;
12047             }
12048          } else if (ast_true(v->value)) {
12049             confp->chan.echotraining = 400;
12050          } else
12051             confp->chan.echotraining = 0;
12052       } else if (!strcasecmp(v->name, "hidecallerid")) {
12053          confp->chan.hidecallerid = ast_true(v->value);
12054       } else if (!strcasecmp(v->name, "hidecalleridname")) {
12055          confp->chan.hidecalleridname = ast_true(v->value);
12056       } else if (!strcasecmp(v->name, "pulsedial")) {
12057          confp->chan.pulse = ast_true(v->value);
12058       } else if (!strcasecmp(v->name, "callreturn")) {
12059          confp->chan.callreturn = ast_true(v->value);
12060       } else if (!strcasecmp(v->name, "callwaiting")) {
12061          confp->chan.callwaiting = ast_true(v->value);
12062       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
12063          confp->chan.callwaitingcallerid = ast_true(v->value);
12064       } else if (!strcasecmp(v->name, "context")) {
12065          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
12066       } else if (!strcasecmp(v->name, "language")) {
12067          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
12068       } else if (!strcasecmp(v->name, "progzone")) {
12069          ast_copy_string(progzone, v->value, sizeof(progzone));
12070       } else if (!strcasecmp(v->name, "mohinterpret") 
12071          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
12072          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
12073       } else if (!strcasecmp(v->name, "mohsuggest")) {
12074          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
12075       } else if (!strcasecmp(v->name, "stripmsd")) {
12076          confp->chan.stripmsd = atoi(v->value);
12077       } else if (!strcasecmp(v->name, "jitterbuffers")) {
12078          numbufs = atoi(v->value);
12079       } else if (!strcasecmp(v->name, "group")) {
12080          confp->chan.group = ast_get_group(v->value);
12081       } else if (!strcasecmp(v->name, "callgroup")) {
12082          confp->chan.callgroup = ast_get_group(v->value);
12083       } else if (!strcasecmp(v->name, "pickupgroup")) {
12084          confp->chan.pickupgroup = ast_get_group(v->value);
12085       } else if (!strcasecmp(v->name, "immediate")) {
12086          confp->chan.immediate = ast_true(v->value);
12087       } else if (!strcasecmp(v->name, "transfertobusy")) {
12088          confp->chan.transfertobusy = ast_true(v->value);
12089       } else if (!strcasecmp(v->name, "rxgain")) {
12090          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
12091             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
12092          }
12093       } else if (!strcasecmp(v->name, "txgain")) {
12094          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
12095             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
12096          }
12097       } else if (!strcasecmp(v->name, "tonezone")) {
12098          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
12099             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
12100          }
12101       } else if (!strcasecmp(v->name, "callerid")) {
12102          if (!strcasecmp(v->value, "asreceived")) {
12103             confp->chan.cid_num[0] = '\0';
12104             confp->chan.cid_name[0] = '\0';
12105          } else {
12106             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
12107          } 
12108       } else if (!strcasecmp(v->name, "fullname")) {
12109          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
12110       } else if (!strcasecmp(v->name, "cid_number")) {
12111          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
12112       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
12113          confp->chan.zaptrcallerid = ast_true(v->value);
12114       } else if (!strcasecmp(v->name, "restrictcid")) {
12115          confp->chan.restrictcid = ast_true(v->value);
12116       } else if (!strcasecmp(v->name, "usecallingpres")) {
12117          confp->chan.use_callingpres = ast_true(v->value);
12118       } else if (!strcasecmp(v->name, "accountcode")) {
12119          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
12120       } else if (!strcasecmp(v->name, "amaflags")) {
12121          y = ast_cdr_amaflags2int(v->value);
12122          if (y < 0) 
12123             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
12124          else
12125             confp->chan.amaflags = y;
12126       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
12127          confp->chan.polarityonanswerdelay = atoi(v->value);
12128       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
12129          confp->chan.answeronpolarityswitch = ast_true(v->value);
12130       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
12131          confp->chan.hanguponpolarityswitch = ast_true(v->value);
12132       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
12133          confp->chan.sendcalleridafter = atoi(v->value);
12134       } else if (!reload){ 
12135           if (!strcasecmp(v->name, "signalling")) {
12136             confp->chan.outsigmod = -1;
12137             if (!strcasecmp(v->value, "em")) {
12138                confp->chan.sig = SIG_EM;
12139             } else if (!strcasecmp(v->value, "em_e1")) {
12140                confp->chan.sig = SIG_EM_E1;
12141             } else if (!strcasecmp(v->value, "em_w")) {
12142                confp->chan.sig = SIG_EMWINK;
12143                confp->chan.radio = 0;
12144             } else if (!strcasecmp(v->value, "fxs_ls")) {
12145                confp->chan.sig = SIG_FXSLS;
12146                confp->chan.radio = 0;
12147             } else if (!strcasecmp(v->value, "fxs_gs")) {
12148                confp->chan.sig = SIG_FXSGS;
12149                confp->chan.radio = 0;
12150             } else if (!strcasecmp(v->value, "fxs_ks")) {
12151                confp->chan.sig = SIG_FXSKS;
12152                confp->chan.radio = 0;
12153             } else if (!strcasecmp(v->value, "fxo_ls")) {
12154                confp->chan.sig = SIG_FXOLS;
12155                confp->chan.radio = 0;
12156             } else if (!strcasecmp(v->value, "fxo_gs")) {
12157                confp->chan.sig = SIG_FXOGS;
12158                confp->chan.radio = 0;
12159             } else if (!strcasecmp(v->value, "fxo_ks")) {
12160                confp->chan.sig = SIG_FXOKS;
12161                confp->chan.radio = 0;
12162             } else if (!strcasecmp(v->value, "fxs_rx")) {
12163                confp->chan.sig = SIG_FXSKS;
12164                confp->chan.radio = 1;
12165             } else if (!strcasecmp(v->value, "fxo_rx")) {
12166                confp->chan.sig = SIG_FXOLS;
12167                confp->chan.radio = 1;
12168             } else if (!strcasecmp(v->value, "fxs_tx")) {
12169                confp->chan.sig = SIG_FXSLS;
12170                confp->chan.radio = 1;
12171             } else if (!strcasecmp(v->value, "fxo_tx")) {
12172                confp->chan.sig = SIG_FXOGS;
12173                confp->chan.radio = 1;
12174             } else if (!strcasecmp(v->value, "em_rx")) {
12175                confp->chan.sig = SIG_EM;
12176                confp->chan.radio = 1;
12177             } else if (!strcasecmp(v->value, "em_tx")) {
12178                confp->chan.sig = SIG_EM;
12179                confp->chan.radio = 1;
12180             } else if (!strcasecmp(v->value, "em_rxtx")) {
12181                confp->chan.sig = SIG_EM;
12182                confp->chan.radio = 2;
12183             } else if (!strcasecmp(v->value, "em_txrx")) {
12184                confp->chan.sig = SIG_EM;
12185                confp->chan.radio = 2;
12186             } else if (!strcasecmp(v->value, "sf")) {
12187                confp->chan.sig = SIG_SF;
12188                confp->chan.radio = 0;
12189             } else if (!strcasecmp(v->value, "sf_w")) {
12190                confp->chan.sig = SIG_SFWINK;
12191                confp->chan.radio = 0;
12192             } else if (!strcasecmp(v->value, "sf_featd")) {
12193                confp->chan.sig = SIG_FEATD;
12194                confp->chan.radio = 0;
12195             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12196                confp->chan.sig = SIG_FEATDMF;
12197                confp->chan.radio = 0;
12198             } else if (!strcasecmp(v->value, "sf_featb")) {
12199                confp->chan.sig = SIG_SF_FEATB;
12200                confp->chan.radio = 0;
12201             } else if (!strcasecmp(v->value, "sf")) {
12202                confp->chan.sig = SIG_SF;
12203                confp->chan.radio = 0;
12204             } else if (!strcasecmp(v->value, "sf_rx")) {
12205                confp->chan.sig = SIG_SF;
12206                confp->chan.radio = 1;
12207             } else if (!strcasecmp(v->value, "sf_tx")) {
12208                confp->chan.sig = SIG_SF;
12209                confp->chan.radio = 1;
12210             } else if (!strcasecmp(v->value, "sf_rxtx")) {
12211                confp->chan.sig = SIG_SF;
12212                confp->chan.radio = 2;
12213             } else if (!strcasecmp(v->value, "sf_txrx")) {
12214                confp->chan.sig = SIG_SF;
12215                confp->chan.radio = 2;
12216             } else if (!strcasecmp(v->value, "featd")) {
12217                confp->chan.sig = SIG_FEATD;
12218                confp->chan.radio = 0;
12219             } else if (!strcasecmp(v->value, "featdmf")) {
12220                confp->chan.sig = SIG_FEATDMF;
12221                confp->chan.radio = 0;
12222             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12223                confp->chan.sig = SIG_FEATDMF_TA;
12224                confp->chan.radio = 0;
12225             } else if (!strcasecmp(v->value, "e911")) {
12226                confp->chan.sig = SIG_E911;
12227                confp->chan.radio = 0;
12228             } else if (!strcasecmp(v->value, "fgccama")) {
12229                confp->chan.sig = SIG_FGC_CAMA;
12230                confp->chan.radio = 0;
12231             } else if (!strcasecmp(v->value, "fgccamamf")) {
12232                confp->chan.sig = SIG_FGC_CAMAMF;
12233                confp->chan.radio = 0;
12234             } else if (!strcasecmp(v->value, "featb")) {
12235                confp->chan.sig = SIG_FEATB;
12236                confp->chan.radio = 0;
12237 #ifdef HAVE_PRI
12238             } else if (!strcasecmp(v->value, "pri_net")) {
12239                confp->chan.radio = 0;
12240                confp->chan.sig = SIG_PRI;
12241                confp->pri.nodetype = PRI_NETWORK;
12242             } else if (!strcasecmp(v->value, "pri_cpe")) {
12243                confp->chan.sig = SIG_PRI;
12244                confp->chan.radio = 0;
12245                confp->pri.nodetype = PRI_CPE;
12246             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
12247                confp->chan.sig = SIG_GR303FXOKS;
12248                confp->chan.radio = 0;
12249                confp->pri.nodetype = PRI_NETWORK;
12250             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
12251                confp->chan.sig = SIG_GR303FXSKS;
12252                confp->chan.radio = 0;
12253                confp->pri.nodetype = PRI_CPE;
12254             } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
12255                confp->chan.radio = 0;
12256                confp->chan.sig = SIG_PRI;
12257                confp->pri.nodetype = BRI_NETWORK_PTMP;
12258             } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
12259                confp->chan.sig = SIG_PRI;
12260                confp->chan.radio = 0;
12261                confp->pri.nodetype = BRI_CPE_PTMP;
12262             } else if (!strcasecmp(v->value, "bri_net")) {
12263                confp->chan.radio = 0;
12264                confp->chan.sig = SIG_PRI;
12265                confp->pri.nodetype = BRI_NETWORK;
12266             } else if (!strcasecmp(v->value, "bri_cpe")) {
12267                confp->chan.sig = SIG_PRI;
12268                confp->chan.radio = 0;
12269                confp->pri.nodetype = BRI_CPE;
12270 #endif
12271 #ifdef HAVE_GSMAT
12272             } else if (!strcasecmp(v->value, "gsm")) {
12273                confp->chan.sig = SIG_GSM;
12274                confp->chan.radio = 0;
12275 #endif
12276             } else {
12277                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12278             }
12279           } else if (!strcasecmp(v->name, "outsignalling")) {
12280             if (!strcasecmp(v->value, "em")) {
12281                confp->chan.outsigmod = SIG_EM;
12282             } else if (!strcasecmp(v->value, "em_e1")) {
12283                confp->chan.outsigmod = SIG_EM_E1;
12284             } else if (!strcasecmp(v->value, "em_w")) {
12285                confp->chan.outsigmod = SIG_EMWINK;
12286             } else if (!strcasecmp(v->value, "sf")) {
12287                confp->chan.outsigmod = SIG_SF;
12288             } else if (!strcasecmp(v->value, "sf_w")) {
12289                confp->chan.outsigmod = SIG_SFWINK;
12290             } else if (!strcasecmp(v->value, "sf_featd")) {
12291                confp->chan.outsigmod = SIG_FEATD;
12292             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12293                confp->chan.outsigmod = SIG_FEATDMF;
12294             } else if (!strcasecmp(v->value, "sf_featb")) {
12295                confp->chan.outsigmod = SIG_SF_FEATB;
12296             } else if (!strcasecmp(v->value, "sf")) {
12297                confp->chan.outsigmod = SIG_SF;
12298             } else if (!strcasecmp(v->value, "featd")) {
12299                confp->chan.outsigmod = SIG_FEATD;
12300             } else if (!strcasecmp(v->value, "featdmf")) {
12301                confp->chan.outsigmod = SIG_FEATDMF;
12302             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12303                confp->chan.outsigmod = SIG_FEATDMF_TA;
12304             } else if (!strcasecmp(v->value, "e911")) {
12305                confp->chan.outsigmod = SIG_E911;
12306             } else if (!strcasecmp(v->value, "fgccama")) {
12307                confp->chan.outsigmod = SIG_FGC_CAMA;
12308             } else if (!strcasecmp(v->value, "fgccamamf")) {
12309                confp->chan.outsigmod = SIG_FGC_CAMAMF;
12310             } else if (!strcasecmp(v->value, "featb")) {
12311                confp->chan.outsigmod = SIG_FEATB;
12312             } else {
12313                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12314             }
12315 #ifdef HAVE_PRI
12316          } else if (!strcasecmp(v->name, "pridialplan")) {
12317             if (!strcasecmp(v->value, "national")) {
12318                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
12319             } else if (!strcasecmp(v->value, "unknown")) {
12320                confp->pri.dialplan = PRI_UNKNOWN + 1;
12321             } else if (!strcasecmp(v->value, "private")) {
12322                confp->pri.dialplan = PRI_PRIVATE + 1;
12323             } else if (!strcasecmp(v->value, "international")) {
12324                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
12325             } else if (!strcasecmp(v->value, "local")) {
12326                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
12327             } else if (!strcasecmp(v->value, "dynamic")) {
12328                confp->pri.dialplan = -1;
12329             } else {
12330                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12331             }
12332          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
12333             if (!strcasecmp(v->value, "national")) {
12334                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
12335             } else if (!strcasecmp(v->value, "unknown")) {
12336                confp->pri.localdialplan = PRI_UNKNOWN + 1;
12337             } else if (!strcasecmp(v->value, "private")) {
12338                confp->pri.localdialplan = PRI_PRIVATE + 1;
12339             } else if (!strcasecmp(v->value, "international")) {
12340                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
12341             } else if (!strcasecmp(v->value, "local")) {
12342                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
12343             } else if (!strcasecmp(v->value, "dynamic")) {
12344                confp->pri.localdialplan = -1;
12345             } else {
12346                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12347             }
12348          } else if (!strcasecmp(v->name, "switchtype")) {
12349             if (!strcasecmp(v->value, "national")) 
12350                confp->pri.switchtype = PRI_SWITCH_NI2;
12351             else if (!strcasecmp(v->value, "ni1"))
12352                confp->pri.switchtype = PRI_SWITCH_NI1;
12353             else if (!strcasecmp(v->value, "dms100"))
12354                confp->pri.switchtype = PRI_SWITCH_DMS100;
12355             else if (!strcasecmp(v->value, "4ess"))
12356                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
12357             else if (!strcasecmp(v->value, "5ess"))
12358                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
12359             else if (!strcasecmp(v->value, "euroisdn"))
12360                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
12361             else if (!strcasecmp(v->value, "qsig"))
12362                confp->pri.switchtype = PRI_SWITCH_QSIG;
12363             else {
12364                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
12365                return -1;
12366             }
12367          } else if (!strcasecmp(v->name, "nsf")) {
12368             if (!strcasecmp(v->value, "sdn"))
12369                confp->pri.nsf = PRI_NSF_SDN;
12370             else if (!strcasecmp(v->value, "megacom"))
12371                confp->pri.nsf = PRI_NSF_MEGACOM;
12372             else if (!strcasecmp(v->value, "tollfreemegacom"))
12373                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
12374             else if (!strcasecmp(v->value, "accunet"))
12375                confp->pri.nsf = PRI_NSF_ACCUNET;
12376             else if (!strcasecmp(v->value, "none"))
12377                confp->pri.nsf = PRI_NSF_NONE;
12378             else {
12379                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
12380                confp->pri.nsf = PRI_NSF_NONE;
12381             }
12382          } else if (!strcasecmp(v->name, "priindication")) {
12383             if (!strcasecmp(v->value, "outofband"))
12384                confp->chan.priindication_oob = 1;
12385             else if (!strcasecmp(v->value, "inband"))
12386                confp->chan.priindication_oob = 0;
12387             else if (!strcasecmp(v->value, "passthrough"))
12388                confp->chan.priindication_oob = 2;
12389             else
12390                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n",
12391                   v->value, v->lineno);
12392          } else if (!strcasecmp(v->name, "pritransfer")) {
12393             if (!strcasecmp(v->value, "no"))
12394                confp->chan.pritransfer = 0;
12395             else if (!strcasecmp(v->value, "ect"))
12396                confp->chan.pritransfer = 1;
12397             else if (!strcasecmp(v->value, "hangup"))
12398                confp->chan.pritransfer = 2;
12399             else
12400                ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n",
12401                   v->value, v->lineno);
12402          } else if (!strcasecmp(v->name, "priexclusive")) {
12403             confp->chan.priexclusive = ast_true(v->value);
12404          } else if (!strcasecmp(v->name, "internationalprefix")) {
12405             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
12406          } else if (!strcasecmp(v->name, "nationalprefix")) {
12407             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
12408          } else if (!strcasecmp(v->name, "localprefix")) {
12409             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
12410          } else if (!strcasecmp(v->name, "privateprefix")) {
12411             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
12412          } else if (!strcasecmp(v->name, "unknownprefix")) {
12413             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
12414          } else if (!strcasecmp(v->name, "nocid")) {
12415             ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid));
12416          } else if (!strcasecmp(v->name, "withheldcid")) {
12417             ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid));
12418          } else if (!strcasecmp(v->name, "pin")) {
12419             ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1);
12420          } else if (!strcasecmp(v->name, "exten")) {
12421             ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1);
12422          } else if (!strcasecmp(v->name, "resetinterval")) {
12423             if (!strcasecmp(v->value, "never"))
12424                confp->pri.resetinterval = -1;
12425             else if (atoi(v->value) >= 60)
12426                confp->pri.resetinterval = atoi(v->value);
12427             else
12428                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
12429                   v->value, v->lineno);
12430          } else if (!strcasecmp(v->name, "minunused")) {
12431             confp->pri.minunused = atoi(v->value);
12432          } else if (!strcasecmp(v->name, "minidle")) {
12433             confp->pri.minidle = atoi(v->value); 
12434          } else if (!strcasecmp(v->name, "idleext")) {
12435             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
12436          } else if (!strcasecmp(v->name, "idledial")) {
12437             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
12438          } else if (!strcasecmp(v->name, "pritrustusercid")) {
12439             confp->pri.usercid = ast_true(v->value);
12440          } else if (!strcasecmp(v->name, "overlapdial")) {
12441             confp->pri.overlapdial = ast_true(v->value);
12442          } else if (!strcasecmp(v->name, "pritimer")) {
12443 #ifdef PRI_GETSET_TIMERS
12444             char *timerc, *c;
12445             int timer, timeridx;
12446             c = v->value;
12447             timerc = strsep(&c, ",");
12448             if (timerc) {
12449                timer = atoi(c);
12450                if (!timer)
12451                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
12452                else {
12453                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
12454                      pritimers[timeridx] = timer;
12455                   else
12456                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
12457                }
12458             } else
12459                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
12460 
12461          } else if (!strcasecmp(v->name, "facilityenable")) {
12462             confp->pri.facilityenable = ast_true(v->value);
12463 #endif /* PRI_GETSET_TIMERS */
12464 #endif /* HAVE_PRI */
12465          } else if (!strcasecmp(v->name, "cadence")) {
12466             /* setup to scan our argument */
12467             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
12468             int i;
12469             struct zt_ring_cadence new_cadence;
12470             int cid_location = -1;
12471             int firstcadencepos = 0;
12472             char original_args[80];
12473             int cadence_is_ok = 1;
12474 
12475             ast_copy_string(original_args, v->value, sizeof(original_args));
12476             /* 16 cadences allowed (8 pairs) */
12477             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]);
12478    
12479             /* Cadence must be even (on/off) */
12480             if (element_count % 2 == 1) {
12481                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
12482                cadence_is_ok = 0;
12483             }
12484    
12485             /* Ring cadences cannot be negative */
12486             for (i = 0; i < element_count; i++) {
12487                if (c[i] == 0) {
12488                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
12489                   cadence_is_ok = 0;
12490                   break;
12491                } else if (c[i] < 0) {
12492                   if (i % 2 == 1) {
12493                      /* Silence duration, negative possibly okay */
12494                      if (cid_location == -1) {
12495                         cid_location = i;
12496                         c[i] *= -1;
12497                      } else {
12498                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
12499                         cadence_is_ok = 0;
12500                         break;
12501                      }
12502                   } else {
12503                      if (firstcadencepos == 0) {
12504                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
12505                                  /* duration will be passed negative to the zaptel driver */
12506                      } else {
12507                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
12508                         cadence_is_ok = 0;
12509                         break;
12510                      }
12511                   }
12512                }
12513             }
12514    
12515             /* Substitute our scanned cadence */
12516             for (i = 0; i < 16; i++) {
12517                new_cadence.ringcadence[i] = c[i];
12518             }
12519    
12520             if (cadence_is_ok) {
12521                /* ---we scanned it without getting annoyed; now some sanity checks--- */
12522                if (element_count < 2) {
12523                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
12524                } else {
12525                   if (cid_location == -1) {
12526                      /* user didn't say; default to first pause */
12527                      cid_location = 1;
12528                   } else {
12529                      /* convert element_index to cidrings value */
12530                      cid_location = (cid_location + 1) / 2;
12531                   }
12532                   /* ---we like their cadence; try to install it--- */
12533                   if (!user_has_defined_cadences++)
12534                      /* this is the first user-defined cadence; clear the default user cadences */
12535                      num_cadence = 0;
12536                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
12537                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
12538                   else {
12539                      cadences[num_cadence] = new_cadence;
12540                      cidrings[num_cadence++] = cid_location;
12541                      if (option_verbose > 2)
12542                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
12543                   }
12544                }
12545             }
12546          } else if (!strcasecmp(v->name, "ringtimeout")) {
12547             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
12548          } else if (!strcasecmp(v->name, "prewink")) {
12549             confp->timing.prewinktime = atoi(v->value);
12550          } else if (!strcasecmp(v->name, "preflash")) {
12551             confp->timing.preflashtime = atoi(v->value);
12552          } else if (!strcasecmp(v->name, "wink")) {
12553             confp->timing.winktime = atoi(v->value);
12554          } else if (!strcasecmp(v->name, "flash")) {
12555             confp->timing.flashtime = atoi(v->value);
12556          } else if (!strcasecmp(v->name, "start")) {
12557             confp->timing.starttime = atoi(v->value);
12558          } else if (!strcasecmp(v->name, "rxwink")) {
12559             confp->timing.rxwinktime = atoi(v->value);
12560          } else if (!strcasecmp(v->name, "rxflash")) {
12561             confp->timing.rxflashtime = atoi(v->value);
12562          } else if (!strcasecmp(v->name, "debounce")) {
12563             confp->timing.debouncetime = atoi(v->value);
12564          } else if (!strcasecmp(v->name, "toneduration")) {
12565             int toneduration;
12566             int ctlfd;
12567             int res;
12568             struct zt_dialparams dps;
12569 
12570             ctlfd = open("/dev/zap/ctl", O_RDWR);
12571             if (ctlfd == -1) {
12572                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
12573                return -1;
12574             }
12575 
12576             toneduration = atoi(v->value);
12577             if (toneduration > -1) {
12578                memset(&dps, 0, sizeof(dps));
12579 
12580                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
12581                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
12582                if (res < 0) {
12583                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
12584                   return -1;
12585                }
12586             }
12587             close(ctlfd);
12588          } else if (!strcasecmp(v->name, "defaultcic")) {
12589             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
12590          } else if (!strcasecmp(v->name, "defaultozz")) {
12591             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
12592          } 
12593       } else if (!skipchannels)
12594          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
12595    }
12596    if (zapchan[0]) { 
12597       /* The user has set 'zapchan' */
12598       /*< \todo pass proper line number instead of 0 */
12599       if (build_channels(confp, 0, zapchan, reload, 0, &found_pseudo)) {
12600          return -1;
12601       }
12602    }
12603    /*< \todo why check for the pseudo in the per-channel section.
12604     * Any actual use for manual setup of the pseudo channel? */
12605    if (!found_pseudo && reload == 0) {
12606       /* Make sure pseudo isn't a member of any groups if
12607          we're automatically making it. */   
12608       
12609       confp->chan.group = 0;
12610       confp->chan.callgroup = 0;
12611       confp->chan.pickupgroup = 0;
12612 
12613       tmp = mkintf(CHAN_PSEUDO, confp, NULL, reload);
12614 
12615       if (tmp) {
12616          if (option_verbose > 2)
12617             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
12618       } else {
12619          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
12620       }
12621    }
12622    return 0;
12623 }
12624       
12625 static int setup_zap(int reload)
12626 {
12627    struct ast_config *cfg;
12628    struct ast_variable *v;
12629    struct zt_chan_conf conf = zt_chan_conf_default();
12630    int res;
12631 
12632 #ifdef HAVE_PRI
12633    char *c;
12634    int spanno;
12635    int i, x;
12636    int logicalspan;
12637    int trunkgroup;
12638    int dchannels[NUM_DCHANS];
12639 #endif
12640 
12641    cfg = ast_config_load(config);
12642 
12643    /* Error if we have no config file */
12644    if (!cfg) {
12645       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
12646       return 0;
12647    }
12648 
12649    /* It's a little silly to lock it, but we mind as well just to be sure */
12650    ast_mutex_lock(&iflock);
12651 #ifdef HAVE_PRI
12652    if (!reload) {
12653       /* Process trunkgroups first */
12654       v = ast_variable_browse(cfg, "trunkgroups");
12655       while (v) {
12656          if (!strcasecmp(v->name, "trunkgroup")) {
12657             trunkgroup = atoi(v->value);
12658             if (trunkgroup > 0) {
12659                if ((c = strchr(v->value, ','))) {
12660                   i = 0;
12661                   memset(dchannels, 0, sizeof(dchannels));
12662                   while (c && (i < NUM_DCHANS)) {
12663                      dchannels[i] = atoi(c + 1);
12664                      if (dchannels[i] < 0) {
12665                         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);
12666                      } else
12667                         i++;
12668                      c = strchr(c + 1, ',');
12669                   }
12670                   if (i) {
12671                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
12672                         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);
12673                      } else if (option_verbose > 1)
12674                         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");
12675                   } else
12676                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
12677                } else
12678                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
12679             } else
12680                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
12681          } else if (!strcasecmp(v->name, "spanmap")) {
12682             spanno = atoi(v->value);
12683             if (spanno > 0) {
12684                if ((c = strchr(v->value, ','))) {
12685                   trunkgroup = atoi(c + 1);
12686                   if (trunkgroup > 0) {
12687                      if ((c = strchr(c + 1, ','))) 
12688                         logicalspan = atoi(c + 1);
12689                      else
12690                         logicalspan = 0;
12691                      if (logicalspan >= 0) {
12692                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
12693                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
12694                         } else if (option_verbose > 1) 
12695                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
12696                      } else
12697                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
12698                   } else
12699                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
12700                } else
12701                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
12702             } else
12703                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
12704          } else {
12705             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
12706          }
12707          v = v->next;
12708       }
12709    }
12710 #endif
12711    
12712    /* Copy the default jb config over global_jbconf */
12713    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
12714 
12715    v = ast_variable_browse(cfg, "channels");
12716    res = process_zap(&conf, v, reload, 0);
12717    ast_mutex_unlock(&iflock);
12718    ast_config_destroy(cfg);
12719    if (res)
12720       return res;
12721    cfg = ast_config_load("users.conf");
12722    if (cfg) {
12723       char *cat;
12724       const char *chans;
12725       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
12726       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
12727          if (!strcasecmp(cat, "general"))
12728             continue;
12729          chans = ast_variable_retrieve(cfg, cat, "zapchan");
12730          if (!ast_strlen_zero(chans)) {
12731             struct zt_chan_conf sect_conf;
12732             memcpy(&sect_conf, &conf, sizeof(sect_conf));
12733 
12734             process_zap(&sect_conf, ast_variable_browse(cfg, cat), reload, 0);
12735          }
12736       }
12737       ast_config_destroy(cfg);
12738    }
12739 #ifdef HAVE_PRI
12740    if (!reload) {
12741       for (x = 0; x < NUM_SPANS; x++) {
12742          pris[x].debugfd = -1;
12743          if (pris[x].pvts[0]) {
12744             if (start_pri(pris + x)) {
12745                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
12746                return -1;
12747             } else if (option_verbose > 1)
12748                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
12749          }
12750       }
12751    }
12752 #endif
12753    /* And start the monitor for the first time */
12754    restart_monitor();
12755    return 0;
12756 }
12757 
12758 static int load_module(void)
12759 {
12760    int res;
12761 
12762 #ifdef HAVE_PRI
12763    int y,i;
12764    memset(pris, 0, sizeof(pris));
12765    for (y = 0; y < NUM_SPANS; y++) {
12766       ast_mutex_init(&pris[y].lock);
12767       pris[y].offset = -1;
12768       pris[y].master = AST_PTHREADT_NULL;
12769       for (i = 0; i < NUM_DCHANS; i++)
12770          pris[y].fds[i] = -1;
12771    }
12772    pri_set_error(zt_pri_error);
12773    pri_set_message(zt_pri_message);
12774    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
12775          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
12776 #endif
12777 #ifdef HAVE_GSMAT
12778    gsm_set_error(zt_gsm_error);
12779    gsm_set_message(zt_gsm_message);
12780 #endif
12781    res = setup_zap(0);
12782    /* Make sure we can register our Zap channel type */
12783    if (res)
12784       return AST_MODULE_LOAD_DECLINE;
12785    if (ast_channel_register(&zap_tech)) {
12786       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
12787       __unload_module();
12788       return -1;
12789    }
12790 #ifdef HAVE_PRI
12791    ast_string_field_init(&inuse, 16);
12792    ast_string_field_set(&inuse, name, "GR-303InUse");
12793    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
12794    ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc);
12795         ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc);
12796 #endif   
12797    ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
12798    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
12799 #ifdef HAVE_GSMAT
12800    ast_cli_register(&gsm_send_sms);
12801    ast_cli_register(&gsm_send_pdu);
12802    ast_cli_register(&gsm_show_status);
12803    ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
12804 #endif
12805    
12806    memset(round_robin, 0, sizeof(round_robin));
12807    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
12808    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
12809    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
12810    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
12811    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
12812    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
12813    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
12814 
12815    return res;
12816 }
12817 
12818 #ifdef HAVE_PRI
12819 static int zt_tdd_sendtext(struct ast_channel *c, const char *text);
12820 
12821 static int zt_pri_sendtext(struct ast_channel *c, const char *text) {
12822  struct zt_pvt *p = c->tech_pvt;
12823  if (!p) return -1;
12824  if (!p->pri) return -1;
12825        if (strlen(text)) {
12826       if (p->pri) {
12827           if (!pri_grab(p, p->pri)) {
12828       // ast_log(LOG_NOTICE, "Sending Display IE  '%s'\n", text);
12829          pri_information_display(p->pri->pri,p->call,(char *)text);
12830          pri_rel(p->pri);
12831              } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
12832       }
12833        }
12834  return 0;
12835 }
12836 #endif
12837 
12838 static int zt_sendtext(struct ast_channel *c, const char *text) {
12839  struct zt_pvt *p = c->tech_pvt;
12840  if (!p) return -1;
12841  if (p->sig == SIG_PRI) {
12842 #ifdef HAVE_PRI
12843    return zt_pri_sendtext(c, text);
12844 #endif
12845  } else if (p->sig == SIG_GSM) {
12846  } else {
12847    return zt_tdd_sendtext(c, text);
12848  }
12849  return -1;
12850 }
12851 
12852 static int zt_sendmessage(struct ast_channel *c, const char *dest, const char *text, int ispdu) {
12853 struct zt_pvt *p = c->tech_pvt;
12854  if (!p) return -1;
12855  if (p->sig == SIG_PRI) {
12856 #ifdef HAVE_PRI
12857    if (ispdu) {
12858        ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n");
12859        return -1;
12860    }
12861    return zt_pri_sendtext(c, text);
12862 #endif
12863  } else if (p->sig == SIG_GSM) {
12864 #ifdef HAVE_GSMAT
12865      return zt_gsm_sendtext(c, dest, text, ispdu);
12866 #endif
12867  } else {
12868    if (ispdu) {
12869        ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP channel\n");
12870        return -1;
12871    }
12872    return zt_tdd_sendtext(c, text);
12873  }
12874  return -1;
12875 }
12876 
12877 static int zt_tdd_sendtext(struct ast_channel *c, const char *text)
12878 {
12879 #define  END_SILENCE_LEN 400
12880 #define  HEADER_MS 50
12881 #define  TRAILER_MS 5
12882 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
12883 #define  ASCII_BYTES_PER_CHAR 80
12884 
12885    unsigned char *buf,*mybuf;
12886    struct zt_pvt *p = c->tech_pvt;
12887    struct pollfd fds[1];
12888    int size,res,fd,len,x;
12889    int bytes=0;
12890    /* Initial carrier (imaginary) */
12891    float cr = 1.0;
12892    float ci = 0.0;
12893    float scont = 0.0;
12894    int index;
12895 
12896 
12897    index = zt_get_index(c, p, 0);
12898    if (index < 0) {
12899       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
12900       return -1;
12901    }
12902    if (!text[0]) return(0); /* if nothing to send, dont */
12903    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
12904    if (p->mate) 
12905       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
12906    else
12907       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
12908    if (!buf)
12909       return -1;
12910    mybuf = buf;
12911    if (p->mate) {
12912       int codec = AST_LAW(p);
12913       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
12914          PUT_CLID_MARKMS;
12915       }
12916       /* Put actual message */
12917       for (x = 0; text[x]; x++) {
12918          PUT_CLID(text[x]);
12919       }
12920       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
12921          PUT_CLID_MARKMS;
12922       }
12923       len = bytes;
12924       buf = mybuf;
12925    } else {
12926       len = tdd_generate(p->tdd, buf, text);
12927       if (len < 1) {
12928          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
12929          free(mybuf);
12930          return -1;
12931       }
12932    }
12933    memset(buf + len, 0x7f, END_SILENCE_LEN);
12934    len += END_SILENCE_LEN;
12935    fd = p->subs[index].zfd;
12936    while (len) {
12937       if (ast_check_hangup(c)) {
12938          free(mybuf);
12939          return -1;
12940       }
12941       size = len;
12942       if (size > READ_SIZE)
12943          size = READ_SIZE;
12944       fds[0].fd = fd;
12945       fds[0].events = POLLOUT | POLLPRI;
12946       fds[0].revents = 0;
12947       res = poll(fds, 1, -1);
12948       if (!res) {
12949          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
12950          continue;
12951       }
12952         /* if got exception */
12953       if (fds[0].revents & POLLPRI) {
12954          ast_free(mybuf);
12955          return -1;
12956       }
12957       if (!(fds[0].revents & POLLOUT)) {
12958          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
12959          continue;
12960       }
12961       res = write(fd, buf, size);
12962       if (res != size) {
12963          if (res == -1) {
12964             free(mybuf);
12965             return -1;
12966          }
12967          if (option_debug)
12968             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
12969          break;
12970       }
12971       len -= size;
12972       buf += size;
12973    }
12974    free(mybuf);
12975    return(0);
12976 }
12977 
12978 
12979 static int reload(void)
12980 {
12981    int res = 0;
12982 
12983    res = setup_zap(1);
12984    if (res) {
12985       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
12986       return -1;
12987    }
12988    return 0;
12989 }
12990 
12991 /* This is a workaround so that menuselect displays a proper description
12992  * AST_MODULE_INFO(, , "Zapata Telephony"
12993  */
12994 
12995 #ifdef ZAPATA_PRI
12996 #define tdesc "Zapata Telephony w/PRI"
12997 #else
12998 #define tdesc "Zapata Telephony"
12999 #endif
13000 
13001 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
13002       .load = load_module,
13003       .unload = unload_module,
13004       .reload = reload,
13005           );
13006 
13007 

Generated on Thu Oct 8 21:57:25 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.8