Sat Apr 12 07:12:22 2008

Asterisk developer's documentation


chan_zap.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * 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: 94251 $")
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 #include "asterisk/devicestate.h"
00115 
00116 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00117 
00118 /*! Global jitterbuffer configuration - by default, jb is disabled */
00119 static struct ast_jb_conf default_jbconf =
00120 {
00121    .flags = 0,
00122    .max_size = -1,
00123    .resync_threshold = -1,
00124    .impl = ""
00125 };
00126 static struct ast_jb_conf global_jbconf;
00127 
00128 #if !defined(ZT_SIG_EM_E1) || (defined(HAVE_PRI) && !defined(ZT_SIG_HARDHDLC))
00129 #error "Your zaptel is too old.  Please update"
00130 #endif
00131 
00132 #ifndef ZT_TONEDETECT
00133 /* Work around older code with no tone detect */
00134 #define ZT_EVENT_DTMFDOWN 0
00135 #define ZT_EVENT_DTMFUP 0
00136 #endif
00137 
00138 /* define this to send PRI user-user information elements */
00139 #undef SUPPORT_USERUSER
00140 
00141 /*! 
00142  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00143  * the user hangs up to reset the state machine so ring works properly.
00144  * This is used to be able to support kewlstart by putting the zhone in
00145  * groundstart mode since their forward disconnect supervision is entirely
00146  * broken even though their documentation says it isn't and their support
00147  * is entirely unwilling to provide any assistance with their channel banks
00148  * even though their web site says they support their products for life.
00149  */
00150 /* #define ZHONE_HACK */
00151 
00152 /*! \note
00153  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00154  * before dialing on it.  Certain FXO interfaces always think they're out of
00155  * service with this method however.
00156  */
00157 /* #define ZAP_CHECK_HOOKSTATE */
00158 
00159 /*! \brief Typically, how many rings before we should send Caller*ID */
00160 #define DEFAULT_CIDRINGS 1
00161 
00162 #define CHANNEL_PSEUDO -12
00163 
00164 #define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
00165 
00166 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
00167 #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)) 
00168 
00169 static const char tdesc[] = "Zapata Telephony Driver"
00170 #ifdef HAVE_PRI
00171                " w/PRI"
00172 #endif
00173 ;
00174 
00175 static const char config[] = "zapata.conf";
00176 
00177 #define SIG_EM    ZT_SIG_EM
00178 #define SIG_EMWINK   (0x0100000 | ZT_SIG_EM)
00179 #define SIG_FEATD (0x0200000 | ZT_SIG_EM)
00180 #define  SIG_FEATDMF (0x0400000 | ZT_SIG_EM)
00181 #define  SIG_FEATB   (0x0800000 | ZT_SIG_EM)
00182 #define  SIG_E911 (0x1000000 | ZT_SIG_EM)
00183 #define  SIG_FEATDMF_TA (0x2000000 | ZT_SIG_EM)
00184 #define  SIG_FGC_CAMA   (0x4000000 | ZT_SIG_EM)
00185 #define  SIG_FGC_CAMAMF (0x8000000 | ZT_SIG_EM)
00186 #define SIG_FXSLS ZT_SIG_FXSLS
00187 #define SIG_FXSGS ZT_SIG_FXSGS
00188 #define SIG_FXSKS ZT_SIG_FXSKS
00189 #define SIG_FXOLS ZT_SIG_FXOLS
00190 #define SIG_FXOGS ZT_SIG_FXOGS
00191 #define SIG_FXOKS ZT_SIG_FXOKS
00192 #define SIG_PRI      ZT_SIG_CLEAR
00193 #define SIG_GSM      (0x100000 | ZT_SIG_CLEAR)
00194 #define  SIG_SF      ZT_SIG_SF
00195 #define SIG_SFWINK   (0x0100000 | ZT_SIG_SF)
00196 #define SIG_SF_FEATD (0x0200000 | ZT_SIG_SF)
00197 #define  SIG_SF_FEATDMF (0x0400000 | ZT_SIG_SF)
00198 #define  SIG_SF_FEATB   (0x0800000 | ZT_SIG_SF)
00199 #define SIG_EM_E1 ZT_SIG_EM_E1
00200 #define SIG_GR303FXOKS  (0x0100000 | ZT_SIG_FXOKS)
00201 #define SIG_GR303FXSKS  (0x0100000 | ZT_SIG_FXSKS)
00202 
00203 #define NUM_SPANS       128   /*!<"32 spans", muahahaha, us alaws like to have some more... */
00204 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00205 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00206 
00207 #define CHAN_PSEUDO  -2
00208 
00209 #define DCHAN_PROVISIONED (1 << 0)
00210 #define DCHAN_NOTINALARM  (1 << 1)
00211 #define DCHAN_UP          (1 << 2)
00212 
00213 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00214 
00215 static char defaultcic[64] = "";
00216 static char defaultozz[64] = "";
00217 
00218 static char progzone[10] = "";
00219 
00220 static int distinctiveringaftercid = 0;
00221 
00222 static int numbufs = 4;
00223 
00224 #ifdef HAVE_PRI
00225 static struct ast_channel inuse;
00226 #ifdef PRI_GETSET_TIMERS
00227 static int pritimers[PRI_MAX_TIMERS];
00228 #endif
00229 #endif
00230 
00231 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00232 static int firstdigittimeout = 16000;
00233 
00234 /*! \brief How long to wait for following digits (FXO logic) */
00235 static int gendigittimeout = 8000;
00236 
00237 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00238 static int matchdigittimeout = 3000;
00239 
00240 /*! \brief Protect the interface list (of zt_pvt's) */
00241 AST_MUTEX_DEFINE_STATIC(iflock);
00242 
00243 static char gsm_modem_pin[20];
00244 static char gsm_modem_exten[AST_MAX_EXTENSION];
00245 
00246 static int ifcount = 0;
00247 
00248 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00249    when it's doing something critical. */
00250 AST_MUTEX_DEFINE_STATIC(monlock);
00251 
00252 /*! \brief This is the thread for the monitor which checks for input on the channels
00253    which are not currently in use. */
00254 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00255 
00256 static int restart_monitor(void);
00257 
00258 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);
00259 
00260 static int zt_sendtext(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00261 
00262 
00263 /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
00264 static inline int zt_get_event(int fd)
00265 {
00266    int j;
00267    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00268       return -1;
00269    return j;
00270 }
00271 
00272 /*! \brief Avoid the silly zt_waitevent which ignores a bunch of events */
00273 static inline int zt_wait_event(int fd)
00274 {
00275    int i, j = 0;
00276    i = ZT_IOMUX_SIGEVENT;
00277    if (ioctl(fd, ZT_IOMUX, &i) == -1)
00278       return -1;
00279    if (ioctl(fd, ZT_GETEVENT, &j) == -1)
00280       return -1;
00281    return j;
00282 }
00283 
00284 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00285 #define READ_SIZE 160
00286 
00287 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00288 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00289 
00290 #define CALLWAITING_SILENT_SAMPLES  ( (300 * 8) / READ_SIZE) /*!< 300 ms */
00291 #define CALLWAITING_REPEAT_SAMPLES  ( (10000 * 8) / READ_SIZE) /*!< 300 ms */
00292 #define CIDCW_EXPIRE_SAMPLES     ( (500 * 8) / READ_SIZE) /*!< 500 ms */
00293 #define MIN_MS_SINCE_FLASH       ( (2000) )  /*!< 2000 ms */
00294 #define DEFAULT_RINGT            ( (8000 * 8) / READ_SIZE)
00295 
00296 struct zt_pvt;
00297 
00298 static int ringt_base = DEFAULT_RINGT;
00299 
00300 #ifdef HAVE_PRI
00301 
00302 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00303 #define PRI_CHANNEL(p) ((p) & 0xff)
00304 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00305 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00306 
00307 struct zt_suspended_call {
00308    ast_mutex_t lock;    /* Mutex */
00309    char msn[AST_MAX_EXTENSION];  /* the MSN to which this parked call belongs */
00310    char callid[10];        /* the callID provided by the user */
00311    int parked_at;       /* extension in the call parking context */
00312    struct zt_suspended_call *next;
00313 };
00314 
00315 struct zt_holded_call {
00316    ast_mutex_t lock;    /* Mutex */
00317    char msn[AST_MAX_EXTENSION];  /* the MSN to which this parked call belongs */
00318    char uniqueid[AST_MAX_EXTENSION];   /* unique id of the onhold channel */
00319    int tei;
00320    int cref;
00321    int alreadyhungup;
00322    struct ast_channel *channel;
00323    struct ast_channel *bridge;
00324    q931_call *call;  /* this also covers tei mumbojumbo */
00325    struct zt_holded_call *next;
00326 };
00327 
00328 struct zt_pri {
00329    pthread_t master;                /*!< Thread of master */
00330    ast_mutex_t lock;                /*!< Mutex */
00331    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00332    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00333    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00334    int minunused;                   /*!< Min # of channels to keep empty */
00335    int minidle;                     /*!< Min # of "idling" calls to keep active */
00336    int nodetype;                    /*!< Node type */
00337    int switchtype;                     /*!< Type of switch to emulate */
00338    int nsf;                   /*!< Network-Specific Facilities */
00339    int dialplan;                    /*!< Dialing plan */
00340    int localdialplan;                  /*!< Local dialing plan */
00341    char nocid[AST_MAX_EXTENSION];               /*!< CallerID string to use if none provided */
00342    char withheldcid[AST_MAX_EXTENSION];            /*!< CallerID string to use if CallerID is withheld */
00343    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00344    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00345    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00346    char privateprefix[20];                /*!< for private dialplans */
00347    char unknownprefix[20];                /*!< for unknown dialplans */
00348    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00349    int trunkgroup;                     /*!< What our trunkgroup is */
00350    int mastertrunkgroup;                  /*!< What trunk group is our master */
00351    int prilogicalspan;                 /*!< Logical span number within trunk group */
00352    int numchans;                    /*!< Num of channels we represent */
00353    int overlapdial;                 /*!< In overlap dialing mode */
00354    int usercid;
00355    int facilityenable;                 /*!< Enable facility IEs */
00356    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00357    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00358    struct pri *pri;                 /*!< Currently active D-channel */
00359    int debug;
00360    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00361    int offset;
00362    int span;
00363    int resetting;
00364    int resetpos;
00365    time_t lastreset;                /*!< time when unused channels were last reset */
00366    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00367    struct zt_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00368    struct zt_pvt *crvs;                /*!< Member CRV structs */
00369    struct zt_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00370    struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
00371    struct zt_holded_call *holded_calls; /* Calls on hold */
00372    int debugfd;
00373 };
00374 
00375 #ifdef HAVE_GSMAT
00376 struct zt_gsm {
00377    pthread_t master;
00378    ast_mutex_t lock;    /* Mutex */
00379    int fd;
00380    int span;
00381    struct gsm_modul *modul;
00382    char pin[256];
00383    int available;
00384    char exten[AST_MAX_EXTENSION];      /* Where to idle extra calls */
00385    struct zt_pvt *pvt;
00386 };
00387 #endif
00388 
00389 static struct zt_pri pris[NUM_SPANS];
00390 
00391 #if 0
00392 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00393 #else
00394 #define DEFAULT_PRI_DEBUG 0
00395 #endif
00396 
00397 static inline void pri_rel(struct zt_pri *pri)
00398 {
00399    ast_mutex_unlock(&pri->lock);
00400 }
00401 
00402 #else
00403 /*! Shut up the compiler */
00404 struct zt_pri;
00405 #endif
00406 
00407 #define SUB_REAL  0        /*!< Active call */
00408 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00409 #define SUB_THREEWAY 2        /*!< Three-way call */
00410 
00411 /* Polarity states */
00412 #define POLARITY_IDLE   0
00413 #define POLARITY_REV    1
00414 
00415 
00416 
00417 static struct zt_distRings drings;
00418 
00419 struct distRingData {
00420    int ring[3];
00421 };
00422 struct ringContextData {
00423    char contextData[AST_MAX_CONTEXT];
00424 };
00425 struct zt_distRings {
00426    struct distRingData ringnum[3];
00427    struct ringContextData ringContext[3];
00428 };
00429 
00430 static char *subnames[] = {
00431    "Real",
00432    "Callwait",
00433    "Threeway"
00434 };
00435 
00436 struct zt_subchannel {
00437    int zfd;
00438    struct ast_channel *owner;
00439    int chan;
00440    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00441    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00442    unsigned int needringing:1;
00443    unsigned int needbusy:1;
00444    unsigned int needcongestion:1;
00445    unsigned int needcallerid:1;
00446    unsigned int needanswer:1;
00447    unsigned int needflash:1;
00448    unsigned int needhold:1;
00449    unsigned int needunhold:1;
00450    unsigned int linear:1;
00451    unsigned int inthreeway:1;
00452    ZT_CONFINFO curconf;
00453 };
00454 
00455 #define CONF_USER_REAL     (1 << 0)
00456 #define CONF_USER_THIRDCALL   (1 << 1)
00457 
00458 #define MAX_SLAVES   4
00459 
00460 static struct zt_pvt {
00461    ast_mutex_t lock;
00462    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00463                      /*!< Up to three channels can be associated with this call */
00464       
00465    struct zt_subchannel sub_unused;    /*!< Just a safety precaution */
00466    struct zt_subchannel subs[3];       /*!< Sub-channels */
00467    struct zt_confinfo saveconf;        /*!< Saved conference info */
00468 
00469    struct zt_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00470    struct zt_pvt *master;           /*!< Master to us (we follow their conferencing) */
00471    int inconference;          /*!< If our real should be in the conference */
00472    
00473    int sig;             /*!< Signalling style */
00474    int radio;              /*!< radio type */
00475    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00476    int oprmode;               /*!< "Operator Services" mode */
00477    struct zt_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00478    float rxgain;
00479    float txgain;
00480    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00481    struct zt_pvt *next;          /*!< Next channel in list */
00482    struct zt_pvt *prev;          /*!< Prev channel in list */
00483 
00484    /* flags */
00485    unsigned int adsi:1;
00486    unsigned int answeronpolarityswitch:1;
00487    unsigned int busydetect:1;
00488    unsigned int callreturn:1;
00489    unsigned int callwaiting:1;
00490    unsigned int callwaitingcallerid:1;
00491    unsigned int cancallforward:1;
00492    unsigned int canpark:1;
00493    unsigned int confirmanswer:1;       /*!< Wait for '#' to confirm answer */
00494    unsigned int destroy:1;
00495    unsigned int didtdd:1;           /*!< flag to say its done it once */
00496    unsigned int dialednone:1;
00497    unsigned int dialing:1;
00498    unsigned int digital:1;
00499    unsigned int dnd:1;
00500    unsigned int echobreak:1;
00501    unsigned int echocanbridged:1;
00502    unsigned int echocanon:1;
00503    unsigned int faxhandled:1;       /*!< Has a fax tone already been handled? */
00504                      /*!< KPJ: i will abuse this flag to implement a zapata option for dialing out
00505                          on a zap channel with EC to be off no matter what happens. */
00506    unsigned int firstradio:1;
00507    unsigned int hanguponpolarityswitch:1;
00508    unsigned int hardwaredtmf:1;
00509    unsigned int hidecallerid:1;
00510    unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
00511    unsigned int ignoredtmf:1;
00512    unsigned int immediate:1;        /*!< Answer before getting digits? */
00513    unsigned int inalarm:1;
00514    unsigned int mate:1;          /*!< flag to say its in MATE mode */
00515    unsigned int outgoing:1;
00516    unsigned int overlapdial:1;
00517    unsigned int permcallwaiting:1;
00518    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00519    unsigned int priindication_oob:2;
00520    unsigned int pritransfer:2;
00521    unsigned int priexclusive:1;
00522    unsigned int pulse:1;
00523    unsigned int pulsedial:1;        /*!< whether a pulse dial phone is detected */
00524    unsigned int restrictcid:1;         /*!< Whether restrict the callerid -> only send ANI */
00525    unsigned int threewaycalling:1;
00526    unsigned int transfer:1;
00527    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00528    unsigned int use_callingpres:1;        /*!< Whether to use the callingpres the calling switch sends */
00529    unsigned int usedistinctiveringdetection:1;
00530    unsigned int zaptrcallerid:1;       /*!< should we use the callerid from incoming call on zap transfer or not */
00531    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00532 #if defined(HAVE_PRI)
00533    unsigned int alerting:1;
00534    unsigned int alreadyhungup:1;
00535    unsigned int isidlecall:1;
00536    unsigned int proceeding:1;
00537    unsigned int progress:1;
00538    unsigned int resetting:1;
00539    unsigned int setup_ack:1;
00540 #endif
00541    unsigned int use_smdi:1;      /* Whether to use SMDI on this channel */
00542    struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
00543 
00544    struct zt_distRings drings;
00545 
00546    char context[AST_MAX_CONTEXT];
00547    char defcontext[AST_MAX_CONTEXT];
00548    char exten[AST_MAX_EXTENSION];
00549    char language[MAX_LANGUAGE];
00550    char mohinterpret[MAX_MUSICCLASS];
00551    char mohsuggest[MAX_MUSICCLASS];
00552 #ifdef PRI_ANI
00553    char cid_ani[AST_MAX_EXTENSION];
00554 #endif
00555    char cid_num[AST_MAX_EXTENSION];
00556    int cid_ton;               /*!< Type Of Number (TON) */
00557    int cid_pres;              /*!< Calling Presentation */
00558    char cid_name[AST_MAX_EXTENSION];
00559    char lastcid_num[AST_MAX_EXTENSION];
00560    char lastcid_name[AST_MAX_EXTENSION];
00561    char *origcid_num;            /*!< malloced original callerid */
00562    char *origcid_name;           /*!< malloced original callerid */
00563    char callwait_num[AST_MAX_EXTENSION];
00564    char callwait_name[AST_MAX_EXTENSION];
00565    char rdnis[AST_MAX_EXTENSION];
00566    char dnid[AST_MAX_EXTENSION];
00567    ast_group_t group;
00568    int law;
00569    int confno;             /*!< Our conference */
00570    int confusers;             /*!< Who is using our conference */
00571    int propconfno;               /*!< Propagated conference number */
00572    ast_group_t callgroup;
00573    ast_group_t pickupgroup;
00574    int channel;               /*!< Channel Number or CRV */
00575    int span;               /*!< Span number */
00576    time_t guardtime;          /*!< Must wait this much time before using for new call */
00577    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00578    int cid_start;             /*!< CID start indicator, polarity or ring */
00579    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00580    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00581    int cidcwexpire;           /*!< When to expire our muting for CID/CW */
00582    unsigned char *cidspill;
00583    int cidpos;
00584    int cidlen;
00585    int ringt;
00586    int ringt_base;
00587    int stripmsd;
00588    int callwaitcas;
00589    int callwaitrings;
00590    int echocancel;
00591    int echotraining;
00592    char echorest[20];
00593    int busycount;
00594    int busy_tonelength;
00595    int busy_quietlength;
00596    int callprogress;
00597    struct timeval flashtime;        /*!< Last flash-hook time */
00598    struct ast_dsp *dsp;
00599    int cref;               /*!< Call reference number */
00600    ZT_DIAL_OPERATION dop;
00601    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00602    char finaldial[64];
00603    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00604    int amaflags;              /*!< AMA Flags */
00605    struct tdd_state *tdd;           /*!< TDD flag */
00606    char call_forward[AST_MAX_EXTENSION];
00607    char mailbox[AST_MAX_EXTENSION];
00608    char dialdest[256];
00609    int onhooktime;
00610    int msgstate;
00611    int distinctivering;          /*!< Which distinctivering to use */
00612    int cidrings;              /*!< Which ring to deliver CID on */
00613    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00614    int fake_event;
00615    int polarityonanswerdelay;
00616    struct timeval polaritydelaytv;
00617    int sendcalleridafter;
00618 #ifdef HAVE_PRI
00619    struct zt_pri *pri;
00620    struct zt_pvt *bearer;
00621    struct zt_pvt *realcall;
00622    q931_call *call;
00623    int tei;             /* channel in use by this tei */
00624    q931_call *holdedcall;
00625    int prioffset;
00626    int logicalspan;
00627 #endif   
00628 #ifdef HAVE_GSMAT
00629    struct zt_gsm gsm;
00630 #endif
00631    int polarity;
00632    int dsp_features;
00633    char begindigit;
00634 } *iflist = NULL, *ifend = NULL;
00635 
00636 /*! \brief Channel configuration from zapata.conf .
00637  * This struct is used for parsing the [channels] section of zapata.conf.
00638  * Generally there is a field here for every possible configuration item.
00639  *
00640  * The state of fields is saved along the parsing and whenever a 'channel'
00641  * statement is reached, the current zt_chan_conf is used to configure the 
00642  * channel (struct zt_pvt)
00643  *
00644  * @seealso zt_chan_init for the default values.
00645  */
00646 struct zt_chan_conf {
00647    struct zt_pvt chan;
00648 #ifdef HAVE_PRI
00649    struct zt_pri pri;
00650 #endif
00651    ZT_PARAMS timing;
00652 
00653    char smdi_port[SMDI_MAX_FILENAME_LEN];
00654 };
00655 
00656 /** returns a new zt_chan_conf with default values (by-value) */
00657 static struct zt_chan_conf zt_chan_conf_default(void) {
00658    /* recall that if a field is not included here it is initialized
00659     * to 0 or equivalent
00660     */
00661    struct zt_chan_conf conf = {
00662 #ifdef HAVE_PRI
00663       .pri = {
00664          .nsf = PRI_NSF_NONE,
00665          .switchtype = PRI_SWITCH_NI2,
00666          .dialplan = PRI_NATIONAL_ISDN + 1,
00667          .localdialplan = PRI_NATIONAL_ISDN + 1,
00668          .nodetype = PRI_CPE,
00669 
00670          .minunused = 2,
00671          .idleext = "",
00672          .idledial = "",
00673          .nocid = "No CID available",
00674          .withheldcid = "CID withheld",
00675          .internationalprefix = "",
00676          .nationalprefix = "",
00677          .localprefix = "",
00678          .privateprefix = "",
00679          .unknownprefix = "",
00680          .usercid = 0,
00681 
00682          .resetinterval = 3600
00683       },
00684 #endif
00685       .chan = {
00686          .context = "default",
00687          .cid_num = "",
00688          .cid_name = "",
00689          .mohinterpret = "default",
00690          .mohsuggest = "",
00691          .transfertobusy = 1,
00692          .priindication_oob = 0,
00693          .pritransfer = 0,
00694 
00695          .cid_signalling = CID_SIG_BELL,
00696          .cid_start = CID_START_RING,
00697          .zaptrcallerid = 0,
00698          .use_callerid = 1,
00699          .sig = -1,
00700          .outsigmod = -1,
00701 
00702          .tonezone = -1,
00703 
00704          .echocancel = 1,
00705 
00706          .busycount = 3,
00707 
00708          .accountcode = "",
00709 
00710          .mailbox = "",
00711 
00712 
00713          .polarityonanswerdelay = 600,
00714 
00715          .sendcalleridafter = DEFAULT_CIDRINGS
00716       },
00717       .timing = {
00718          .prewinktime = -1,
00719          .preflashtime = -1,
00720          .winktime = -1,
00721          .flashtime = -1,
00722          .starttime = -1,
00723          .rxwinktime = -1,
00724          .rxflashtime = -1,
00725          .debouncetime = -1
00726       },
00727       .smdi_port = "/dev/ttyS0",
00728    };
00729 
00730    return conf;
00731 }
00732 
00733 
00734 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
00735 static int zt_digit_begin(struct ast_channel *ast, char digit);
00736 static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
00737 static int zt_sendtext(struct ast_channel *c, const char *dest, const char *text, int ispdu);
00738 static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
00739 static int zt_hangup(struct ast_channel *ast);
00740 static int zt_answer(struct ast_channel *ast);
00741 static struct ast_frame *zt_read(struct ast_channel *ast);
00742 static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
00743 static struct ast_frame *zt_exception(struct ast_channel *ast);
00744 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
00745 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
00746 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
00747 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
00748 static void enable_dtmf_detect(struct zt_pvt *p);
00749 static void disable_dtmf_detect(struct zt_pvt *p);
00750 
00751 static const struct ast_channel_tech zap_tech = {
00752    .type = "Zap",
00753    .description = tdesc,
00754    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
00755    .requester = zt_request,
00756    .send_digit_begin = zt_digit_begin,
00757    .send_digit_end = zt_digit_end,
00758    .send_text = zt_sendtext,
00759    .call = zt_call,
00760    .hangup = zt_hangup,
00761    .answer = zt_answer,
00762    .read = zt_read,
00763    .write = zt_write,
00764    .bridge = zt_bridge,
00765    .exception = zt_exception,
00766    .indicate = zt_indicate,
00767    .fixup = zt_fixup,
00768    .setoption = zt_setoption,
00769    .func_channel_read = zt_func_read,
00770 /* .devicestate = zt_devicestate, */
00771 };
00772 
00773 #ifdef HAVE_PRI
00774 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
00775 #else
00776 #define GET_CHANNEL(p) ((p)->channel)
00777 #endif
00778 
00779 struct zt_pvt *round_robin[32];
00780 
00781 #ifdef HAVE_PRI
00782 struct app_tmp {
00783    char app[256];
00784    char data[256];
00785    struct ast_channel *chan;
00786    pthread_t t;
00787 };
00788 
00789 static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
00790 {
00791    int res;
00792    /* Grab the lock first */
00793    do {
00794       res = ast_mutex_trylock(&pri->lock);
00795       if (res) {
00796          ast_mutex_unlock(&pvt->lock);
00797          /* Release the lock and try again */
00798          usleep(1);
00799          ast_mutex_lock(&pvt->lock);
00800       }
00801    } while (res);
00802    /* Then break the poll */
00803    pthread_kill(pri->master, SIGURG);
00804    return 0;
00805 }
00806 #endif
00807 
00808 #define NUM_CADENCE_MAX 25
00809 static int num_cadence = 4;
00810 static int user_has_defined_cadences = 0;
00811 
00812 static struct zt_ring_cadence cadences[NUM_CADENCE_MAX] = {
00813    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
00814    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
00815    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
00816    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
00817 };
00818 
00819 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
00820  * is 1, the second pause is 2 and so on.
00821  */
00822 
00823 static int cidrings[NUM_CADENCE_MAX] = {
00824    2,                            /*!< Right after first long ring */
00825    4,                            /*!< Right after long part */
00826    3,                            /*!< After third chirp */
00827    2,                            /*!< Second spell */
00828 };
00829 
00830 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
00831          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
00832 
00833 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00834 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __ZT_SIG_FXO) */)
00835 
00836 static int zt_devicestate(void *data)
00837 {
00838    int groupmatch = 0;
00839    int channelmatch = 0;
00840    struct zt_pvt *p;
00841    char *dest=NULL;
00842    int x;
00843    char *s;
00844    char opt=0;
00845    int res, y=0;
00846    struct zt_pvt *exit, *start, *end;
00847    ast_mutex_t *lock;
00848 
00849 // ast_log(LOG_NOTICE, "data = %s\n", (char *)data);
00850    return AST_DEVICE_UNKNOWN;
00851    
00852    /* Assume we're locking the iflock */
00853    lock = &iflock;
00854    start = iflist;
00855    end = ifend;
00856 
00857    if (data) {
00858       dest = ast_strdupa((char *)data);
00859    } else {
00860       ast_log(LOG_WARNING, "Channel requested with no data\n");
00861       return AST_DEVICE_INVALID;
00862    }
00863    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
00864       /* Retrieve the group number */
00865       char *stringp=NULL;
00866       stringp=dest + 1;
00867       s = strsep(&stringp, "/");
00868       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
00869          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
00870          return AST_DEVICE_INVALID;
00871       }
00872       groupmatch = 1 << x;
00873    } else {
00874       char *stringp=NULL;
00875       stringp=dest;
00876       s = strsep(&stringp, "/");
00877       p = iflist;
00878       if (!strcasecmp(s, "pseudo")) {
00879          /* Special case for pseudo */
00880          x = CHAN_PSEUDO;
00881          channelmatch = x;
00882          /* bail out */
00883          return AST_DEVICE_INVALID;
00884       } 
00885 
00886       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
00887          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
00888          return AST_DEVICE_INVALID;
00889       } else {
00890          channelmatch = x;
00891          ast_log(LOG_NOTICE, "channelmatch = %d\n", channelmatch);
00892       }
00893    }
00894    /* Search for an unowned channel */
00895    if (ast_mutex_lock(lock)) {
00896       ast_log(LOG_ERROR, "Unable to lock interface list???\n");
00897       return AST_DEVICE_INVALID;
00898    }
00899    p = iflist;
00900    exit = iflist;
00901    res = AST_DEVICE_INVALID; /* start pessimistic */
00902    while(p) {
00903       if (p) {
00904           ast_mutex_lock(&p->lock);
00905           if ((groupmatch && ((p->group & groupmatch) != 0)) || (channelmatch && (p->channel == channelmatch))) {
00906 #ifdef ZAPATA_PRI
00907          if (p->pri) {
00908              for(d=0;d<NUM_DCHANS;d++) {
00909             if (p->pri->dchanavail[d] & DCHAN_UP) {
00910                    res = AST_DEVICE_UNKNOWN;
00911             }
00912              }
00913          }
00914 #endif
00915          if ((!ast_strlen_zero(p->cid_num) && (strncasecmp(p->cid_num, dest, strlen(p->cid_num)))) || (!ast_strlen_zero(p->dnid) && (strncasecmp(p->dnid, dest, strlen(p->dnid))))) {
00916              res = AST_DEVICE_UNKNOWN;
00917              if (p->owner) {
00918                 if ((p->owner->_state == AST_STATE_RINGING) && (p->outgoing)) {
00919                   res = AST_DEVICE_RINGING;
00920                 }
00921                 if (((p->owner->_state == AST_STATE_RINGING) && (!p->outgoing)) || (p->owner->_state == AST_STATE_UP) || (p->owner->_state == AST_STATE_DIALING) || (p->owner->_state == AST_STATE_RESERVED) || (p->owner->_state == AST_STATE_RING)){
00922                   res = AST_DEVICE_INUSE;
00923                 }
00924              }
00925              if ((res == AST_DEVICE_INUSE) || (res == AST_DEVICE_RINGING)) {
00926             /* stop searching now, one non-idle channel is sufficient */
00927             ast_mutex_unlock(&p->lock);
00928             break;
00929              }
00930          }
00931           }
00932           ast_mutex_unlock(&p->lock);
00933       }  
00934       p = p->next;
00935    }
00936    ast_mutex_unlock(lock);
00937 
00938    return res;
00939 
00940 }
00941 
00942 static int zt_get_index(struct ast_channel *ast, struct zt_pvt *p, int nullok)
00943 {
00944    int res;
00945    if (p->subs[0].owner == ast)
00946       res = 0;
00947    else if (p->subs[1].owner == ast)
00948       res = 1;
00949    else if (p->subs[2].owner == ast)
00950       res = 2;
00951    else {
00952       res = -1;
00953       if (!nullok)
00954          ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
00955    }
00956    return res;
00957 }
00958 
00959 #ifdef HAVE_PRI
00960 static void wakeup_sub(struct zt_pvt *p, int a, struct zt_pri *pri)
00961 #else
00962 static void wakeup_sub(struct zt_pvt *p, int a, void *pri)
00963 #endif
00964 {
00965 #ifdef HAVE_PRI
00966    if (pri)
00967       ast_mutex_unlock(&pri->lock);
00968 #endif         
00969    for (;;) {
00970       if (p->subs[a].owner) {
00971          if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
00972             ast_mutex_unlock(&p->lock);
00973             usleep(1);
00974             ast_mutex_lock(&p->lock);
00975          } else {
00976             ast_queue_frame(p->subs[a].owner, &ast_null_frame);
00977             ast_mutex_unlock(&p->subs[a].owner->lock);
00978             break;
00979          }
00980       } else
00981          break;
00982    }
00983 #ifdef HAVE_PRI
00984    if (pri)
00985       ast_mutex_lock(&pri->lock);
00986 #endif         
00987 }
00988 
00989 #ifdef HAVE_PRI
00990 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, struct zt_pri *pri)
00991 #else
00992 static void zap_queue_frame(struct zt_pvt *p, struct ast_frame *f, void *pri)
00993 #endif
00994 {
00995    /* We must unlock the PRI to avoid the possibility of a deadlock */
00996 #ifdef HAVE_PRI
00997    if (pri)
00998       ast_mutex_unlock(&pri->lock);
00999 #endif      
01000    for (;;) {
01001       if (p->owner) {
01002          if (ast_mutex_trylock(&p->owner->lock)) {
01003             ast_mutex_unlock(&p->lock);
01004             usleep(1);
01005             ast_mutex_lock(&p->lock);
01006          } else {
01007             ast_queue_frame(p->owner, f);
01008             ast_mutex_unlock(&p->owner->lock);
01009             break;
01010          }
01011       } else
01012          break;
01013    }
01014 #ifdef HAVE_PRI
01015    if (pri)
01016       ast_mutex_lock(&pri->lock);
01017 #endif      
01018 }
01019 
01020 static int restore_gains(struct zt_pvt *p);
01021 
01022 static void swap_subs(struct zt_pvt *p, int a, int b)
01023 {
01024    int tchan;
01025    int tinthreeway;
01026    struct ast_channel *towner;
01027 
01028    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
01029 
01030    tchan = p->subs[a].chan;
01031    towner = p->subs[a].owner;
01032    tinthreeway = p->subs[a].inthreeway;
01033 
01034    p->subs[a].chan = p->subs[b].chan;
01035    p->subs[a].owner = p->subs[b].owner;
01036    p->subs[a].inthreeway = p->subs[b].inthreeway;
01037 
01038    p->subs[b].chan = tchan;
01039    p->subs[b].owner = towner;
01040    p->subs[b].inthreeway = tinthreeway;
01041 
01042    if (p->subs[a].owner) 
01043       p->subs[a].owner->fds[0] = p->subs[a].zfd;
01044    if (p->subs[b].owner) 
01045       p->subs[b].owner->fds[0] = p->subs[b].zfd;
01046    wakeup_sub(p, a, NULL);
01047    wakeup_sub(p, b, NULL);
01048 }
01049 
01050 static int zt_open(char *fn)
01051 {
01052    int fd;
01053    int isnum;
01054    int chan = 0;
01055    int bs;
01056    int x;
01057    isnum = 1;
01058    for (x = 0; x < strlen(fn); x++) {
01059       if (!isdigit(fn[x])) {
01060          isnum = 0;
01061          break;
01062       }
01063    }
01064    if (isnum) {
01065       chan = atoi(fn);
01066       if (chan < 1) {
01067          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
01068          return -1;
01069       }
01070       fn = "/dev/zap/channel";
01071    }
01072    fd = open(fn, O_RDWR | O_NONBLOCK);
01073    if (fd < 0) {
01074       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
01075       return -1;
01076    }
01077    if (chan) {
01078       if (ioctl(fd, ZT_SPECIFY, &chan)) {
01079          x = errno;
01080          close(fd);
01081          errno = x;
01082          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
01083          return -1;
01084       }
01085    }
01086    bs = READ_SIZE;
01087    if (ioctl(fd, ZT_SET_BLOCKSIZE, &bs) == -1) {
01088       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
01089       x = errno;
01090       close(fd);
01091       errno = x;
01092       return -1;
01093    }
01094    return fd;
01095 }
01096 
01097 static void zt_close(int fd)
01098 {
01099    if (fd > 0)
01100       close(fd);
01101 }
01102 
01103 static int zt_setlinear(int zfd, int linear)
01104 {
01105    int res;
01106    res = ioctl(zfd, ZT_SETLINEAR, &linear);
01107    if (res)
01108       return res;
01109    return 0;
01110 }
01111 
01112 
01113 static int alloc_sub(struct zt_pvt *p, int x)
01114 {
01115    ZT_BUFFERINFO bi;
01116    int res;
01117    if (p->subs[x].zfd < 0) {
01118       p->subs[x].zfd = zt_open("/dev/zap/pseudo");
01119       if (p->subs[x].zfd > -1) {
01120          res = ioctl(p->subs[x].zfd, ZT_GET_BUFINFO, &bi);
01121          if (!res) {
01122             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
01123             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
01124             bi.numbufs = numbufs;
01125             res = ioctl(p->subs[x].zfd, ZT_SET_BUFINFO, &bi);
01126             if (res < 0) {
01127                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
01128             }
01129          } else 
01130             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
01131          if (ioctl(p->subs[x].zfd, ZT_CHANNO, &p->subs[x].chan) == 1) {
01132             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d\n", p->subs[x].zfd);
01133             zt_close(p->subs[x].zfd);
01134             p->subs[x].zfd = -1;
01135             return -1;
01136          }
01137          if (option_debug)
01138             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].zfd, p->subs[x].chan);
01139          return 0;
01140       } else
01141          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01142       return -1;
01143    }
01144    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01145    return -1;
01146 }
01147 
01148 static int unalloc_sub(struct zt_pvt *p, int x)
01149 {
01150    if (!x) {
01151       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01152       return -1;
01153    }
01154    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01155    if (p->subs[x].zfd > -1) {
01156       zt_close(p->subs[x].zfd);
01157    }
01158    p->subs[x].zfd = -1;
01159    p->subs[x].linear = 0;
01160    p->subs[x].chan = 0;
01161    p->subs[x].owner = NULL;
01162    p->subs[x].inthreeway = 0;
01163    p->polarity = POLARITY_IDLE;
01164    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01165    return 0;
01166 }
01167 
01168 static int digit_to_dtmfindex(char digit)
01169 {
01170    if (isdigit(digit))
01171       return ZT_TONE_DTMF_BASE + (digit - '0');
01172    else if (digit >= 'A' && digit <= 'D')
01173       return ZT_TONE_DTMF_A + (digit - 'A');
01174    else if (digit >= 'a' && digit <= 'd')
01175       return ZT_TONE_DTMF_A + (digit - 'a');
01176    else if (digit == '*')
01177       return ZT_TONE_DTMF_s;
01178    else if (digit == '#')
01179       return ZT_TONE_DTMF_p;
01180    else
01181       return -1;
01182 }
01183 
01184 static int zt_digit_begin(struct ast_channel *chan, char digit)
01185 {
01186    struct zt_pvt *pvt;
01187    int index;
01188    int dtmf = -1;
01189    
01190    pvt = chan->tech_pvt;
01191 
01192    ast_mutex_lock(&pvt->lock);
01193 
01194    index = zt_get_index(chan, pvt, 0);
01195 
01196    if ((index != SUB_REAL) || !pvt->owner)
01197       goto out;
01198 
01199 #ifdef HAVE_PRI
01200    if ((pvt->sig == SIG_PRI) && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
01201       if (pvt->setup_ack) {
01202          if (!pri_grab(pvt, pvt->pri)) {
01203             pri_information(pvt->pri->pri, pvt->call, digit);
01204             pri_rel(pvt->pri);
01205          } else
01206             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01207       } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
01208          int res;
01209          ast_log(LOG_DEBUG, "Queueing digit '%c' since setup_ack not yet received\n", digit);
01210          res = strlen(pvt->dialdest);
01211          pvt->dialdest[res++] = digit;
01212          pvt->dialdest[res] = '\0';
01213       }
01214       goto out;
01215    }
01216 #endif
01217    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01218       goto out;
01219 
01220    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &dtmf)) {
01221       int res;
01222       ZT_DIAL_OPERATION zo = {
01223          .op = ZT_DIAL_OP_APPEND,
01224          .dialstr[0] = 'T',
01225          .dialstr[1] = digit,
01226          .dialstr[2] = 0,
01227       };
01228       if ((res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_DIAL, &zo)))
01229          ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
01230       else
01231          pvt->dialing = 1;
01232    } else {
01233       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01234       pvt->dialing = 1;
01235       pvt->begindigit = digit;
01236    }
01237 
01238 out:
01239    ast_mutex_unlock(&pvt->lock);
01240 
01241    return 0;
01242 }
01243 
01244 static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01245 {
01246    struct zt_pvt *pvt;
01247    int res = 0;
01248    int index;
01249    int x;
01250    
01251    pvt = chan->tech_pvt;
01252 
01253    ast_mutex_lock(&pvt->lock);
01254    
01255    index = zt_get_index(chan, pvt, 0);
01256 
01257    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01258       goto out;
01259 
01260 #ifdef HAVE_PRI
01261    /* This means that the digit was already sent via PRI signalling */
01262    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01263       goto out;
01264 #endif
01265 
01266    if (pvt->begindigit) {
01267       x = -1;
01268       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01269       res = ioctl(pvt->subs[SUB_REAL].zfd, ZT_SENDTONE, &x);
01270       pvt->dialing = 0;
01271       pvt->begindigit = 0;
01272    }
01273 
01274 out:
01275    ast_mutex_unlock(&pvt->lock);
01276 
01277    return res;
01278 }
01279 
01280 static char *events[] = {
01281    "No event",
01282    "On hook",
01283    "Ring/Answered",
01284    "Wink/Flash",
01285    "Alarm",
01286    "No more alarm",
01287    "HDLC Abort",
01288    "HDLC Overrun",
01289    "HDLC Bad FCS",
01290    "Dial Complete",
01291    "Ringer On",
01292    "Ringer Off",
01293    "Hook Transition Complete",
01294    "Bits Changed",
01295    "Pulse Start",
01296    "Timer Expired",
01297    "Timer Ping",
01298    "Polarity Reversal",
01299    "Ring Begin",
01300 };
01301 
01302 static struct {
01303    int alarm;
01304    char *name;
01305 } alarms[] = {
01306    { ZT_ALARM_RED, "Red Alarm" },
01307    { ZT_ALARM_YELLOW, "Yellow Alarm" },
01308    { ZT_ALARM_BLUE, "Blue Alarm" },
01309    { ZT_ALARM_RECOVER, "Recovering" },
01310    { ZT_ALARM_LOOPBACK, "Loopback" },
01311    { ZT_ALARM_NOTOPEN, "Not Open" },
01312    { ZT_ALARM_NONE, "None" },
01313 };
01314 
01315 static char *alarm2str(int alarm)
01316 {
01317    int x;
01318    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01319       if (alarms[x].alarm & alarm)
01320          return alarms[x].name;
01321    }
01322    return alarm ? "Unknown Alarm" : "No Alarm";
01323 }
01324 
01325 static char *event2str(int event)
01326 {
01327    static char buf[256];
01328    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01329       return events[event];
01330    sprintf(buf, "Event %d", event); /* safe */
01331    return buf;
01332 }
01333 
01334 #ifdef HAVE_PRI
01335 static char *dialplan2str(int dialplan)
01336 {
01337    if (dialplan == -1) {
01338       return("Dynamically set dialplan in ISDN");
01339    }
01340    return (pri_plan2str(dialplan));
01341 }
01342 #endif
01343 
01344 static char *zap_sig2str(int sig)
01345 {
01346    static char buf[256];
01347    switch (sig) {
01348    case SIG_EM:
01349       return "E & M Immediate";
01350    case SIG_EMWINK:
01351       return "E & M Wink";
01352    case SIG_EM_E1:
01353       return "E & M E1";
01354    case SIG_FEATD:
01355       return "Feature Group D (DTMF)";
01356    case SIG_FEATDMF:
01357       return "Feature Group D (MF)";
01358    case SIG_FEATDMF_TA:
01359       return "Feature Groud D (MF) Tandem Access";
01360    case SIG_FEATB:
01361       return "Feature Group B (MF)";
01362    case SIG_E911:
01363       return "E911 (MF)";
01364    case SIG_FGC_CAMA:
01365       return "FGC/CAMA (Dialpulse)";
01366    case SIG_FGC_CAMAMF:
01367       return "FGC/CAMA (MF)";
01368    case SIG_FXSLS:
01369       return "FXS Loopstart";
01370    case SIG_FXSGS:
01371       return "FXS Groundstart";
01372    case SIG_FXSKS:
01373       return "FXS Kewlstart";
01374    case SIG_FXOLS:
01375       return "FXO Loopstart";
01376    case SIG_FXOGS:
01377       return "FXO Groundstart";
01378    case SIG_FXOKS:
01379       return "FXO Kewlstart";
01380    case SIG_PRI:
01381       return "ISDN PRI";
01382    case SIG_SF:
01383       return "SF (Tone) Immediate";
01384    case SIG_SFWINK:
01385       return "SF (Tone) Wink";
01386    case SIG_SF_FEATD:
01387       return "SF (Tone) with Feature Group D (DTMF)";
01388    case SIG_SF_FEATDMF:
01389       return "SF (Tone) with Feature Group D (MF)";
01390    case SIG_SF_FEATB:
01391       return "SF (Tone) with Feature Group B (MF)";
01392    case SIG_GR303FXOKS:
01393       return "GR-303 with FXOKS";
01394    case SIG_GR303FXSKS:
01395       return "GR-303 with FXSKS";
01396    case SIG_GSM:
01397       return "GSM";
01398    case 0:
01399       return "Pseudo";
01400    default:
01401       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01402       return buf;
01403    }
01404 }
01405 
01406 #define sig2str zap_sig2str
01407 
01408 static int conf_add(struct zt_pvt *p, struct zt_subchannel *c, int index, int slavechannel)
01409 {
01410    /* If the conference already exists, and we're already in it
01411       don't bother doing anything */
01412    ZT_CONFINFO zi;
01413    
01414    memset(&zi, 0, sizeof(zi));
01415    zi.chan = 0;
01416 
01417    if (slavechannel > 0) {
01418       /* If we have only one slave, do a digital mon */
01419       zi.confmode = ZT_CONF_DIGITALMON;
01420       zi.confno = slavechannel;
01421    } else {
01422       if (!index) {
01423          /* Real-side and pseudo-side both participate in conference */
01424          zi.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER |
01425             ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER;
01426       } else
01427          zi.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
01428       zi.confno = p->confno;
01429    }
01430    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01431       return 0;
01432    if (c->zfd < 0)
01433       return 0;
01434    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01435       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d\n", c->zfd, zi.confmode, zi.confno);
01436       return -1;
01437    }
01438    if (slavechannel < 1) {
01439       p->confno = zi.confno;
01440    }
01441    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01442    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01443    return 0;
01444 }
01445 
01446 static int isourconf(struct zt_pvt *p, struct zt_subchannel *c)
01447 {
01448    /* If they're listening to our channel, they're ours */  
01449    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == ZT_CONF_DIGITALMON))
01450       return 1;
01451    /* If they're a talker on our (allocated) conference, they're ours */
01452    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & ZT_CONF_TALKER))
01453       return 1;
01454    return 0;
01455 }
01456 
01457 static int conf_del(struct zt_pvt *p, struct zt_subchannel *c, int index)
01458 {
01459    ZT_CONFINFO zi;
01460    if (/* Can't delete if there's no zfd */
01461       (c->zfd < 0) ||
01462       /* Don't delete from the conference if it's not our conference */
01463       !isourconf(p, c)
01464       /* Don't delete if we don't think it's conferenced at all (implied) */
01465       ) return 0;
01466    memset(&zi, 0, sizeof(zi));
01467    zi.chan = 0;
01468    zi.confno = 0;
01469    zi.confmode = 0;
01470    if (ioctl(c->zfd, ZT_SETCONF, &zi)) {
01471       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01472       return -1;
01473    }
01474    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->zfd, c->curconf.confmode, c->curconf.confno);
01475    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01476    return 0;
01477 }
01478 
01479 static int isslavenative(struct zt_pvt *p, struct zt_pvt **out)
01480 {
01481    int x;
01482    int useslavenative;
01483    struct zt_pvt *slave = NULL;
01484    /* Start out optimistic */
01485    useslavenative = 1;
01486    /* Update conference state in a stateless fashion */
01487    for (x = 0; x < 3; x++) {
01488       /* Any three-way calling makes slave native mode *definitely* out
01489          of the question */
01490       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway)
01491          useslavenative = 0;
01492    }
01493    /* If we don't have any 3-way calls, check to see if we have
01494       precisely one slave */
01495    if (useslavenative) {
01496       for (x = 0; x < MAX_SLAVES; x++) {
01497          if (p->slaves[x]) {
01498             if (slave) {
01499                /* Whoops already have a slave!  No 
01500                   slave native and stop right away */
01501                slave = NULL;
01502                useslavenative = 0;
01503                break;
01504             } else {
01505                /* We have one slave so far */
01506                slave = p->slaves[x];
01507             }
01508          }
01509       }
01510    }
01511    /* If no slave, slave native definitely out */
01512    if (!slave)
01513       useslavenative = 0;
01514    else if (slave->law != p->law) {
01515       useslavenative = 0;
01516       slave = NULL;
01517    }
01518    if (out)
01519       *out = slave;
01520    return useslavenative;
01521 }
01522 
01523 static int reset_conf(struct zt_pvt *p)
01524 {
01525    ZT_CONFINFO zi;
01526    memset(&zi, 0, sizeof(zi));
01527    p->confno = -1;
01528    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01529    if (p->subs[SUB_REAL].zfd > -1) {
01530       if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &zi))
01531          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d!\n", p->channel);
01532    }
01533    return 0;
01534 }
01535 
01536 static int update_conf(struct zt_pvt *p)
01537 {
01538    int needconf = 0;
01539    int x;
01540    int useslavenative;
01541    struct zt_pvt *slave = NULL;
01542 
01543    useslavenative = isslavenative(p, &slave);
01544    /* Start with the obvious, general stuff */
01545    for (x = 0; x < 3; x++) {
01546       /* Look for three way calls */
01547       if ((p->subs[x].zfd > -1) && p->subs[x].inthreeway) {
01548          conf_add(p, &p->subs[x], x, 0);
01549          needconf++;
01550       } else {
01551          conf_del(p, &p->subs[x], x);
01552       }
01553    }
01554    /* If we have a slave, add him to our conference now. or DAX
01555       if this is slave native */
01556    for (x = 0; x < MAX_SLAVES; x++) {
01557       if (p->slaves[x]) {
01558          if (useslavenative)
01559             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01560          else {
01561             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01562             needconf++;
01563          }
01564       }
01565    }
01566    /* If we're supposed to be in there, do so now */
01567    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01568       if (useslavenative)
01569          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01570       else {
01571          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01572          needconf++;
01573       }
01574    }
01575    /* If we have a master, add ourselves to his conference */
01576    if (p->master) {
01577       if (isslavenative(p->master, NULL)) {
01578          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01579       } else {
01580          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01581       }
01582    }
01583    if (!needconf) {
01584       /* Nobody is left (or should be left) in our conference.
01585          Kill it. */
01586       p->confno = -1;
01587    }
01588    if (option_debug)
01589       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01590    return 0;
01591 }
01592 
01593 static void zt_enable_ec(struct zt_pvt *p)
01594 {
01595    int x;
01596    int res;
01597    if (!p)
01598       return;
01599    if (p->faxhandled)  {
01600       ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n");
01601       return;
01602    }
01603    if (p->echocanon) {
01604       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01605       return;
01606    }
01607    if (p->digital) {
01608       ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n");
01609       return;
01610    }
01611    if (p->echocancel) {
01612       if (p->sig == SIG_PRI) {
01613          x = 1;
01614          res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
01615          if (res)
01616             ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01617       }
01618       x = p->echocancel;
01619       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01620       if (res) 
01621          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
01622       else {
01623          p->echocanon = 1;
01624          if (option_debug)
01625             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01626       }
01627    } else if (option_debug)
01628       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01629 }
01630 
01631 static void zt_train_ec(struct zt_pvt *p)
01632 {
01633    int x;
01634    int res;
01635    if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) {
01636       x = p->echotraining;
01637       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
01638       if (res)
01639          ast_log(LOG_WARNING, "Unable to request echo training on channel %d\n", p->channel);
01640       else {
01641          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01642       }
01643    } else
01644       ast_log(LOG_DEBUG, "No echo training requested\n");
01645 }
01646 
01647 static void zt_disable_ec(struct zt_pvt *p)
01648 {
01649    int x;
01650    int res;
01651    if (p->echocancel) {
01652       x = 0;
01653       res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
01654       if (res)
01655          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
01656       else if (option_debug)
01657          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01658    }
01659    p->echocanon = 0;
01660 }
01661 
01662 static void fill_txgain(struct zt_gains *g, float gain, int law)
01663 {
01664    int j;
01665    int k;
01666    float linear_gain = pow(10.0, gain / 20.0);
01667 
01668    switch (law) {
01669    case ZT_LAW_ALAW:
01670       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01671          if (gain) {
01672             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01673             if (k > 32767) k = 32767;
01674             if (k < -32767) k = -32767;
01675             g->txgain[j] = AST_LIN2A(k);
01676          } else {
01677             g->txgain[j] = j;
01678          }
01679       }
01680       break;
01681    case ZT_LAW_MULAW:
01682       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01683          if (gain) {
01684             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01685             if (k > 32767) k = 32767;
01686             if (k < -32767) k = -32767;
01687             g->txgain[j] = AST_LIN2MU(k);
01688          } else {
01689             g->txgain[j] = j;
01690          }
01691       }
01692       break;
01693    }
01694 }
01695 
01696 static void fill_rxgain(struct zt_gains *g, float gain, int law)
01697 {
01698    int j;
01699    int k;
01700    float linear_gain = pow(10.0, gain / 20.0);
01701 
01702    switch (law) {
01703    case ZT_LAW_ALAW:
01704       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01705          if (gain) {
01706             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01707             if (k > 32767) k = 32767;
01708             if (k < -32767) k = -32767;
01709             g->rxgain[j] = AST_LIN2A(k);
01710          } else {
01711             g->rxgain[j] = j;
01712          }
01713       }
01714       break;
01715    case ZT_LAW_MULAW:
01716       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01717          if (gain) {
01718             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01719             if (k > 32767) k = 32767;
01720             if (k < -32767) k = -32767;
01721             g->rxgain[j] = AST_LIN2MU(k);
01722          } else {
01723             g->rxgain[j] = j;
01724          }
01725       }
01726       break;
01727    }
01728 }
01729 
01730 static int set_actual_txgain(int fd, int chan, float gain, int law)
01731 {
01732    struct zt_gains g;
01733    int res;
01734 
01735    memset(&g, 0, sizeof(g));
01736    g.chan = chan;
01737    res = ioctl(fd, ZT_GETGAINS, &g);
01738    if (res) {
01739       if (option_debug)
01740          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01741       return res;
01742    }
01743 
01744    fill_txgain(&g, gain, law);
01745 
01746    return ioctl(fd, ZT_SETGAINS, &g);
01747 }
01748 
01749 static int set_actual_rxgain(int fd, int chan, float gain, int law)
01750 {
01751    struct zt_gains g;
01752    int res;
01753 
01754    memset(&g, 0, sizeof(g));
01755    g.chan = chan;
01756    res = ioctl(fd, ZT_GETGAINS, &g);
01757    if (res) {
01758       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01759       return res;
01760    }
01761 
01762    fill_rxgain(&g, gain, law);
01763 
01764    return ioctl(fd, ZT_SETGAINS, &g);
01765 }
01766 
01767 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
01768 {
01769    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
01770 }
01771 
01772 static int bump_gains(struct zt_pvt *p)
01773 {
01774    int res;
01775 
01776    /* Bump receive gain by 5.0db */
01777    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain + 5.0, p->txgain, p->law);
01778    if (res) {
01779       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
01780       return -1;
01781    }
01782 
01783    return 0;
01784 }
01785 
01786 static int restore_gains(struct zt_pvt *p)
01787 {
01788    int res;
01789 
01790    res = set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
01791    if (res) {
01792       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
01793       return -1;
01794    }
01795 
01796    return 0;
01797 }
01798 
01799 static inline int zt_set_hook(int fd, int hs)
01800 {
01801    int x, res;
01802 
01803    x = hs;
01804    res = ioctl(fd, ZT_HOOK, &x);
01805 
01806    if (res < 0) {
01807       if (errno == EINPROGRESS)
01808          return 0;
01809       ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
01810    }
01811 
01812    return res;
01813 }
01814 
01815 static inline int zt_confmute(struct zt_pvt *p, int muted)
01816 {
01817    int x, y, res;
01818    x = muted;
01819    if ((p->sig == SIG_PRI) || (p->sig == SIG_GSM)) {
01820       y = 1;
01821       res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &y);
01822       if (res)
01823          ast_log(LOG_WARNING, "Unable to set audio mode on '%d'\n", p->channel);
01824    }
01825    res = ioctl(p->subs[SUB_REAL].zfd, ZT_CONFMUTE, &x);
01826    if (res < 0)
01827       ast_log(LOG_WARNING, "zt confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
01828    return res;
01829 }
01830 
01831 static int save_conference(struct zt_pvt *p)
01832 {
01833    struct zt_confinfo c;
01834    int res;
01835    if (p->saveconf.confmode) {
01836       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
01837       return -1;
01838    }
01839    p->saveconf.chan = 0;
01840    res = ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &p->saveconf);
01841    if (res) {
01842       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
01843       p->saveconf.confmode = 0;
01844       return -1;
01845    }
01846    c.chan = 0;
01847    c.confno = 0;
01848    c.confmode = ZT_CONF_NORMAL;
01849    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &c);
01850    if (res) {
01851       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
01852       return -1;
01853    }
01854    if (option_debug)
01855       ast_log(LOG_DEBUG, "Disabled conferencing\n");
01856    return 0;
01857 }
01858 
01859 static int restore_conference(struct zt_pvt *p)
01860 {
01861    int res;
01862    if (p->saveconf.confmode) {
01863       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETCONF, &p->saveconf);
01864       p->saveconf.confmode = 0;
01865       if (res) {
01866          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
01867          return -1;
01868       }
01869    }
01870    if (option_debug)
01871       ast_log(LOG_DEBUG, "Restored conferencing\n");
01872    return 0;
01873 }
01874 
01875 static int send_callerid(struct zt_pvt *p);
01876 
01877 static int send_cwcidspill(struct zt_pvt *p)
01878 {
01879    p->callwaitcas = 0;
01880    p->cidcwexpire = 0;
01881    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
01882       return -1;
01883    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
01884    /* Make sure we account for the end */
01885    p->cidlen += READ_SIZE * 4;
01886    p->cidpos = 0;
01887    send_callerid(p);
01888    if (option_verbose > 2)
01889       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
01890    return 0;
01891 }
01892 
01893 static int has_voicemail(struct zt_pvt *p)
01894 {
01895 
01896    return ast_app_has_voicemail(p->mailbox, NULL);
01897 }
01898 
01899 static int send_callerid(struct zt_pvt *p)
01900 {
01901    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
01902    int res;
01903    /* Take out of linear mode if necessary */
01904    if (p->subs[SUB_REAL].linear) {
01905       p->subs[SUB_REAL].linear = 0;
01906       zt_setlinear(p->subs[SUB_REAL].zfd, 0);
01907    }
01908    while (p->cidpos < p->cidlen) {
01909       res = write(p->subs[SUB_REAL].zfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
01910       if (res < 0) {
01911          if (errno == EAGAIN)
01912             return 0;
01913          else {
01914             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
01915             return -1;
01916          }
01917       }
01918       if (!res)
01919          return 0;
01920       p->cidpos += res;
01921    }
01922    free(p->cidspill);
01923    p->cidspill = NULL;
01924    if (p->callwaitcas) {
01925       /* Wait for CID/CW to expire */
01926       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
01927    } else
01928       restore_conference(p);
01929    return 0;
01930 }
01931 
01932 static int zt_callwait(struct ast_channel *ast)
01933 {
01934    struct zt_pvt *p = ast->tech_pvt;
01935    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
01936    if (p->cidspill) {
01937       ast_log(LOG_WARNING, "Spill already exists?!?\n");
01938       free(p->cidspill);
01939    }
01940    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
01941       return -1;
01942    save_conference(p);
01943    /* Silence */
01944    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
01945    if (!p->callwaitrings && p->callwaitingcallerid) {
01946       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
01947       p->callwaitcas = 1;
01948       p->cidlen = 2400 + 680 + READ_SIZE * 4;
01949    } else {
01950       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
01951       p->callwaitcas = 0;
01952       p->cidlen = 2400 + READ_SIZE * 4;
01953    }
01954    p->cidpos = 0;
01955    send_callerid(p);
01956    
01957    return 0;
01958 }
01959 
01960 static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
01961 {
01962    struct zt_pvt *p = ast->tech_pvt;
01963    int x, res, index,mysig;
01964    char *c, *n, *l;
01965 #ifdef HAVE_PRI
01966    char *s = NULL;
01967 #endif
01968    char dest[256]; /* must be same length as p->dialdest */
01969    ast_mutex_lock(&p->lock);
01970    ast_copy_string(dest, rdest, sizeof(dest));
01971    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
01972    if ((ast->_state == AST_STATE_BUSY)) {
01973       p->subs[SUB_REAL].needbusy = 1;
01974       ast_mutex_unlock(&p->lock);
01975       return 0;
01976    }
01977    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
01978       ast_log(LOG_WARNING, "zt_call called on %s, neither down nor reserved\n", ast->name);
01979       ast_mutex_unlock(&p->lock);
01980       return -1;
01981    }
01982    p->dialednone = 0;
01983    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
01984    {
01985       /* Special pseudo -- automatically up */
01986       ast_setstate(ast, AST_STATE_UP); 
01987       ast_mutex_unlock(&p->lock);
01988       return 0;
01989    }
01990    x = ZT_FLUSH_READ | ZT_FLUSH_WRITE;
01991    res = ioctl(p->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
01992    if (res)
01993       ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
01994    p->outgoing = 1;
01995 
01996    if (IS_DIGITAL(ast->transfercapability)) {
01997        set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
01998    } else {
01999        set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
02000    }
02001 
02002 
02003    mysig = p->sig;
02004    if (p->outsigmod > -1)
02005       mysig = p->outsigmod;
02006 
02007    switch (mysig) {
02008    case SIG_FXOLS:
02009    case SIG_FXOGS:
02010    case SIG_FXOKS:
02011       if (p->owner == ast) {
02012          /* Normal ring, on hook */
02013          
02014          /* Don't send audio while on hook, until the call is answered */
02015          p->dialing = 1;
02016          if (p->use_callerid) {
02017             /* Generate the Caller-ID spill if desired */
02018             if (p->cidspill) {
02019                ast_log(LOG_WARNING, "cidspill already exists??\n");
02020                free(p->cidspill);
02021             }
02022             p->callwaitcas = 0;
02023             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
02024                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
02025                p->cidpos = 0;
02026                send_callerid(p);
02027             }
02028          }
02029          /* Choose proper cadence */
02030          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
02031             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, &cadences[p->distinctivering - 1]))
02032                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s'\n", p->distinctivering, ast->name);
02033             p->cidrings = cidrings[p->distinctivering - 1];
02034          } else {
02035             if (ioctl(p->subs[SUB_REAL].zfd, ZT_SETCADENCE, NULL))
02036                ast_log(LOG_WARNING, "Unable to reset default ring on '%s'\n", ast->name);
02037             p->cidrings = p->sendcalleridafter;
02038          }
02039 
02040          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
02041          c = strchr(dest, '/');
02042          if (c)
02043             c++;
02044          if (c && (strlen(c) < p->stripmsd)) {
02045             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02046             c = NULL;
02047          }
02048          if (c) {
02049             p->dop.op = ZT_DIAL_OP_REPLACE;
02050             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
02051             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
02052          } else {
02053             p->dop.dialstr[0] = '\0';
02054          }
02055          x = ZT_RING;
02056          if (ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x) && (errno != EINPROGRESS)) {
02057             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
02058             ast_mutex_unlock(&p->lock);
02059             return -1;
02060          }
02061          p->dialing = 1;
02062       } else {
02063          /* Call waiting call */
02064          p->callwaitrings = 0;
02065          if (ast->cid.cid_num)
02066             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
02067          else
02068             p->callwait_num[0] = '\0';
02069          if (ast->cid.cid_name)
02070             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
02071          else
02072             p->callwait_name[0] = '\0';
02073          /* Call waiting tone instead */
02074          if (zt_callwait(ast)) {
02075             ast_mutex_unlock(&p->lock);
02076             return -1;
02077          }
02078          /* Make ring-back */
02079          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].zfd, ZT_TONE_RINGTONE))
02080             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
02081             
02082       }
02083       n = ast->cid.cid_name;
02084       l = ast->cid.cid_num;
02085       if (l)
02086          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
02087       else
02088          p->lastcid_num[0] = '\0';
02089       if (n)
02090          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
02091       else
02092          p->lastcid_name[0] = '\0';
02093       ast_setstate(ast, AST_STATE_RINGING);
02094       index = zt_get_index(ast, p, 0);
02095       if (index > -1) {
02096          p->subs[index].needringing = 1;
02097       }
02098       break;
02099    case SIG_FXSLS:
02100    case SIG_FXSGS:
02101    case SIG_FXSKS:
02102    case SIG_EMWINK:
02103    case SIG_EM:
02104    case SIG_EM_E1:
02105    case SIG_FEATD:
02106    case SIG_FEATDMF:
02107    case SIG_E911:
02108    case SIG_FGC_CAMA:
02109    case SIG_FGC_CAMAMF:
02110    case SIG_FEATB:
02111    case SIG_SFWINK:
02112    case SIG_SF:
02113    case SIG_SF_FEATD:
02114    case SIG_SF_FEATDMF:
02115    case SIG_FEATDMF_TA:
02116    case SIG_SF_FEATB:
02117       c = strchr(dest, '/');
02118       if (c)
02119          c++;
02120       else
02121          c = "";
02122       if (strlen(c) < p->stripmsd) {
02123          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02124          ast_mutex_unlock(&p->lock);
02125          return -1;
02126       }
02127 #ifdef HAVE_PRI
02128       /* Start the trunk, if not GR-303 */
02129       if (!p->pri) {
02130 #endif
02131          x = ZT_START;
02132          res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02133          if (res < 0) {
02134             if (errno != EINPROGRESS) {
02135                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
02136                ast_mutex_unlock(&p->lock);
02137                return -1;
02138             }
02139          }
02140 #ifdef HAVE_PRI
02141       }
02142 #endif
02143       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
02144       p->dop.op = ZT_DIAL_OP_REPLACE;
02145 
02146       c += p->stripmsd;
02147 
02148       switch (mysig) {
02149       case SIG_FEATD:
02150          l = ast->cid.cid_num;
02151          if (l) 
02152             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
02153          else
02154             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
02155          break;
02156       case SIG_FEATDMF:
02157          l = ast->cid.cid_num;
02158          if (l) 
02159             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
02160          else
02161             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
02162          break;
02163       case SIG_FEATDMF_TA:
02164       {
02165          const char *cic, *ozz;
02166 
02167          /* If you have to go through a Tandem Access point you need to use this */
02168          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
02169          if (!ozz)
02170             ozz = defaultozz;
02171          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
02172          if (!cic)
02173             cic = defaultcic;
02174          if (!ozz || !cic) {
02175             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
02176             ast_mutex_unlock(&p->lock);
02177             return -1;
02178          }
02179          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
02180          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
02181          p->whichwink = 0;
02182       }
02183          break;
02184       case SIG_E911:
02185          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
02186          break;
02187       case SIG_FGC_CAMA:
02188          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02189          break;
02190       case SIG_FGC_CAMAMF:
02191       case SIG_FEATB:
02192          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02193          break;
02194       default:
02195          if (p->pulse)
02196             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02197          else
02198             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02199          break;
02200       }
02201 
02202       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02203          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02204          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02205          p->echorest[sizeof(p->echorest) - 1] = '\0';
02206          p->echobreak = 1;
02207          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02208       } else
02209          p->echobreak = 0;
02210       if (!res) {
02211          if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
02212             x = ZT_ONHOOK;
02213             ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
02214             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
02215             ast_mutex_unlock(&p->lock);
02216             return -1;
02217          }
02218       } else
02219          ast_log(LOG_DEBUG, "Deferring dialing...\n");
02220       p->dialing = 1;
02221       if (ast_strlen_zero(c))
02222          p->dialednone = 1;
02223       ast_setstate(ast, AST_STATE_DIALING);
02224       break;
02225    case 0:
02226       /* Special pseudo -- automatically up*/
02227       ast_setstate(ast, AST_STATE_UP);
02228       break;      
02229    case SIG_PRI:
02230       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02231       p->dialdest[0] = '\0';
02232       disable_dtmf_detect(p);
02233       break;
02234    case SIG_GSM:
02235 #ifdef HAVE_GSMAT
02236       if (p->gsm.modul) {
02237           c = strchr(dest, '/');
02238           if (c)
02239          c++;
02240           else
02241          c = dest;
02242           ast_mutex_lock(&p->gsm.lock);
02243           if (gsm_dial(p->gsm.modul, p->use_callingpres ? ast->cid.cid_pres : 0, c)) {
02244          ast_log(LOG_WARNING, "dialing failed on channel %d\n", p->channel);
02245          ast_mutex_unlock(&p->gsm.lock);
02246          ast_mutex_unlock(&p->lock);
02247          return -1;
02248           }
02249           ast_mutex_unlock(&p->gsm.lock);
02250       }
02251 #endif
02252       break;
02253    default:
02254       ast_log(LOG_DEBUG, "not yet implemented\n");
02255       ast_mutex_unlock(&p->lock);
02256       return -1;
02257    }
02258 #ifdef HAVE_PRI
02259    if (p->pri) {
02260       struct pri_sr *sr;
02261 #ifdef SUPPORT_USERUSER
02262       const char *useruser;
02263 #endif
02264       int pridialplan;
02265       int dp_strip;
02266       int prilocaldialplan;
02267       int ldp_strip;
02268       int exclusive;
02269       const char *rr_str;
02270       int redirect_reason;
02271 
02272       if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
02273           // pass NO audio when ringing an isdn phone
02274           p->dialing = 1;
02275           // maybe we could allow passing audio when calling a p2p PBX, but well... ;-)
02276       }
02277 
02278       c = strchr(dest, '/');
02279       if (c)
02280          c++;
02281       else
02282          c = dest;
02283 
02284       l = NULL;
02285       n = NULL;
02286 
02287       if (!p->hidecallerid) {
02288          l = ast->cid.cid_num;
02289          if (!p->hidecalleridname) {
02290             n = ast->cid.cid_name;
02291          }
02292       }
02293 
02294 
02295       if (strlen(c) < p->stripmsd) {
02296          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02297          ast_mutex_unlock(&p->lock);
02298          return -1;
02299       }
02300       strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1);
02301       if (mysig != SIG_FXSKS) {
02302          p->dop.op = ZT_DIAL_OP_REPLACE;
02303          s = strchr(c + p->stripmsd, 'w');
02304          if (s) {
02305             if (strlen(s) > 1)
02306                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02307             else
02308                p->dop.dialstr[0] = '\0';
02309             *s = '\0';
02310          } else {
02311             p->dop.dialstr[0] = '\0';
02312          }
02313       }
02314       if (pri_grab(p, p->pri)) {
02315          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02316          ast_mutex_unlock(&p->lock);
02317          return -1;
02318       }
02319       if (!(p->call = pri_new_call(p->pri->pri))) {
02320          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02321          pri_rel(p->pri);
02322          ast_mutex_unlock(&p->lock);
02323          return -1;
02324       } else {
02325       // ast_log(LOG_NOTICE, "call %d\n", p->call);
02326       }
02327       if (!(sr = pri_sr_new())) {
02328          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02329          pri_rel(p->pri);
02330          ast_mutex_unlock(&p->lock);
02331       }
02332       if (p->bearer || (mysig == SIG_FXSKS)) {
02333          if (p->bearer) {
02334             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);
02335             p->bearer->call = p->call;
02336          } else
02337             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02338          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02339       }
02340       p->digital = IS_DIGITAL(ast->transfercapability);
02341       /* Add support for exclusive override */
02342       if (p->priexclusive)
02343          exclusive = 1;
02344       else {
02345       /* otherwise, traditional behavior */
02346          if (p->pri->nodetype == PRI_NETWORK)
02347             exclusive = 0;
02348          else
02349             exclusive = 1;
02350       }
02351       
02352       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02353       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02354                (p->digital ? -1 : 
02355                   ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat);
02356       if (p->pri->facilityenable)
02357          pri_facility_enable(p->pri->pri);
02358 
02359       if (option_verbose > 2)
02360          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02361       dp_strip = 0;
02362       pridialplan = p->pri->dialplan - 1;
02363       if (pridialplan == -2) { /* compute dynamically */
02364          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02365             dp_strip = strlen(p->pri->internationalprefix);
02366             pridialplan = PRI_INTERNATIONAL_ISDN;
02367          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02368             dp_strip = strlen(p->pri->nationalprefix);
02369             pridialplan = PRI_NATIONAL_ISDN;
02370          } else {
02371             pridialplan = PRI_LOCAL_ISDN;
02372          }
02373       }
02374       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02375 
02376       ldp_strip = 0;
02377       prilocaldialplan = p->pri->localdialplan - 1;
02378       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02379          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02380             ldp_strip = strlen(p->pri->internationalprefix);
02381             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02382          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02383             ldp_strip = strlen(p->pri->nationalprefix);
02384             prilocaldialplan = PRI_NATIONAL_ISDN;
02385          } else {
02386             prilocaldialplan = PRI_LOCAL_ISDN;
02387          }
02388       }
02389       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02390          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02391       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02392          if (!strcasecmp(rr_str, "UNKNOWN"))
02393             redirect_reason = 0;
02394          else if (!strcasecmp(rr_str, "BUSY"))
02395             redirect_reason = 1;
02396          else if (!strcasecmp(rr_str, "NO_REPLY"))
02397             redirect_reason = 2;
02398          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02399             redirect_reason = 15;
02400          else
02401             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02402       } else
02403          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02404       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02405 
02406 #ifdef SUPPORT_USERUSER
02407       /* User-user info */
02408       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02409 
02410       if (useruser)
02411          pri_sr_set_useruser(sr, useruser);
02412 #endif
02413 
02414       if (pri_setup(p->pri->pri, p->call, sr)) {
02415          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02416             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02417          pri_rel(p->pri);
02418          ast_mutex_unlock(&p->lock);
02419          pri_sr_free(sr);
02420          return -1;
02421       }
02422       pri_sr_free(sr);
02423       ast_setstate(ast, AST_STATE_DIALING);
02424       pri_rel(p->pri);
02425    }
02426 #endif      
02427    ast_mutex_unlock(&p->lock);
02428    return 0;
02429 }
02430 
02431 static void destroy_zt_pvt(struct zt_pvt **pvt)
02432 {
02433    struct zt_pvt *p = *pvt;
02434    /* Remove channel from the list */
02435    if (p->prev)
02436       p->prev->next = p->next;
02437    if (p->next)
02438       p->next->prev = p->prev;
02439    if (p->use_smdi)
02440       ASTOBJ_UNREF(p->smdi_iface, ast_smdi_interface_destroy);
02441    ast_mutex_destroy(&p->lock);
02442    free(p);
02443    *pvt = NULL;
02444 }
02445 
02446 static int destroy_channel(struct zt_pvt *prev, struct zt_pvt *cur, int now)
02447 {
02448    int owned = 0;
02449    int i = 0;
02450 
02451    if (!now) {
02452       if (cur->owner) {
02453          owned = 1;
02454       }
02455 
02456       for (i = 0; i < 3; i++) {
02457          if (cur->subs[i].owner) {
02458             owned = 1;
02459          }
02460       }
02461       if (!owned) {
02462          if (prev) {
02463             prev->next = cur->next;
02464             if (prev->next)
02465                prev->next->prev = prev;
02466             else
02467                ifend = prev;
02468          } else {
02469             iflist = cur->next;
02470             if (iflist)
02471                iflist->prev = NULL;
02472             else
02473                ifend = NULL;
02474          }
02475          if (cur->subs[SUB_REAL].zfd > -1) {
02476             zt_close(cur->subs[SUB_REAL].zfd);
02477          }
02478          destroy_zt_pvt(&cur);
02479       }
02480    } else {
02481       if (prev) {
02482          prev->next = cur->next;
02483          if (prev->next)
02484             prev->next->prev = prev;
02485          else
02486             ifend = prev;
02487       } else {
02488          iflist = cur->next;
02489          if (iflist)
02490             iflist->prev = NULL;
02491          else
02492             ifend = NULL;
02493       }
02494       if (cur->subs[SUB_REAL].zfd > -1) {
02495          zt_close(cur->subs[SUB_REAL].zfd);
02496       }
02497       destroy_zt_pvt(&cur);
02498    }
02499    return 0;
02500 }
02501 
02502 #ifdef HAVE_PRI
02503 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02504 
02505 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02506 
02507 static char *zap_send_keypad_facility_descrip = 
02508 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02509 "  IE over the current channel.\n";
02510 
02511 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02512 {
02513    /* Data will be our digit string */
02514    struct zt_pvt *p;
02515    char *digits = (char *) data;
02516 
02517    if (ast_strlen_zero(digits)) {
02518       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02519       return -1;
02520    }
02521 
02522    p = (struct zt_pvt *)chan->tech_pvt;
02523 
02524    if (!p) {
02525       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02526       return -1;
02527    }
02528 
02529    ast_mutex_lock(&p->lock);
02530 
02531    if (!p->pri || !p->call) {
02532       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02533       ast_mutex_unlock(&p->lock);
02534       return -1;
02535    }
02536 
02537    if (!pri_grab(p, p->pri)) {
02538       pri_keypad_facility(p->pri->pri, p->call, digits);
02539       pri_rel(p->pri);
02540    } else {
02541       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02542       ast_mutex_unlock(&p->lock);
02543       return -1;
02544    }
02545 
02546    ast_mutex_unlock(&p->lock);
02547 
02548    return 0;
02549 }
02550 
02551 static int pri_is_up(struct zt_pri *pri)
02552 {
02553    int x;
02554    for (x = 0; x < NUM_DCHANS; x++) {
02555       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02556          return 1;
02557    }
02558    return 0;
02559 }
02560 
02561 static int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bearer)
02562 {
02563    bearer->owner = &inuse;
02564    bearer->realcall = crv;
02565    crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
02566    if (crv->subs[SUB_REAL].owner)
02567       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
02568    crv->bearer = bearer;
02569    crv->call = bearer->call;
02570    crv->pri = pri;
02571    return 0;
02572 }
02573 
02574 static char *pri_order(int level)
02575 {
02576    switch (level) {
02577    case 0:
02578       return "Primary";
02579    case 1:
02580       return "Secondary";
02581    case 2:
02582       return "Tertiary";
02583    case 3:
02584       return "Quaternary";
02585    default:
02586       return "<Unknown>";
02587    }     
02588 }
02589 
02590 /* Returns fd of the active dchan */
02591 static int pri_active_dchan_fd(struct zt_pri *pri)
02592 {
02593    int x = -1;
02594 
02595    for (x = 0; x < NUM_DCHANS; x++) {
02596       if ((pri->dchans[x] == pri->pri))
02597          break;
02598    }
02599 
02600    return pri->fds[x];
02601 }
02602 
02603 static int pri_find_dchan(struct zt_pri *pri)
02604 {
02605    int oldslot = -1;
02606    struct pri *old;
02607    int newslot = -1;
02608    int x;
02609    old = pri->pri;
02610    for (x = 0; x < NUM_DCHANS; x++) {
02611       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02612          newslot = x;
02613       if (pri->dchans[x] == old) {
02614          oldslot = x;
02615       }
02616    }
02617    if (newslot < 0) {
02618       newslot = 0;
02619       if (pri->nodetype != BRI_CPE_PTMP) {
02620           ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02621          pri->dchannels[newslot]);
02622       }
02623    }
02624    if (old && (oldslot != newslot))
02625       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02626          pri->dchannels[oldslot], pri->dchannels[newslot]);
02627    pri->pri = pri->dchans[newslot];
02628    return 0;
02629 }
02630 #endif
02631 
02632 static int zt_setlaw(int zfd, int law)
02633 {
02634    int res;
02635    res = ioctl(zfd, ZT_SETLAW, &law);
02636    if (res)
02637       return res;
02638    return 0;
02639 }
02640 
02641 
02642 static int zt_hangup(struct ast_channel *ast)
02643 {
02644    int res;
02645    int index,x, law;
02646    /*static int restore_gains(struct zt_pvt *p);*/
02647    struct zt_pvt *p = ast->tech_pvt;
02648    struct zt_pvt *tmp = NULL;
02649    struct zt_pvt *prev = NULL;
02650    ZT_PARAMS par;
02651 
02652    if (option_debug)
02653       ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
02654    if (!ast->tech_pvt) {
02655       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02656       return 0;
02657    }
02658    
02659    ast_mutex_lock(&p->lock);
02660    
02661    index = zt_get_index(ast, p, 1);
02662 
02663    if (p->sig == SIG_PRI) {
02664       x = 1;
02665       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02666    }
02667 
02668    x = 0;
02669    zt_confmute(p, 0);
02670    restore_gains(p);
02671    if (p->origcid_num) {
02672       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02673       free(p->origcid_num);
02674       p->origcid_num = NULL;
02675    }  
02676    if (p->origcid_name) {
02677       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02678       free(p->origcid_name);
02679       p->origcid_name = NULL;
02680    }  
02681    if (p->dsp)
02682       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02683    if (p->exten)
02684       p->exten[0] = '\0';
02685 
02686    if (option_debug)
02687       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02688       p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
02689 
02690    if (index > -1) {
02691       /* Real channel, do some fixup */
02692       p->subs[index].owner = NULL;
02693       p->subs[index].needanswer = 0;
02694       p->subs[index].needflash = 0;
02695       p->subs[index].needringing = 0;
02696       p->subs[index].needbusy = 0;
02697       p->subs[index].needcongestion = 0;
02698       p->subs[index].linear = 0;
02699       p->subs[index].needcallerid = 0;
02700       p->polarity = POLARITY_IDLE;
02701       zt_setlinear(p->subs[index].zfd, 0);
02702       if (index == SUB_REAL) {
02703          if ((p->subs[SUB_CALLWAIT].zfd > -1) && (p->subs[SUB_THREEWAY].zfd > -1)) {
02704             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02705             if (p->subs[SUB_CALLWAIT].inthreeway) {
02706                /* We had flipped over to answer a callwait and now it's gone */
02707                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02708                /* Move to the call-wait, but un-own us until they flip back. */
02709                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02710                unalloc_sub(p, SUB_CALLWAIT);
02711                p->owner = NULL;
02712             } else {
02713                /* The three way hung up, but we still have a call wait */
02714                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02715                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02716                unalloc_sub(p, SUB_THREEWAY);
02717                if (p->subs[SUB_REAL].inthreeway) {
02718                   /* This was part of a three way call.  Immediately make way for
02719                      another call */
02720                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02721                   p->owner = p->subs[SUB_REAL].owner;
02722                } else {
02723                   /* This call hasn't been completed yet...  Set owner to NULL */
02724                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02725                   p->owner = NULL;
02726                }
02727                p->subs[SUB_REAL].inthreeway = 0;
02728             }
02729          } else if (p->subs[SUB_CALLWAIT].zfd > -1) {
02730             /* Move to the call-wait and switch back to them. */
02731             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02732             unalloc_sub(p, SUB_CALLWAIT);
02733             p->owner = p->subs[SUB_REAL].owner;
02734             if (p->owner->_state != AST_STATE_UP)
02735                p->subs[SUB_REAL].needanswer = 1;
02736             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
02737                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
02738          } else if (p->subs[SUB_THREEWAY].zfd > -1) {
02739             swap_subs(p, SUB_THREEWAY, SUB_REAL);
02740             unalloc_sub(p, SUB_THREEWAY);
02741             if (p->subs[SUB_REAL].inthreeway) {
02742                /* This was part of a three way call.  Immediately make way for
02743                   another call */
02744                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02745                p->owner = p->subs[SUB_REAL].owner;
02746             } else {
02747                /* This call hasn't been completed yet...  Set owner to NULL */
02748                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02749                p->owner = NULL;
02750             }
02751             p->subs[SUB_REAL].inthreeway = 0;
02752          }
02753       } else if (index == SUB_CALLWAIT) {
02754          /* Ditch the holding callwait call, and immediately make it availabe */
02755          if (p->subs[SUB_CALLWAIT].inthreeway) {
02756             /* This is actually part of a three way, placed on hold.  Place the third part
02757                on music on hold now */
02758             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
02759                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
02760                   S_OR(p->mohsuggest, NULL),
02761                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02762             }
02763             p->subs[SUB_THREEWAY].inthreeway = 0;
02764             /* Make it the call wait now */
02765             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
02766             unalloc_sub(p, SUB_THREEWAY);
02767          } else
02768             unalloc_sub(p, SUB_CALLWAIT);
02769       } else if (index == SUB_THREEWAY) {
02770          if (p->subs[SUB_CALLWAIT].inthreeway) {
02771             /* The other party of the three way call is currently in a call-wait state.
02772                Start music on hold for them, and take the main guy out of the third call */
02773             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
02774                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
02775                   S_OR(p->mohsuggest, NULL),
02776                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
02777             }
02778             p->subs[SUB_CALLWAIT].inthreeway = 0;
02779          }
02780          p->subs[SUB_REAL].inthreeway = 0;
02781          /* If this was part of a three way call index, let us make
02782             another three way call */
02783          unalloc_sub(p, SUB_THREEWAY);
02784       } else {
02785          /* This wasn't any sort of call, but how are we an index? */
02786          ast_log(LOG_WARNING, "Index found but not any type of call?\n");
02787       }
02788    }
02789 
02790    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
02791       int outgoing = p->outgoing;
02792       p->owner = NULL;
02793       p->ringt = 0;
02794       p->distinctivering = 0;
02795       p->confirmanswer = 0;
02796       p->cidrings = 1;
02797       p->outgoing = 0;
02798       p->digital = 0;
02799       p->faxhandled = 0;
02800       p->pulsedial = 0;
02801       p->onhooktime = time(NULL);
02802 #ifdef HAVE_PRI
02803       p->proceeding = 0;
02804       p->progress = 0;
02805       p->alerting = 0;
02806       p->setup_ack = 0;
02807 #endif      
02808       if (p->dsp) {
02809          ast_dsp_free(p->dsp);
02810          p->dsp = NULL;
02811       }
02812 
02813       law = ZT_LAW_DEFAULT;
02814       res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
02815       if (res < 0) 
02816          ast_log(LOG_WARNING, "Unable to set law on channel %d to default\n", p->channel);
02817       /* Perform low level hangup if no owner left */
02818 #ifdef HAVE_PRI
02819       if (p->pri) {
02820 #ifdef SUPPORT_USERUSER
02821          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
02822 #endif
02823 
02824          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
02825          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
02826             if (!pri_grab(p, p->pri)) {
02827                if (p->alreadyhungup) {
02828                   ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
02829 
02830 #ifdef SUPPORT_USERUSER
02831                   pri_call_set_useruser(p->call, useruser);
02832 #endif
02833 
02834                   pri_hangup(p->pri->pri, p->call, -1, -1);
02835                   p->call = NULL;
02836                   if (p->bearer) 
02837                      p->bearer->call = NULL;
02838                } else {
02839                   const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
02840                   int icause = ast->hangupcause ? ast->hangupcause : -1;
02841                   ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
02842 
02843 #ifdef SUPPORT_USERUSER
02844                   pri_call_set_useruser(p->call, useruser);
02845 #endif
02846 
02847                   p->alreadyhungup = 1;
02848                   if (p->bearer)
02849                      p->bearer->alreadyhungup = 1;
02850                   if (cause) {
02851                      if (atoi(cause))
02852                         icause = atoi(cause);
02853                   }
02854 
02855                   pri_hangup(p->pri->pri, p->call, icause, -1);
02856 
02857                   /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */
02858                   if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) {
02859                       if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) {
02860                      p->call = NULL;
02861                       } else {
02862                      ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state);
02863                      icause = 16; /* Note, in pri_hangup() libpri will already override the cause */
02864                       }
02865                   } 
02866                   
02867                   if (p->pri->nodetype == BRI_NETWORK_PTMP) {
02868                       if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) {
02869                      if (outgoing) {
02870                          p->call = NULL;
02871                      }
02872                       }
02873                   }
02874                   
02875                   
02876                }
02877                if (res < 0) 
02878                   ast_log(LOG_WARNING, "pri_disconnect failed\n");
02879                pri_rel(p->pri);        
02880             } else {
02881                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
02882                res = -1;
02883             }
02884          } else {
02885             if (p->bearer)
02886                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
02887             p->call = NULL;
02888             res = 0;
02889          }
02890       }
02891 #endif
02892 #ifdef HAVE_GSMAT
02893       if (p->gsm.modul) {
02894           if (!p->alreadyhungup)
02895          gsm_hangup(p->gsm.modul);
02896       }
02897 #endif
02898       if (p->sig && (p->sig != SIG_PRI) && (p->sig != SIG_GSM))
02899          res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
02900       if (res < 0) {
02901          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
02902       }
02903       switch (p->sig) {
02904       case SIG_FXOGS:
02905       case SIG_FXOLS:
02906       case SIG_FXOKS:
02907          res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
02908          if (!res) {
02909 #if 0
02910             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
02911 #endif
02912             /* If they're off hook, try playing congestion */
02913             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
02914                tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
02915             else
02916                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02917          }
02918          break;
02919       case SIG_FXSGS:
02920       case SIG_FXSLS:
02921       case SIG_FXSKS:
02922          /* Make sure we're not made available for at least two seconds assuming
02923             we were actually used for an inbound or outbound call. */
02924          if (ast->_state != AST_STATE_RESERVED) {
02925             time(&p->guardtime);
02926             p->guardtime += 2;
02927          }
02928          break;
02929       default:
02930          tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
02931       }
02932       if (p->cidspill)
02933          free(p->cidspill);
02934       if (p->sig)
02935          zt_disable_ec(p);
02936       x = 0;
02937       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
02938       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
02939       p->didtdd = 0;
02940       p->cidspill = NULL;
02941       p->callwaitcas = 0;
02942       p->callwaiting = p->permcallwaiting;
02943       p->hidecallerid = p->permhidecallerid;
02944       p->dialing = 0;
02945       p->rdnis[0] = '\0';
02946       update_conf(p);
02947       reset_conf(p);
02948       /* Restore data mode */
02949       if (p->sig == SIG_PRI) {
02950          x = 0;
02951          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02952       }
02953 #ifdef HAVE_PRI
02954       if (p->bearer) {
02955          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
02956          /* Free up the bearer channel as well, and
02957             don't use its file descriptor anymore */
02958          update_conf(p->bearer);
02959          reset_conf(p->bearer);
02960          p->bearer->owner = NULL;
02961          p->bearer->realcall = NULL;
02962          p->bearer = NULL;
02963          p->subs[SUB_REAL].zfd = -1;
02964          p->pri = NULL;
02965       }
02966 #endif
02967       restart_monitor();
02968    }
02969 
02970    p->callwaitingrepeat = 0;
02971    p->cidcwexpire = 0;
02972    p->oprmode = 0;
02973    ast->tech_pvt = NULL;
02974    ast_mutex_unlock(&p->lock);
02975    ast_module_unref(ast_module_info->self);
02976    if (option_verbose > 2) 
02977       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
02978 
02979    ast_mutex_lock(&iflock);
02980    tmp = iflist;
02981    prev = NULL;
02982    if (p->destroy) {
02983       while (tmp) {
02984          if (tmp == p) {
02985             destroy_channel(prev, tmp, 0);
02986             break;
02987          } else {
02988             prev = tmp;
02989             tmp = tmp->next;
02990          }
02991       }
02992    }
02993    ast_mutex_unlock(&iflock);
02994    return 0;
02995 }
02996 
02997 static int zt_answer(struct ast_channel *ast)
02998 {
02999    struct zt_pvt *p = ast->tech_pvt;
03000    int res = 0;
03001    int index;
03002    int oldstate = ast->_state;
03003    ast_setstate(ast, AST_STATE_UP);
03004    ast_mutex_lock(&p->lock);
03005    index = zt_get_index(ast, p, 0);
03006    if (index < 0)
03007       index = SUB_REAL;
03008    /* nothing to do if a radio channel */
03009    if ((p->radio || (p->oprmode < 0))) {
03010       ast_mutex_unlock(&p->lock);
03011       return 0;
03012    }
03013    switch (p->sig) {
03014    case SIG_FXSLS:
03015    case SIG_FXSGS:
03016    case SIG_FXSKS:
03017       p->ringt = 0;
03018       /* Fall through */
03019    case SIG_EM:
03020    case SIG_EM_E1:
03021    case SIG_EMWINK:
03022    case SIG_FEATD:
03023    case SIG_FEATDMF:
03024    case SIG_FEATDMF_TA:
03025    case SIG_E911:
03026    case SIG_FGC_CAMA:
03027    case SIG_FGC_CAMAMF:
03028    case SIG_FEATB:
03029    case SIG_SF:
03030    case SIG_SFWINK:
03031    case SIG_SF_FEATD:
03032    case SIG_SF_FEATDMF:
03033    case SIG_SF_FEATB:
03034    case SIG_FXOLS:
03035    case SIG_FXOGS:
03036    case SIG_FXOKS:
03037       /* Pick up the line */
03038       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
03039       if (p->hanguponpolarityswitch) {
03040          gettimeofday(&p->polaritydelaytv, NULL);
03041       }
03042       res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
03043       tone_zone_play_tone(p->subs[index].zfd, -1);
03044       p->dialing = 0;
03045       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
03046          if (oldstate == AST_STATE_RINGING) {
03047             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
03048             tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, -1);
03049             swap_subs(p, SUB_THREEWAY, SUB_REAL);
03050             p->owner = p->subs[SUB_REAL].owner;
03051          }
03052       }
03053       if (p->sig & __ZT_SIG_FXS) {
03054          zt_enable_ec(p);
03055          zt_train_ec(p);
03056       }
03057       break;
03058 #ifdef HAVE_PRI
03059    case SIG_PRI:
03060       /* Send a pri acknowledge */
03061       if (!pri_grab(p, p->pri)) {
03062          p->proceeding = 1;
03063          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
03064          pri_rel(p->pri);
03065          /* stop ignoring inband dtmf */
03066          enable_dtmf_detect(p);
03067       } else {
03068          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
03069          res = -1;
03070       }
03071       /* the audio path is complete now, train the echo canceler */
03072       zt_train_ec(p);
03073       break;
03074 #endif
03075 #ifdef HAVE_GSMAT
03076    case SIG_GSM:
03077       if (p->gsm.modul) {
03078           gsm_answer(p->gsm.modul);
03079       }
03080       break;
03081 #endif
03082    case 0:
03083       ast_mutex_unlock(&p->lock);
03084       return 0;
03085    default:
03086       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
03087       res = -1;
03088    }
03089    ast_mutex_unlock(&p->lock);
03090    return res;
03091 }
03092 
03093 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
03094 {
03095    char *cp;
03096    signed char *scp;
03097    int x;
03098    int index;
03099    struct zt_pvt *p = chan->tech_pvt, *pp;
03100    struct oprmode *oprmode;
03101    
03102 
03103    /* all supported options require data */
03104    if (!data || (datalen < 1)) {
03105       errno = EINVAL;
03106       return -1;
03107    }
03108 
03109    switch (option) {
03110    case AST_OPTION_TXGAIN:
03111       scp = (signed char *) data;
03112       index = zt_get_index(chan, p, 0);
03113       if (index < 0) {
03114          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
03115          return -1;
03116       }
03117       if (option_debug)
03118          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
03119       return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
03120    case AST_OPTION_RXGAIN:
03121       scp = (signed char *) data;
03122       index = zt_get_index(chan, p, 0);
03123       if (index < 0) {
03124          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
03125          return -1;
03126       }
03127       if (option_debug)
03128          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
03129       return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
03130    case AST_OPTION_TONE_VERIFY:
03131       if (!p->dsp)
03132          break;
03133       cp = (char *) data;
03134       switch (*cp) {
03135       case 1:
03136          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
03137          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
03138          break;
03139       case 2:
03140          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
03141          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
03142          break;
03143       default:
03144          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
03145          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
03146          break;
03147       }
03148       break;
03149    case AST_OPTION_TDD:
03150       /* turn on or off TDD */
03151       cp = (char *) data;
03152       p->mate = 0;
03153       if (!*cp) { /* turn it off */
03154          if (option_debug)
03155             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
03156          if (p->tdd)
03157             tdd_free(p->tdd);
03158          p->tdd = 0;
03159          break;
03160       }
03161       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
03162          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
03163       zt_disable_ec(p);
03164       /* otherwise, turn it on */
03165       if (!p->didtdd) { /* if havent done it yet */
03166          unsigned char mybuf[41000], *buf;
03167          int size, res, fd, len;
03168          struct pollfd fds[1];
03169 
03170          buf = mybuf;
03171          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
03172          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
03173          len = 40000;
03174          index = zt_get_index(chan, p, 0);
03175          if (index < 0) {
03176             ast_log(LOG_WARNING, "No index in TDD?\n");
03177             return -1;
03178          }
03179          fd = p->subs[index].zfd;
03180          while (len) {
03181             if (ast_check_hangup(chan))
03182                return -1;
03183             size = len;
03184             if (size > READ_SIZE)
03185                size = READ_SIZE;
03186             fds[0].fd = fd;
03187             fds[0].events = POLLPRI | POLLOUT;
03188             fds[0].revents = 0;
03189             res = poll(fds, 1, -1);
03190             if (!res) {
03191                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
03192                continue;
03193             }
03194             /* if got exception */
03195             if (fds[0].revents & POLLPRI)
03196                return -1;
03197             if (!(fds[0].revents & POLLOUT)) {
03198                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
03199                continue;
03200             }
03201             res = write(fd, buf, size);
03202             if (res != size) {
03203                if (res == -1) return -1;
03204                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
03205                break;
03206             }
03207             len -= size;
03208             buf += size;
03209          }
03210          p->didtdd = 1; /* set to have done it now */    
03211       }
03212       if (*cp == 2) { /* Mate mode */
03213          if (p->tdd)
03214             tdd_free(p->tdd);
03215          p->tdd = 0;
03216          p->mate = 1;
03217          break;
03218       }     
03219       if (!p->tdd) { /* if we dont have one yet */
03220          p->tdd = tdd_new(); /* allocate one */
03221       }     
03222       break;
03223    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
03224       if (!p->dsp)
03225          break;
03226       cp = (char *) data;
03227       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
03228          *cp ? "ON" : "OFF", (int) *cp, chan->name);
03229                 p->dtmfrelax = 0;
03230                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
03231                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
03232       break;
03233    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
03234       cp = (char *) data;
03235       if (!*cp) {    
03236          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
03237          x = 0;
03238          zt_disable_ec(p);
03239       } else {    
03240          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
03241          x = 1;
03242       }
03243       if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
03244          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
03245       break;
03246    case AST_OPTION_OPRMODE:  /* Operator services mode */
03247       oprmode = (struct oprmode *) data;
03248       pp = oprmode->peer->tech_pvt;
03249       p->oprmode = pp->oprmode = 0;
03250       /* setup peers */
03251       p->oprpeer = pp;
03252       pp->oprpeer = p;
03253       /* setup modes, if any */
03254       if (oprmode->mode) 
03255       {
03256          pp->oprmode = oprmode->mode;
03257          p->oprmode = -oprmode->mode;
03258       }
03259       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
03260          oprmode->mode, chan->name,oprmode->peer->name);;
03261       break;
03262    case AST_OPTION_ECHOCAN:
03263       cp = (char *) data;
03264       if (*cp) {
03265          ast_log(LOG_DEBUG, "Enabling echo cancelation on %s\n", chan->name);
03266          zt_enable_ec(p);
03267       } else {
03268          ast_log(LOG_DEBUG, "Disabling echo cancelation on %s\n", chan->name);
03269          zt_disable_ec(p);
03270       }
03271       break;
03272    }
03273    errno = 0;
03274 
03275    return 0;
03276 }
03277 
03278 static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03279 {
03280    struct zt_pvt *p = chan->tech_pvt;
03281    
03282    if (!strcasecmp(data, "rxgain")) {
03283       ast_mutex_lock(&p->lock);
03284       snprintf(buf, len, "%f", p->rxgain);
03285       ast_mutex_unlock(&p->lock);   
03286    } else if (!strcasecmp(data, "txgain")) {
03287       ast_mutex_lock(&p->lock);
03288       snprintf(buf, len, "%f", p->txgain);
03289       ast_mutex_unlock(&p->lock);   
03290    } else {
03291       ast_copy_string(buf, "", len);
03292    }
03293    return 0;
03294 }
03295 
03296 
03297 static void zt_unlink(struct zt_pvt *slave, struct zt_pvt *master, int needlock)
03298 {
03299    /* Unlink a specific slave or all slaves/masters from a given master */
03300    int x;
03301    int hasslaves;
03302    if (!master)
03303       return;
03304    if (needlock) {
03305       ast_mutex_lock(&master->lock);
03306       if (slave) {
03307          while (ast_mutex_trylock(&slave->lock)) {
03308             ast_mutex_unlock(&master->lock);
03309             usleep(1);
03310             ast_mutex_lock(&master->lock);
03311          }
03312       }
03313    }
03314    hasslaves = 0;
03315    for (x = 0; x < MAX_SLAVES; x++) {
03316       if (master->slaves[x]) {
03317          if (!slave || (master->slaves[x] == slave)) {
03318             /* Take slave out of the conference */
03319             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03320             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03321             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03322             master->slaves[x]->master = NULL;
03323             master->slaves[x] = NULL;
03324          } else
03325             hasslaves = 1;
03326       }
03327       if (!hasslaves)
03328          master->inconference = 0;
03329    }
03330    if (!slave) {
03331       if (master->master) {
03332          /* Take master out of the conference */
03333          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03334          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03335          hasslaves = 0;
03336          for (x = 0; x < MAX_SLAVES; x++) {
03337             if (master->master->slaves[x] == master)
03338                master->master->slaves[x] = NULL;
03339             else if (master->master->slaves[x])
03340                hasslaves = 1;
03341          }
03342          if (!hasslaves)
03343             master->master->inconference = 0;
03344       }
03345       master->master = NULL;
03346    }
03347    update_conf(master);
03348    if (needlock) {
03349       if (slave)
03350          ast_mutex_unlock(&slave->lock);
03351       ast_mutex_unlock(&master->lock);
03352    }
03353 }
03354 
03355 static void zt_link(struct zt_pvt *slave, struct zt_pvt *master) {
03356    int x;
03357    if (!slave || !master) {
03358       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03359       return;
03360    }
03361    for (x = 0; x < MAX_SLAVES; x++) {
03362       if (!master->slaves[x]) {
03363          master->slaves[x] = slave;
03364          break;
03365       }
03366    }
03367    if (x >= MAX_SLAVES) {
03368       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03369       master->slaves[MAX_SLAVES - 1] = slave;
03370    }
03371    if (slave->master) 
03372       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03373    slave->master = master;
03374    
03375    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03376 }
03377 
03378 static void disable_dtmf_detect(struct zt_pvt *p)
03379 {
03380 #ifdef ZT_TONEDETECT
03381    int val;
03382 #endif
03383 
03384    p->ignoredtmf = 1;
03385 
03386 #ifdef ZT_TONEDETECT
03387    val = 0;
03388    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03389 #endif      
03390    if (!p->hardwaredtmf && p->dsp) {
03391       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03392       ast_dsp_set_features(p->dsp, p->dsp_features);
03393    }
03394 }
03395 
03396 static void enable_dtmf_detect(struct zt_pvt *p)
03397 {
03398 #ifdef ZT_TONEDETECT
03399    int val;
03400 #endif
03401 
03402    if (p->channel == CHAN_PSEUDO)
03403       return;
03404 
03405    p->ignoredtmf = 0;
03406 
03407 #ifdef ZT_TONEDETECT
03408    val = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
03409    ioctl(p->subs[SUB_REAL].zfd, ZT_TONEDETECT, &val);
03410 #endif      
03411    if (!p->hardwaredtmf && p->dsp) {
03412       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03413       ast_dsp_set_features(p->dsp, p->dsp_features);
03414    }
03415 }
03416 
03417 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)
03418 {
03419    struct ast_channel *who;
03420    struct zt_pvt *p0, *p1, *op0, *op1;
03421    struct zt_pvt *master = NULL, *slave = NULL;
03422    struct ast_frame *f;
03423    int inconf = 0;
03424    int nothingok = 1;
03425    int ofd0, ofd1;
03426    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03427    int os0 = -1, os1 = -1;
03428    int priority = 0;
03429    struct ast_channel *oc0, *oc1;
03430    enum ast_bridge_result res;
03431 
03432 #ifdef PRI_2BCT
03433    int triedtopribridge = 0;
03434    q931_call *q931c0 = NULL, *q931c1 = NULL;
03435 #endif
03436 
03437    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03438       There is code below to handle it properly until DTMF is actually seen,
03439       but due to currently unresolved issues it's ignored...
03440    */
03441 
03442    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03443       return AST_BRIDGE_FAILED_NOWARN;
03444 
03445    ast_mutex_lock(&c0->lock);
03446    while (ast_mutex_trylock(&c1->lock)) {
03447       ast_mutex_unlock(&c0->lock);
03448       usleep(1);
03449       ast_mutex_lock(&c0->lock);
03450    }
03451 
03452    p0 = c0->tech_pvt;
03453    p1 = c1->tech_pvt;
03454    /* cant do pseudo-channels here */
03455    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03456       ast_mutex_unlock(&c0->lock);
03457       ast_mutex_unlock(&c1->lock);
03458       return AST_BRIDGE_FAILED_NOWARN;
03459    }
03460 
03461    oi0 = zt_get_index(c0, p0, 0);
03462    oi1 = zt_get_index(c1, p1, 0);
03463    if ((oi0 < 0) || (oi1 < 0)) {
03464       ast_mutex_unlock(&c0->lock);
03465       ast_mutex_unlock(&c1->lock);
03466       return AST_BRIDGE_FAILED;
03467    }
03468 
03469    op0 = p0 = c0->tech_pvt;
03470    op1 = p1 = c1->tech_pvt;
03471    ofd0 = c0->fds[0];
03472    ofd1 = c1->fds[0];
03473    oc0 = p0->owner;
03474    oc1 = p1->owner;
03475 
03476    if (ast_mutex_trylock(&p0->lock)) {
03477       /* Don't block, due to potential for deadlock */
03478       ast_mutex_unlock(&c0->lock);
03479       ast_mutex_unlock(&c1->lock);
03480       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03481       return AST_BRIDGE_RETRY;
03482    }
03483    if (ast_mutex_trylock(&p1->lock)) {
03484       /* Don't block, due to potential for deadlock */
03485       ast_mutex_unlock(&p0->lock);
03486       ast_mutex_unlock(&c0->lock);
03487       ast_mutex_unlock(&c1->lock);
03488       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03489       return AST_BRIDGE_RETRY;
03490    }
03491 
03492    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03493       if (p0->owner && p1->owner) {
03494          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03495          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03496             master = p0;
03497             slave = p1;
03498             inconf = 1;
03499          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03500             master = p1;
03501             slave = p0;
03502             inconf = 1;
03503          } else {
03504             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03505             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03506                p0->channel,
03507                oi0, (p0->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03508                p0->subs[SUB_REAL].inthreeway, p0->channel,
03509                oi0, (p1->subs[SUB_CALLWAIT].zfd > -1) ? 1 : 0,
03510                p1->subs[SUB_REAL].inthreeway);
03511          }
03512          nothingok = 0;
03513       }
03514    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03515       if (p1->subs[SUB_THREEWAY].inthreeway) {
03516          master = p1;
03517          slave = p0;
03518          nothingok = 0;
03519       }
03520    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03521       if (p0->subs[SUB_THREEWAY].inthreeway) {
03522          master = p0;
03523          slave = p1;
03524          nothingok = 0;
03525       }
03526    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03527       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03528          don't put us in anything */
03529       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03530          master = p1;
03531          slave = p0;
03532          nothingok = 0;
03533       }
03534    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03535       /* Same as previous */
03536       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03537          master = p0;
03538          slave = p1;
03539          nothingok = 0;
03540       }
03541    }
03542    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03543       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03544    if (master && slave) {
03545       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03546          in an active threeway call with a channel that is ringing, we should
03547          indicate ringing. */
03548       if ((oi1 == SUB_THREEWAY) && 
03549           p1->subs[SUB_THREEWAY].inthreeway && 
03550           p1->subs[SUB_REAL].owner && 
03551           p1->subs[SUB_REAL].inthreeway && 
03552           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03553          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
03554          tone_zone_play_tone(p0->subs[oi0].zfd, ZT_TONE_RINGTONE);
03555          os1 = p1->subs[SUB_REAL].owner->_state;
03556       } else {
03557          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
03558          tone_zone_play_tone(p0->subs[oi0].zfd, -1);
03559       }
03560       if ((oi0 == SUB_THREEWAY) && 
03561           p0->subs[SUB_THREEWAY].inthreeway && 
03562           p0->subs[SUB_REAL].owner && 
03563           p0->subs[SUB_REAL].inthreeway && 
03564           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03565          ast_log(LOG_DEBUG, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
03566          tone_zone_play_tone(p1->subs[oi1].zfd, ZT_TONE_RINGTONE);
03567          os0 = p0->subs[SUB_REAL].owner->_state;
03568       } else {
03569          ast_log(LOG_DEBUG, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
03570          tone_zone_play_tone(p1->subs[oi0].zfd, -1);
03571       }
03572       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03573          if (!p0->echocanbridged || !p1->echocanbridged) {
03574             /* Disable echo cancellation if appropriate */
03575             zt_disable_ec(p0);
03576             zt_disable_ec(p1);
03577          }
03578       }
03579       zt_link(slave, master);
03580       master->inconference = inconf;
03581    } else if (!nothingok)
03582       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03583 
03584    update_conf(p0);
03585    update_conf(p1);
03586    t0 = p0->subs[SUB_REAL].inthreeway;
03587    t1 = p1->subs[SUB_REAL].inthreeway;
03588 
03589    ast_mutex_unlock(&p0->lock);
03590    ast_mutex_unlock(&p1->lock);
03591 
03592    ast_mutex_unlock(&c0->lock);
03593    ast_mutex_unlock(&c1->lock);
03594 
03595    /* Native bridge failed */
03596    if ((!master || !slave) && !nothingok) {
03597       zt_enable_ec(p0);
03598       zt_enable_ec(p1);
03599       return AST_BRIDGE_FAILED;
03600    }
03601    
03602    if (option_verbose > 2) 
03603       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03604 
03605    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03606       disable_dtmf_detect(op0);
03607 
03608    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03609       disable_dtmf_detect(op1);
03610 
03611    for (;;) {
03612       struct ast_channel *c0_priority[2] = {c0, c1};
03613       struct ast_channel *c1_priority[2] = {c1, c0};
03614 
03615       /* Here's our main loop...  Start by locking things, looking for private parts, 
03616          and then balking if anything is wrong */
03617       ast_mutex_lock(&c0->lock);
03618       while (ast_mutex_trylock(&c1->lock)) {
03619          ast_mutex_unlock(&c0->lock);
03620          usleep(1);
03621          ast_mutex_lock(&c0->lock);
03622       }
03623 
03624       p0 = c0->tech_pvt;
03625       p1 = c1->tech_pvt;
03626 
03627       if (op0 == p0)
03628          i0 = zt_get_index(c0, p0, 1);
03629       if (op1 == p1)
03630          i1 = zt_get_index(c1, p1, 1);
03631       ast_mutex_unlock(&c0->lock);
03632       ast_mutex_unlock(&c1->lock);
03633 
03634       if (!timeoutms || 
03635           (op0 != p0) ||
03636           (op1 != p1) || 
03637           (ofd0 != c0->fds[0]) || 
03638           (ofd1 != c1->fds[0]) ||
03639           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
03640           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
03641           (oc0 != p0->owner) || 
03642           (oc1 != p1->owner) ||
03643           (t0 != p0->subs[SUB_REAL].inthreeway) ||
03644           (t1 != p1->subs[SUB_REAL].inthreeway) ||
03645           (oi0 != i0) ||
03646           (oi1 != i1)) {
03647          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
03648             op0->channel, oi0, op1->channel, oi1);
03649          res = AST_BRIDGE_RETRY;
03650          goto return_from_bridge;
03651       }
03652 
03653 #ifdef PRI_2BCT
03654       q931c0 = p0->call;
03655       q931c1 = p1->call;
03656       if (p0->transfer && p1->transfer 
03657           && q931c0 && q931c1 
03658           && !triedtopribridge) {
03659          pri_channel_bridge(q931c0, q931c1);
03660          triedtopribridge = 1;
03661       }
03662 #endif
03663 
03664       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
03665       if (!who) {
03666          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
03667          continue;
03668       }
03669       f = ast_read(who);
03670       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
03671          *fo = f;
03672          *rc = who;
03673          res = AST_BRIDGE_COMPLETE;
03674          goto return_from_bridge;
03675       }
03676       if (f->frametype == AST_FRAME_DTMF) {
03677          if ((who == c0) && p0->pulsedial) {
03678             ast_write(c1, f);
03679          } else if ((who == c1) && p1->pulsedial) {
03680             ast_write(c0, f);
03681          } else {
03682             *fo = f;
03683             *rc = who;
03684             res = AST_BRIDGE_COMPLETE;
03685             goto return_from_bridge;
03686          }
03687       }
03688       ast_frfree(f);
03689       
03690       /* Swap who gets priority */
03691       priority = !priority;
03692    }
03693 
03694 return_from_bridge:
03695    if (op0 == p0)
03696       zt_enable_ec(p0);
03697 
03698    if (op1 == p1)
03699       zt_enable_ec(p1);
03700 
03701    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03702       enable_dtmf_detect(op0);
03703 
03704    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03705       enable_dtmf_detect(op1);
03706 
03707    zt_unlink(slave, master, 1);
03708 
03709    return res;
03710 }
03711 
03712 static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
03713 {
03714    struct zt_pvt *p = newchan->tech_pvt;
03715    int x;
03716    if (newchan && newchan->tech_pvt) {
03717        p = newchan->tech_pvt;
03718    }
03719    if (!p) {
03720        if (newchan) {
03721       ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name);
03722        }
03723        return 0;
03724    }
03725    ast_mutex_lock(&p->lock);
03726    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
03727    if (p->owner == oldchan) {
03728       p->owner = newchan;
03729    }
03730    for (x = 0; x < 3; x++)
03731       if (p->subs[x].owner == oldchan) {
03732          if (!x)
03733             zt_unlink(NULL, p, 0);
03734          p->subs[x].owner = newchan;
03735       }
03736    if (newchan->_state == AST_STATE_RINGING) 
03737       zt_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
03738    update_conf(p);
03739    ast_mutex_unlock(&p->lock);
03740    return 0;
03741 }
03742 
03743 static int zt_ring_phone(struct zt_pvt *p)
03744 {
03745    int x;
03746    int res;
03747    /* Make sure our transmit state is on hook */
03748    x = 0;
03749    x = ZT_ONHOOK;
03750    res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03751    do {
03752       x = ZT_RING;
03753       res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
03754       if (res) {
03755          switch (errno) {
03756          case EBUSY:
03757          case EINTR:
03758             /* Wait just in case */
03759             usleep(10000);
03760             continue;
03761          case EINPROGRESS:
03762             res = 0;
03763             break;
03764          default:
03765             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
03766             res = 0;
03767          }
03768       }
03769    } while (res);
03770    return res;
03771 }
03772 
03773 static void *ss_thread(void *data);
03774 
03775 static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int);
03776 
03777 static int attempt_transfer(struct zt_pvt *p)
03778 {
03779    /* In order to transfer, we need at least one of the channels to
03780       actually be in a call bridge.  We can't conference two applications
03781       together (but then, why would we want to?) */
03782    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
03783       /* The three-way person we're about to transfer to could still be in MOH, so
03784          stop if now if appropriate */
03785       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
03786          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
03787       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
03788          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
03789       }
03790       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
03791          tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
03792       }
03793       if (p->subs[SUB_REAL].owner->cdr) {
03794          /* Move CDR from second channel to current one */
03795          p->subs[SUB_THREEWAY].owner->cdr =
03796             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, p->subs[SUB_REAL].owner->cdr);
03797          p->subs[SUB_REAL].owner->cdr = NULL;
03798       }
03799       if (ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr) {
03800          /* Move CDR from second channel's bridge to current one */
03801          p->subs[SUB_THREEWAY].owner->cdr =
03802             ast_cdr_append(p->subs[SUB_THREEWAY].owner->cdr, ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr);
03803          ast_bridged_channel(p->subs[SUB_REAL].owner)->cdr = NULL;
03804       }
03805        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
03806          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03807                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
03808          return -1;
03809       }
03810       /* Orphan the channel after releasing the lock */
03811       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
03812       unalloc_sub(p, SUB_THREEWAY);
03813    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03814       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03815       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
03816          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
03817       }
03818       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
03819          tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
03820       }
03821       if (p->subs[SUB_THREEWAY].owner->cdr) {
03822          /* Move CDR from second channel to current one */
03823          p->subs[SUB_REAL].owner->cdr = 
03824             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, p->subs[SUB_THREEWAY].owner->cdr);
03825          p->subs[SUB_THREEWAY].owner->cdr = NULL;
03826       }
03827       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr) {
03828          /* Move CDR from second channel's bridge to current one */
03829          p->subs[SUB_REAL].owner->cdr = 
03830             ast_cdr_append(p->subs[SUB_REAL].owner->cdr, ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr);
03831          ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->cdr = NULL;
03832       }
03833       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
03834          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
03835                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
03836          return -1;
03837       }
03838       /* Three-way is now the REAL */
03839       swap_subs(p, SUB_THREEWAY, SUB_REAL);
03840       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03841       unalloc_sub(p, SUB_THREEWAY);
03842       /* Tell the caller not to hangup */
03843       return 1;
03844    } else {
03845       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
03846                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
03847       p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
03848       return -1;
03849    }
03850    return 0;
03851 }
03852 
03853 static int check_for_conference(struct zt_pvt *p)
03854 {
03855    ZT_CONFINFO ci;
03856    /* Fine if we already have a master, etc */
03857    if (p->master || (p->confno > -1))
03858       return 0;
03859    memset(&ci, 0, sizeof(ci));
03860    if (ioctl(p->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
03861       ast_log(LOG_WARNING, "Failed to get conference info on channel %d\n", p->channel);
03862       return 0;
03863    }
03864    /* If we have no master and don't have a confno, then 
03865       if we're in a conference, it's probably a MeetMe room or
03866       some such, so don't let us 3-way out! */
03867    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
03868       if (option_verbose > 2) 
03869          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
03870       return 1;
03871    }
03872    return 0;
03873 }
03874 
03875 static int get_alarms(struct zt_pvt *p)
03876 {
03877    int res;
03878    ZT_SPANINFO zi;
03879    memset(&zi, 0, sizeof(zi));
03880    zi.spanno = p->span;
03881    res = ioctl(p->subs[SUB_REAL].zfd, ZT_SPANSTAT, &zi);
03882    if (res < 0) {
03883       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
03884       return 0;
03885    }
03886    return zi.alarms;
03887 }
03888 
03889 static void zt_handle_dtmfup(struct ast_channel *ast, int index, struct ast_frame **dest)
03890 {
03891    struct zt_pvt *p = ast->tech_pvt;
03892    struct ast_frame *f = *dest;
03893 
03894    if (option_debug)
03895       ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
03896 
03897    if (p->confirmanswer) {
03898       if (option_debug)
03899          ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
03900       /* Upon receiving a DTMF digit, consider this an answer confirmation instead
03901          of a DTMF digit */
03902       p->subs[index].f.frametype = AST_FRAME_CONTROL;
03903       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
03904       *dest = &p->subs[index].f;
03905       /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
03906       p->confirmanswer = 0;
03907    } else if (p->callwaitcas) {
03908       if ((f->subclass == 'A') || (f->subclass == 'D')) {
03909          if (option_debug)
03910             ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
03911          if (p->cidspill)
03912             free(p->cidspill);
03913          send_cwcidspill(p);
03914       }
03915       if ((f->subclass != 'm') && (f->subclass != 'u')) 
03916          p->callwaitcas = 0;
03917       p->subs[index].f.frametype = AST_FRAME_NULL;
03918       p->subs[index].f.subclass = 0;
03919       *dest = &p->subs[index].f;
03920    } else if (f->subclass == 'f') {
03921       /* Fax tone -- Handle and return NULL */
03922       if ((p->callprogress & 0x6) && !p->faxhandled) {
03923          p->faxhandled++;
03924          if (strcmp(ast->exten, "fax")) {
03925             const char *target_context = S_OR(ast->macrocontext, ast->context);
03926 
03927             if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
03928                if (option_verbose > 2)
03929                   ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
03930                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
03931                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
03932                if (ast_async_goto(ast, target_context, "fax", 1))
03933                   ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
03934             } else {
03935                 if (option_verbose > 2)
03936                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
03937             }
03938          } else if (option_debug)
03939             ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
03940       } else if (option_debug)
03941             ast_log(LOG_DEBUG, "Fax already handled\n");
03942       zt_confmute(p, 0);
03943       p->subs[index].f.frametype = AST_FRAME_NULL;
03944       p->subs[index].f.subclass = 0;
03945       *dest = &p->subs[index].f;
03946    } else if (f->subclass == 'm') {
03947       /* Confmute request */
03948       zt_confmute(p, 1);
03949       p->subs[index].f.frametype = AST_FRAME_NULL;
03950       p->subs[index].f.subclass = 0;
03951       *dest = &p->subs[index].f;    
03952    } else if (f->subclass == 'u') {
03953       /* Unmute */
03954       zt_confmute(p, 0);
03955       p->subs[index].f.frametype = AST_FRAME_NULL;
03956       p->subs[index].f.subclass = 0;
03957       *dest = &p->subs[index].f;    
03958    } else
03959       zt_confmute(p, 0);
03960 }
03961          
03962 static struct ast_frame *zt_handle_event(struct ast_channel *ast)
03963 {
03964    int res, x;
03965    int index, mysig;
03966    char *c;
03967    struct zt_pvt *p = ast->tech_pvt;
03968    pthread_t threadid;
03969    pthread_attr_t attr;
03970    struct ast_channel *chan;
03971    struct ast_frame *f;
03972 
03973    index = zt_get_index(ast, p, 0);
03974    mysig = p->sig;
03975    if (p->outsigmod > -1)
03976       mysig = p->outsigmod;
03977    p->subs[index].f.frametype = AST_FRAME_NULL;
03978    p->subs[index].f.subclass = 0;
03979    p->subs[index].f.datalen = 0;
03980    p->subs[index].f.samples = 0;
03981    p->subs[index].f.mallocd = 0;
03982    p->subs[index].f.offset = 0;
03983    p->subs[index].f.src = "zt_handle_event";
03984    p->subs[index].f.data = NULL;
03985    f = &p->subs[index].f;
03986 
03987    if (index < 0)
03988       return &p->subs[index].f;
03989    if (p->fake_event) {
03990       res = p->fake_event;
03991       p->fake_event = 0;
03992    } else
03993       res = zt_get_event(p->subs[index].zfd);
03994 
03995    if (option_debug)
03996       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
03997 
03998    if (res & (ZT_EVENT_PULSEDIGIT | ZT_EVENT_DTMFUP)) {
03999       p->pulsedial =  (res & ZT_EVENT_PULSEDIGIT) ? 1 : 0;
04000 
04001       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
04002 #ifdef HAVE_PRI
04003       if (!p->proceeding && p->sig == SIG_PRI && p->pri && p->pri->overlapdial) {
04004          /* absorb event */
04005       } else {
04006 #endif
04007          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
04008          p->subs[index].f.subclass = res & 0xff;
04009 #ifdef HAVE_PRI
04010       }
04011 #endif
04012       zt_handle_dtmfup(ast, index, &f);
04013       return f;
04014    }
04015 
04016    if (res & ZT_EVENT_DTMFDOWN) {
04017       if (option_debug)
04018          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
04019       /* Mute conference */
04020       zt_confmute(p, 1);
04021       p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
04022       p->subs[index].f.subclass = res & 0xff;
04023       return &p->subs[index].f;
04024    }
04025 
04026    switch (res) {
04027 #ifdef ZT_EVENT_EC_DISABLED
04028       case ZT_EVENT_EC_DISABLED:
04029          if (option_verbose > 2) 
04030             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
04031          p->echocanon = 0;
04032          break;
04033 #endif
04034       case ZT_EVENT_BITSCHANGED:
04035          ast_log(LOG_WARNING, "Recieved bits changed on %s signalling?\n", sig2str(p->sig));
04036       case ZT_EVENT_PULSE_START:
04037          /* Stop tone if there's a pulse start and the PBX isn't started */
04038          if (!ast->pbx)
04039             tone_zone_play_tone(p->subs[index].zfd, -1);
04040          break;   
04041       case ZT_EVENT_DIALCOMPLETE:
04042          if (p->inalarm) break;
04043          if ((p->radio || (p->oprmode < 0))) break;
04044          if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
04045             ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
04046             return NULL;
04047          }
04048          if (!x) { /* if not still dialing in driver */
04049             zt_enable_ec(p);
04050             if (p->echobreak) {
04051                zt_train_ec(p);
04052                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
04053                p->dop.op = ZT_DIAL_OP_REPLACE;
04054                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04055                p->echobreak = 0;
04056             } else {
04057                p->dialing = 0;
04058                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
04059                   /* if thru with dialing after offhook */
04060                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
04061                      ast_setstate(ast, AST_STATE_UP);
04062                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
04063                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04064                      break;
04065                   } else { /* if to state wait for offhook to dial rest */
04066                      /* we now wait for off hook */
04067                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
04068                   }
04069                }
04070                if (ast->_state == AST_STATE_DIALING) {
04071                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
04072                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
04073                   } 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)))) {
04074                      ast_setstate(ast, AST_STATE_RINGING);
04075                   } else if (!p->answeronpolarityswitch) {
04076                      ast_setstate(ast, AST_STATE_UP);
04077                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
04078                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04079                      /* If aops=0 and hops=1, this is necessary */
04080                      p->polarity = POLARITY_REV;
04081                   } else {
04082                      /* Start clean, so we can catch the change to REV polarity when party answers */
04083                      p->polarity = POLARITY_IDLE;
04084                   }
04085                }
04086             }
04087          }
04088          break;
04089       case ZT_EVENT_ALARM:
04090 #ifdef HAVE_PRI
04091          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
04092             /* T309 is not enabled : hangup calls when alarm occurs */
04093             if (p->call) {
04094                if (p->pri && p->pri->pri) {
04095                   if (!pri_grab(p, p->pri)) {
04096                      pri_hangup(p->pri->pri, p->call, -1, -1);
04097                      pri_destroycall(p->pri->pri, p->call);
04098                      p->call = NULL;
04099                      pri_rel(p->pri);
04100                   } else
04101                      ast_log(LOG_WARNING, "Failed to grab PRI!\n");
04102                } else
04103                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
04104             }
04105             if (p->owner)
04106                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04107          }
04108          if (p->bearer)
04109             p->bearer->inalarm = 1;
04110          else
04111 #endif
04112          p->inalarm = 1;
04113          res = get_alarms(p);
04114          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm2str(res));
04115          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
04116                         "Alarm: %s\r\n"
04117                         "Channel: %d\r\n",
04118                         alarm2str(res), p->channel);
04119 #ifdef HAVE_LIBPRI
04120          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
04121             /* fall through intentionally */
04122          } else {
04123             break;
04124          }
04125 #endif
04126       case ZT_EVENT_ONHOOK:
04127          if (p->radio) {
04128             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04129             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04130             break;
04131          }
04132          if (p->oprmode < 0)
04133          {
04134             if (p->oprmode != -1) break;
04135             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04136             {
04137                /* Make sure it starts ringing */
04138                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04139                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
04140                save_conference(p->oprpeer);
04141                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04142             }
04143             break;
04144          }
04145          switch (p->sig) {
04146          case SIG_FXOLS:
04147          case SIG_FXOGS:
04148          case SIG_FXOKS:
04149             p->onhooktime = time(NULL);
04150             p->msgstate = -1;
04151             /* Check for some special conditions regarding call waiting */
04152             if (index == SUB_REAL) {
04153                /* The normal line was hung up */
04154                if (p->subs[SUB_CALLWAIT].owner) {
04155                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
04156                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
04157                   if (option_verbose > 2) 
04158                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
04159                   unalloc_sub(p, SUB_CALLWAIT); 
04160 #if 0
04161                   p->subs[index].needanswer = 0;
04162                   p->subs[index].needringing = 0;
04163 #endif                  
04164                   p->callwaitingrepeat = 0;
04165                   p->cidcwexpire = 0;
04166                   p->owner = NULL;
04167                   /* Don't start streaming audio yet if the incoming call isn't up yet */
04168                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
04169                      p->dialing = 1;
04170                   zt_ring_phone(p);
04171                } else if (p->subs[SUB_THREEWAY].owner) {
04172                   unsigned int mssinceflash;
04173                   /* Here we have to retain the lock on both the main channel, the 3-way channel, and
04174                      the private structure -- not especially easy or clean */
04175                   while (p->subs[SUB_THREEWAY].owner && ast_mutex_trylock(&p->subs[SUB_THREEWAY].owner->lock)) {
04176                      /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
04177                      ast_mutex_unlock(&p->lock);
04178                      ast_mutex_unlock(&ast->lock);
04179                      usleep(1);
04180                      /* We can grab ast and p in that order, without worry.  We should make sure
04181                         nothing seriously bad has happened though like some sort of bizarre double
04182                         masquerade! */
04183                      ast_mutex_lock(&ast->lock);
04184                      ast_mutex_lock(&p->lock);
04185                      if (p->owner != ast) {
04186                         ast_log(LOG_WARNING, "This isn't good...\n");
04187                         return NULL;
04188                      }
04189                   }
04190                   if (!p->subs[SUB_THREEWAY].owner) {
04191                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
04192                      return NULL;
04193                   }
04194                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
04195                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
04196                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
04197                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
04198                         hanging up.  Hangup both channels now */
04199                      if (p->subs[SUB_THREEWAY].owner)
04200                         ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
04201                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04202                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
04203                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04204                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
04205                      if (p->transfer) {
04206                         /* In any case this isn't a threeway call anymore */
04207                         p->subs[SUB_REAL].inthreeway = 0;
04208                         p->subs[SUB_THREEWAY].inthreeway = 0;
04209                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
04210                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
04211                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04212                            /* Swap subs and dis-own channel */
04213                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
04214                            p->owner = NULL;
04215                            /* Ring the phone */
04216                            zt_ring_phone(p);
04217                         } else {
04218                            if ((res = attempt_transfer(p)) < 0) {
04219                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04220                               if (p->subs[SUB_THREEWAY].owner)
04221                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04222                            } else if (res) {
04223                               /* Don't actually hang up at this point */
04224                               if (p->subs[SUB_THREEWAY].owner)
04225                                  ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04226                               break;
04227                            }
04228                         }
04229                      } else {
04230                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04231                         if (p->subs[SUB_THREEWAY].owner)
04232                            ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04233                      }
04234                   } else {
04235                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04236                      /* Swap subs and dis-own channel */
04237                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04238                      p->owner = NULL;
04239                      /* Ring the phone */
04240                      zt_ring_phone(p);
04241                   }
04242                }
04243             } else {
04244                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
04245             }
04246             /* Fall through */
04247          default:
04248             zt_disable_ec(p);
04249             return NULL;
04250          }
04251          break;
04252       case ZT_EVENT_RINGOFFHOOK:
04253          if (p->inalarm) break;
04254          if (p->oprmode < 0)
04255          {
04256             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04257             {
04258                /* Make sure it stops ringing */
04259                zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
04260                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
04261                restore_conference(p->oprpeer);
04262             }
04263             break;
04264          }
04265          if (p->radio)
04266          {
04267             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04268             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04269             break;
04270          }
04271          /* for E911, its supposed to wait for offhook then dial
04272             the second half of the dial string */
04273          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04274             c = strchr(p->dialdest, '/');
04275             if (c)
04276                c++;
04277             else
04278                c = p->dialdest;
04279             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04280             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04281             if (strlen(p->dop.dialstr) > 4) {
04282                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04283                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04284                p->echorest[sizeof(p->echorest) - 1] = '\0';
04285                p->echobreak = 1;
04286                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04287             } else
04288                p->echobreak = 0;
04289             if (ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop)) {
04290                x = ZT_ONHOOK;
04291                ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
04292                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
04293                return NULL;
04294                }
04295             p->dialing = 1;
04296             return &p->subs[index].f;
04297          }
04298          switch (p->sig) {
04299          case SIG_FXOLS:
04300          case SIG_FXOGS:
04301          case SIG_FXOKS:
04302             switch (ast->_state) {
04303             case AST_STATE_RINGING:
04304                zt_enable_ec(p);
04305                zt_train_ec(p);
04306                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04307                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04308                /* Make sure it stops ringing */
04309                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04310                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04311                if (p->cidspill) {
04312                   /* Cancel any running CallerID spill */
04313                   free(p->cidspill);
04314                   p->cidspill = NULL;
04315                }
04316                p->dialing = 0;
04317                p->callwaitcas = 0;
04318                if (p->confirmanswer) {
04319                   /* Ignore answer if "confirm answer" is enabled */
04320                   p->subs[index].f.frametype = AST_FRAME_NULL;
04321                   p->subs[index].f.subclass = 0;
04322                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04323                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04324                   res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04325                   if (res < 0) {
04326                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04327                      p->dop.dialstr[0] = '\0';
04328                      return NULL;
04329                   } else {
04330                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04331                      p->subs[index].f.frametype = AST_FRAME_NULL;
04332                      p->subs[index].f.subclass = 0;
04333                      p->dialing = 1;
04334                   }
04335                   p->dop.dialstr[0] = '\0';
04336                   ast_setstate(ast, AST_STATE_DIALING);
04337                } else
04338                   ast_setstate(ast, AST_STATE_UP);
04339                return &p->subs[index].f;
04340             case AST_STATE_DOWN:
04341                ast_setstate(ast, AST_STATE_RING);
04342                ast->rings = 1;
04343                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04344                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04345                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04346                return &p->subs[index].f;
04347             case AST_STATE_UP:
04348                /* Make sure it stops ringing */
04349                zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
04350                /* Okay -- probably call waiting*/
04351                if (ast_bridged_channel(p->owner))
04352                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04353                p->subs[index].needunhold = 1;
04354                break;
04355             case AST_STATE_RESERVED:
04356                /* Start up dialtone */
04357                if (has_voicemail(p))
04358                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
04359                else
04360                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
04361                break;
04362             default:
04363                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04364             }
04365             break;
04366          case SIG_FXSLS:
04367          case SIG_FXSGS:
04368          case SIG_FXSKS:
04369             if (ast->_state == AST_STATE_RING) {
04370                p->ringt = p->ringt_base;
04371             }
04372 
04373             /* Fall through */
04374          case SIG_EM:
04375          case SIG_EM_E1:
04376          case SIG_EMWINK:
04377          case SIG_FEATD:
04378          case SIG_FEATDMF:
04379          case SIG_FEATDMF_TA:
04380          case SIG_E911:
04381          case SIG_FGC_CAMA:
04382          case SIG_FGC_CAMAMF:
04383          case SIG_FEATB:
04384          case SIG_SF:
04385          case SIG_SFWINK:
04386          case SIG_SF_FEATD:
04387          case SIG_SF_FEATDMF:
04388          case SIG_SF_FEATB:
04389             if (ast->_state == AST_STATE_PRERING)
04390                ast_setstate(ast, AST_STATE_RING);
04391             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04392                if (option_debug)
04393                   ast_log(LOG_DEBUG, "Ring detected\n");
04394                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04395                p->subs[index].f.subclass = AST_CONTROL_RING;
04396             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04397                if (option_debug)
04398                   ast_log(LOG_DEBUG, "Line answered\n");
04399                if (p->confirmanswer) {
04400                   p->subs[index].f.frametype = AST_FRAME_NULL;
04401                   p->subs[index].f.subclass = 0;
04402                } else {
04403                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04404                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04405                   ast_setstate(ast, AST_STATE_UP);
04406                }
04407             } else if (ast->_state != AST_STATE_RING)
04408                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04409             break;
04410          default:
04411             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04412          }
04413          break;
04414 #ifdef ZT_EVENT_RINGBEGIN
04415       case ZT_EVENT_RINGBEGIN:
04416          switch (p->sig) {
04417          case SIG_FXSLS:
04418          case SIG_FXSGS:
04419          case SIG_FXSKS:
04420             if (ast->_state == AST_STATE_RING) {
04421                p->ringt = p->ringt_base;
04422             }
04423             break;
04424          }
04425          break;
04426 #endif         
04427       case ZT_EVENT_RINGEROFF:
04428          if (p->inalarm) break;
04429          if ((p->radio || (p->oprmode < 0))) break;
04430          ast->rings++;
04431          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04432             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04433             free(p->cidspill);
04434             p->cidspill = NULL;
04435             p->callwaitcas = 0;
04436          }
04437          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04438          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04439          break;
04440       case ZT_EVENT_RINGERON:
04441          break;
04442       case ZT_EVENT_NOALARM:
04443          p->inalarm = 0;
04444 #ifdef HAVE_PRI
04445          /* Extremely unlikely but just in case */
04446          if (p->bearer)
04447             p->bearer->inalarm = 0;
04448 #endif            
04449          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04450          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04451                         "Channel: %d\r\n", p->channel);
04452          break;
04453       case ZT_EVENT_WINKFLASH:
04454          if (p->inalarm) break;
04455          if (p->radio) break;
04456          if (p->oprmode < 0) break;
04457          if (p->oprmode > 1)
04458          {
04459             struct zt_params par;
04460 
04461             if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
04462             {
04463                if (!par.rxisoffhook)
04464                {
04465                   /* Make sure it stops ringing */
04466                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
04467                   zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
04468                   save_conference(p);
04469                   tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04470                }
04471             }
04472             break;
04473          }
04474          /* Remember last time we got a flash-hook */
04475          gettimeofday(&p->flashtime, NULL);
04476          switch (mysig) {
04477          case SIG_FXOLS:
04478          case SIG_FXOGS:
04479          case SIG_FXOKS:
04480             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04481                index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
04482             p->callwaitcas = 0;
04483 
04484             if (index != SUB_REAL) {
04485                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04486                goto winkflashdone;
04487             }
04488             
04489             if (p->subs[SUB_CALLWAIT].owner) {
04490                /* Swap to call-wait */
04491                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04492                tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
04493                p->owner = p->subs[SUB_REAL].owner;
04494                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04495                if (p->owner->_state == AST_STATE_RINGING) {
04496                   ast_setstate(p->owner, AST_STATE_UP);
04497                   p->subs[SUB_REAL].needanswer = 1;
04498                }
04499                p->callwaitingrepeat = 0;
04500                p->cidcwexpire = 0;
04501                /* Start music on hold if appropriate */
04502                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04503                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04504                      S_OR(p->mohsuggest, NULL),
04505                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04506                }
04507                p->subs[SUB_CALLWAIT].needhold = 1;
04508                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04509                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04510                      S_OR(p->mohsuggest, NULL),
04511                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04512                }
04513                p->subs[SUB_REAL].needunhold = 1;
04514             } else if (!p->subs[SUB_THREEWAY].owner) {
04515                char cid_num[256];
04516                char cid_name[256];
04517 
04518                if (!p->threewaycalling) {
04519                   /* Just send a flash if no 3-way calling */
04520                   p->subs[SUB_REAL].needflash = 1;
04521                   goto winkflashdone;
04522                } else if (!check_for_conference(p)) {
04523                   if (p->zaptrcallerid && p->owner) {
04524                      if (p->owner->cid.cid_num)
04525                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
04526                      if (p->owner->cid.cid_name)
04527                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
04528                   }
04529                   /* XXX This section needs much more error checking!!! XXX */
04530                   /* Start a 3-way call if feasible */
04531                   if (!((ast->pbx) ||
04532                         (ast->_state == AST_STATE_UP) ||
04533                         (ast->_state == AST_STATE_RING))) {
04534                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
04535                         goto winkflashdone;
04536                   }
04537                   if (alloc_sub(p, SUB_THREEWAY)) {
04538                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
04539                      goto winkflashdone;
04540                   }
04541                   /* Make new channel */
04542                   chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
04543                   if (p->zaptrcallerid) {
04544                      if (!p->origcid_num)
04545                         p->origcid_num = ast_strdup(p->cid_num);
04546                      if (!p->origcid_name)
04547                         p->origcid_name = ast_strdup(p->cid_name);
04548                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
04549                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
04550                   }
04551                   /* Swap things around between the three-way and real call */
04552                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
04553                   /* Disable echo canceller for better dialing */
04554                   zt_disable_ec(p);
04555                   res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_DIALRECALL);
04556                   if (res)
04557                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
04558                   p->owner = chan;
04559                   pthread_attr_init(&attr);
04560                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04561                   if (!chan) {
04562                      ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
04563                   } else if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
04564                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
04565                      res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
04566                      zt_enable_ec(p);
04567                      ast_hangup(chan);
04568                   } else {
04569                      if (option_verbose > 2) 
04570                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
04571                      /* Start music on hold if appropriate */
04572                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04573                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
04574                            S_OR(p->mohsuggest, NULL),
04575                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04576                      }
04577                      p->subs[SUB_THREEWAY].needhold = 1;
04578                   }
04579                   pthread_attr_destroy(&attr);
04580                }
04581             } else {
04582                /* Already have a 3 way call */
04583                if (p->subs[SUB_THREEWAY].inthreeway) {
04584                   /* Call is already up, drop the last person */
04585                   if (option_debug)
04586                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
04587                   /* If the primary call isn't answered yet, use it */
04588                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
04589                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
04590                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04591                      p->owner = p->subs[SUB_REAL].owner;
04592                   }
04593                   /* Drop the last call and stop the conference */
04594                   if (option_verbose > 2)
04595                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
04596                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04597                   p->subs[SUB_REAL].inthreeway = 0;
04598                   p->subs[SUB_THREEWAY].inthreeway = 0;
04599                } else {
04600                   /* Lets see what we're up to */
04601                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
04602                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
04603                      int otherindex = SUB_THREEWAY;
04604 
04605                      if (option_verbose > 2)
04606                         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);
04607                      /* Put them in the threeway, and flip */
04608                      p->subs[SUB_THREEWAY].inthreeway = 1;
04609                      p->subs[SUB_REAL].inthreeway = 1;
04610                      if (ast->_state == AST_STATE_UP) {
04611                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
04612                         otherindex = SUB_REAL;
04613                      }
04614                      if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
04615                         ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
04616                      p->subs[otherindex].needunhold = 1;
04617                      p->owner = p->subs[SUB_REAL].owner;
04618                      if (ast->_state == AST_STATE_RINGING) {
04619                         ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
04620                         res = tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
04621                         res = tone_zone_play_tone(p->subs[SUB_THREEWAY].zfd, ZT_TONE_RINGTONE);
04622                      }
04623                   } else {
04624                      if (option_verbose > 2)
04625                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
04626                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04627                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04628                      p->owner = p->subs[SUB_REAL].owner;
04629                      if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
04630                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04631                      p->subs[SUB_REAL].needunhold = 1;
04632                      zt_enable_ec(p);
04633                   }
04634                      
04635                }
04636             }
04637          winkflashdone:              
04638             update_conf(p);
04639             break;
04640          case SIG_EM:
04641          case SIG_EM_E1:
04642          case SIG_EMWINK:
04643          case SIG_FEATD:
04644          case SIG_SF:
04645          case SIG_SFWINK:
04646          case SIG_SF_FEATD:
04647          case SIG_FXSLS:
04648          case SIG_FXSGS:
04649             if (p->dialing)
04650                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
04651             else
04652                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
04653             break;
04654          case SIG_FEATDMF_TA:
04655             switch (p->whichwink) {
04656             case 0:
04657                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04658                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
04659                break;
04660             case 1:
04661                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
04662                break;
04663             case 2:
04664                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
04665                return NULL;
04666             }
04667             p->whichwink++;
04668             /* Fall through */
04669          case SIG_FEATDMF:
04670          case SIG_E911:
04671          case SIG_FGC_CAMAMF:
04672          case SIG_FGC_CAMA:
04673          case SIG_FEATB:
04674          case SIG_SF_FEATDMF:
04675          case SIG_SF_FEATB:
04676             /* FGD MF *Must* wait for wink */
04677             if (!ast_strlen_zero(p->dop.dialstr))
04678                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04679             else if (res < 0) {
04680                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04681                p->dop.dialstr[0] = '\0';
04682                return NULL;
04683             } else 
04684                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04685             p->dop.dialstr[0] = '\0';
04686             break;
04687          default:
04688             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
04689          }
04690          break;
04691       case ZT_EVENT_HOOKCOMPLETE:
04692          if (p->inalarm) break;
04693          if ((p->radio || (p->oprmode < 0))) break;
04694          switch (mysig) {
04695          case SIG_FXSLS:  /* only interesting for FXS */
04696          case SIG_FXSGS:
04697          case SIG_FXSKS:
04698          case SIG_EM:
04699          case SIG_EM_E1:
04700          case SIG_EMWINK:
04701          case SIG_FEATD:
04702          case SIG_SF:
04703          case SIG_SFWINK:
04704          case SIG_SF_FEATD:
04705             if (!ast_strlen_zero(p->dop.dialstr)) 
04706                res = ioctl(p->subs[SUB_REAL].zfd, ZT_DIAL, &p->dop);
04707             else if (res < 0) {
04708                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
04709                p->dop.dialstr[0] = '\0';
04710                return NULL;
04711             } else 
04712                ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
04713             p->dop.dialstr[0] = '\0';
04714             p->dop.op = ZT_DIAL_OP_REPLACE;
04715             break;
04716          case SIG_FEATDMF:
04717          case SIG_FEATDMF_TA:
04718          case SIG_E911:
04719          case SIG_FGC_CAMA:
04720          case SIG_FGC_CAMAMF:
04721          case SIG_FEATB:
04722          case SIG_SF_FEATDMF:
04723          case SIG_SF_FEATB:
04724             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
04725             break;
04726          default:
04727             break;
04728          }
04729          break;
04730       case ZT_EVENT_POLARITY:
04731          /*
04732           * If we get a Polarity Switch event, check to see
04733           * if we should change the polarity state and
04734           * mark the channel as UP or if this is an indication
04735           * of remote end disconnect.
04736           */
04737          if (p->polarity == POLARITY_IDLE) {
04738             p->polarity = POLARITY_REV;
04739             if (p->answeronpolarityswitch &&
04740                 ((ast->_state == AST_STATE_DIALING) ||
04741                 (ast->_state == AST_STATE_RINGING))) {
04742                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
04743                ast_setstate(p->owner, AST_STATE_UP);
04744                if (p->hanguponpolarityswitch) {
04745                   gettimeofday(&p->polaritydelaytv, NULL);
04746                }
04747             } else
04748                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
04749          } 
04750          /* Removed else statement from here as it was preventing hangups from ever happening*/
04751          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
04752          if (p->hanguponpolarityswitch &&
04753             (p->polarityonanswerdelay > 0) &&
04754                 (p->polarity == POLARITY_REV) &&
04755             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
04756                                 /* Added log_debug information below to provide a better indication of what is going on */
04757             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) );
04758          
04759             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
04760                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
04761                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
04762                p->polarity = POLARITY_IDLE;
04763             } else {
04764                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);
04765             }
04766          } else {
04767             p->polarity = POLARITY_IDLE;
04768             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
04769          }
04770                         /* Added more log_debug information below to provide a better indication of what is going on */
04771          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) );
04772          break;
04773       default:
04774          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
04775    }
04776    return &p->subs[index].f;
04777 }
04778 
04779 static struct ast_frame *__zt_exception(struct ast_channel *ast)
04780 {
04781    struct zt_pvt *p = ast->tech_pvt;
04782    int res;
04783    int usedindex=-1;
04784    int index;
04785    struct ast_frame *f;
04786 
04787 
04788    index = zt_get_index(ast, p, 1);
04789    
04790    p->subs[index].f.frametype = AST_FRAME_NULL;
04791    p->subs[index].f.datalen = 0;
04792    p->subs[index].f.samples = 0;
04793    p->subs[index].f.mallocd = 0;
04794    p->subs[index].f.offset = 0;
04795    p->subs[index].f.subclass = 0;
04796    p->subs[index].f.delivery = ast_tv(0,0);
04797    p->subs[index].f.src = "zt_exception";
04798    p->subs[index].f.data = NULL;
04799    
04800    
04801    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
04802       /* If nobody owns us, absorb the event appropriately, otherwise
04803          we loop indefinitely.  This occurs when, during call waiting, the
04804          other end hangs up our channel so that it no longer exists, but we
04805          have neither FLASH'd nor ONHOOK'd to signify our desire to
04806          change to the other channel. */
04807       if (p->fake_event) {
04808          res = p->fake_event;
04809          p->fake_event = 0;
04810       } else
04811          res = zt_get_event(p->subs[SUB_REAL].zfd);
04812       /* Switch to real if there is one and this isn't something really silly... */
04813       if ((res != ZT_EVENT_RINGEROFF) && (res != ZT_EVENT_RINGERON) &&
04814          (res != ZT_EVENT_HOOKCOMPLETE)) {
04815          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
04816          p->owner = p->subs[SUB_REAL].owner;
04817          if (p->owner && ast_bridged_channel(p->owner))
04818             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04819          p->subs[SUB_REAL].needunhold = 1;
04820       }
04821       switch (res) {
04822       case ZT_EVENT_ONHOOK:
04823          zt_disable_ec(p);
04824          if (p->owner) {
04825             if (option_verbose > 2) 
04826                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
04827             zt_ring_phone(p);
04828             p->callwaitingrepeat = 0;
04829             p->cidcwexpire = 0;
04830          } else
04831             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04832          update_conf(p);
04833          break;
04834       case ZT_EVENT_RINGOFFHOOK:
04835          zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
04836          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
04837             p->subs[SUB_REAL].needanswer = 1;
04838             p->dialing = 0;
04839          }
04840          break;
04841       case ZT_EVENT_HOOKCOMPLETE:
04842       case ZT_EVENT_RINGERON:
04843       case ZT_EVENT_RINGEROFF:
04844          /* Do nothing */
04845          break;
04846       case ZT_EVENT_WINKFLASH:
04847          gettimeofday(&p->flashtime, NULL);
04848          if (p->owner) {
04849             if (option_verbose > 2) 
04850                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
04851             if (p->owner->_state != AST_STATE_UP) {
04852                /* Answer if necessary */
04853                usedindex = zt_get_index(p->owner, p, 0);
04854                if (usedindex > -1) {
04855                   p->subs[usedindex].needanswer = 1;
04856                }
04857                ast_setstate(p->owner, AST_STATE_UP);
04858             }
04859             p->callwaitingrepeat = 0;
04860             p->cidcwexpire = 0;
04861             if (ast_bridged_channel(p->owner))
04862                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04863             p->subs[SUB_REAL].needunhold = 1;
04864          } else
04865             ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
04866          update_conf(p);
04867          break;
04868       default:
04869          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
04870       }
04871       f = &p->subs[index].f;
04872       return f;
04873    }
04874    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
04875       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
04876    /* If it's not us, return NULL immediately */
04877    if (ast != p->owner) {
04878       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
04879       f = &p->subs[index].f;
04880       return f;
04881    }
04882    f = zt_handle_event(ast);
04883    return f;
04884 }
04885 
04886 static struct ast_frame *zt_exception(struct ast_channel *ast)
04887 {
04888    struct zt_pvt *p = ast->tech_pvt;
04889    struct ast_frame *f;
04890    ast_mutex_lock(&p->lock);
04891    f = __zt_exception(ast);
04892    ast_mutex_unlock(&p->lock);
04893    return f;
04894 }
04895 
04896 static struct ast_frame  *zt_read(struct ast_channel *ast)
04897 {
04898    struct zt_pvt *p = ast->tech_pvt;
04899    int res;
04900    int index;
04901    void *readbuf;
04902    struct ast_frame *f;
04903    
04904 
04905    ast_mutex_lock(&p->lock);
04906    
04907    index = zt_get_index(ast, p, 0);
04908    
04909    /* Hang up if we don't really exist */
04910    if (index < 0) {
04911       ast_log(LOG_WARNING, "We dont exist?\n");
04912       ast_mutex_unlock(&p->lock);
04913       return NULL;
04914    }
04915    
04916    if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
04917 
04918    p->subs[index].f.frametype = AST_FRAME_NULL;
04919    p->subs[index].f.datalen = 0;
04920    p->subs[index].f.samples = 0;
04921    p->subs[index].f.mallocd = 0;
04922    p->subs[index].f.offset = 0;
04923    p->subs[index].f.subclass = 0;
04924    p->subs[index].f.delivery = ast_tv(0,0);
04925    p->subs[index].f.src = "zt_read";
04926    p->subs[index].f.data = NULL;
04927    
04928    /* make sure it sends initial key state as first frame */
04929    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
04930    {
04931       ZT_PARAMS ps;
04932 
04933       ps.channo = p->channel;
04934       if (ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
04935          ast_mutex_unlock(&p->lock);
04936          return NULL;
04937       }
04938       p->firstradio = 1;
04939       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04940       if (ps.rxisoffhook)
04941       {
04942          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04943       }
04944       else
04945       {
04946          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04947       }
04948       ast_mutex_unlock(&p->lock);
04949       return &p->subs[index].f;
04950    }
04951    if (p->ringt == 1) {
04952       ast_mutex_unlock(&p->lock);
04953       return NULL;
04954    }
04955    else if (p->ringt > 0) 
04956       p->ringt--;
04957 
04958    if (p->subs[index].needringing) {
04959       /* Send ringing frame if requested */
04960       p->subs[index].needringing = 0;
04961       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04962       p->subs[index].f.subclass = AST_CONTROL_RINGING;
04963       ast_setstate(ast, AST_STATE_RINGING);
04964       ast_mutex_unlock(&p->lock);
04965       return &p->subs[index].f;
04966    }
04967 
04968    if (p->subs[index].needbusy) {
04969       /* Send busy frame if requested */
04970       p->subs[index].needbusy = 0;
04971       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04972       p->subs[index].f.subclass = AST_CONTROL_BUSY;
04973       ast_mutex_unlock(&p->lock);
04974       return &p->subs[index].f;
04975    }
04976 
04977    if (p->subs[index].needcongestion) {
04978       /* Send congestion frame if requested */
04979       p->subs[index].needcongestion = 0;
04980       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04981       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
04982       ast_mutex_unlock(&p->lock);
04983       return &p->subs[index].f;
04984    }
04985 
04986    if (p->subs[index].needcallerid) {
04987       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
04988                      S_OR(p->lastcid_name, NULL),
04989                      S_OR(p->lastcid_num, NULL)
04990                      );
04991       p->subs[index].needcallerid = 0;
04992    }
04993    
04994    if (p->subs[index].needanswer) {
04995       /* Send answer frame if requested */
04996       p->subs[index].needanswer = 0;
04997       p->subs[index].f.frametype = AST_FRAME_CONTROL;
04998       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04999       ast_mutex_unlock(&p->lock);
05000       return &p->subs[index].f;
05001    }  
05002    
05003    if (p->subs[index].needflash) {
05004       /* Send answer frame if requested */
05005       p->subs[index].needflash = 0;
05006       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05007       p->subs[index].f.subclass = AST_CONTROL_FLASH;
05008       ast_mutex_unlock(&p->lock);
05009       return &p->subs[index].f;
05010    }  
05011    
05012    if (p->subs[index].needhold) {
05013       /* Send answer frame if requested */
05014       p->subs[index].needhold = 0;
05015       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05016       p->subs[index].f.subclass = AST_CONTROL_HOLD;
05017       ast_mutex_unlock(&p->lock);
05018       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
05019       return &p->subs[index].f;
05020    }  
05021    
05022    if (p->subs[index].needunhold) {
05023       /* Send answer frame if requested */
05024       p->subs[index].needunhold = 0;
05025       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05026       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
05027       ast_mutex_unlock(&p->lock);
05028       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
05029       return &p->subs[index].f;
05030    }  
05031    
05032    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
05033       if (!p->subs[index].linear) {
05034          p->subs[index].linear = 1;
05035          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05036          if (res) 
05037             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
05038       }
05039    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
05040          (ast->rawreadformat == AST_FORMAT_ALAW)) {
05041       if (p->subs[index].linear) {
05042          p->subs[index].linear = 0;
05043          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05044          if (res) 
05045             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
05046       }
05047    } else {
05048       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
05049       ast_mutex_unlock(&p->lock);
05050       return NULL;
05051    }
05052    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
05053    CHECK_BLOCKING(ast);
05054    res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
05055    ast_clear_flag(ast, AST_FLAG_BLOCKING);
05056    /* Check for hangup */
05057    if (res < 0) {
05058       f = NULL;
05059       if (res == -1)  {
05060          if (errno == EAGAIN) {
05061             /* Return "NULL" frame if there is nobody there */
05062             ast_mutex_unlock(&p->lock);
05063             return &p->subs[index].f;
05064          } else if (errno == ELAST) {
05065             f = __zt_exception(ast);
05066          } else
05067             ast_log(LOG_WARNING, "zt_rec: %s\n", strerror(errno));
05068       }
05069       ast_mutex_unlock(&p->lock);
05070       return f;
05071    }
05072    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
05073       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
05074       f = __zt_exception(ast);
05075       ast_mutex_unlock(&p->lock);
05076       return f;
05077    }
05078    if (p->tdd) { /* if in TDD mode, see if we receive that */
05079       int c;
05080 
05081       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
05082       if (c < 0) {
05083          ast_log(LOG_DEBUG,"tdd_feed failed\n");
05084          ast_mutex_unlock(&p->lock);
05085          return NULL;
05086       }
05087       if (c) { /* if a char to return */
05088          p->subs[index].f.subclass = 0;
05089          p->subs[index].f.frametype = AST_FRAME_TEXT;
05090          p->subs[index].f.mallocd = 0;
05091          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05092          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
05093          p->subs[index].f.datalen = 1;
05094          *((char *) p->subs[index].f.data) = c;
05095          ast_mutex_unlock(&p->lock);
05096          return &p->subs[index].f;
05097       }
05098    }
05099    if (p->callwaitingrepeat)
05100       p->callwaitingrepeat--;
05101    if (p->cidcwexpire)
05102       p->cidcwexpire--;
05103    /* Repeat callwaiting */
05104    if (p->callwaitingrepeat == 1) {
05105       p->callwaitrings++;
05106       zt_callwait(ast);
05107    }
05108    /* Expire CID/CW */
05109    if (p->cidcwexpire == 1) {
05110       if (option_verbose > 2)
05111          ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
05112       restore_conference(p);
05113    }
05114    if (p->subs[index].linear) {
05115       p->subs[index].f.datalen = READ_SIZE * 2;
05116    } else 
05117       p->subs[index].f.datalen = READ_SIZE;
05118 
05119    /* Handle CallerID Transmission */
05120    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
05121       send_callerid(p);
05122    }
05123 
05124    p->subs[index].f.frametype = AST_FRAME_VOICE;
05125    p->subs[index].f.subclass = ast->rawreadformat;
05126    p->subs[index].f.samples = READ_SIZE;
05127    p->subs[index].f.mallocd = 0;
05128    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05129    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
05130 #if 0
05131    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
05132 #endif   
05133    if (p->dialing || /* Transmitting something */
05134       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
05135       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
05136       ) {
05137       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
05138          don't send anything */
05139       p->subs[index].f.frametype = AST_FRAME_NULL;
05140       p->subs[index].f.subclass = 0;
05141       p->subs[index].f.samples = 0;
05142       p->subs[index].f.mallocd = 0;
05143       p->subs[index].f.offset = 0;
05144       p->subs[index].f.data = NULL;
05145       p->subs[index].f.datalen= 0;
05146    }
05147    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
05148       /* Perform busy detection. etc on the zap line */
05149       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
05150       if (f) {
05151          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
05152             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
05153                /* Treat this as a "hangup" instead of a "busy" on the assumption that
05154                   a busy  */
05155                f = NULL;
05156             }
05157          } else if (f->frametype == AST_FRAME_DTMF) {
05158 #ifdef HAVE_PRI
05159             if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) {
05160                /* Don't accept in-band DTMF when in overlap dial mode 
05161                   or when in non-overlap overlapdialing mode ... */
05162                f->frametype = AST_FRAME_NULL;
05163                f->subclass = 0;
05164             }
05165 #endif            
05166             /* DSP clears us of being pulse */
05167             p->pulsedial = 0;
05168          }
05169       }
05170    } else 
05171       f = &p->subs[index].f; 
05172 
05173    if (f && (f->frametype == AST_FRAME_DTMF))
05174       zt_handle_dtmfup(ast, index, &f);
05175 
05176    /* If we have a fake_event, trigger exception to handle it */
05177    if (p->fake_event)
05178       ast_set_flag(ast, AST_FLAG_EXCEPTION);
05179 
05180    ast_mutex_unlock(&p->lock);
05181    return f;
05182 }
05183 
05184 static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index, int linear)
05185 {
05186    int sent=0;
05187    int size;
05188    int res;
05189    int fd;
05190    fd = p->subs[index].zfd;
05191    while (len) {
05192       size = len;
05193       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
05194          size = (linear ? READ_SIZE * 2 : READ_SIZE);
05195       res = write(fd, buf, size);
05196       if (res != size) {
05197          if (option_debug)
05198             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
05199          return sent;
05200       }
05201       len -= size;
05202       buf += size;
05203    }
05204    return sent;
05205 }
05206 
05207 static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
05208 {
05209    struct zt_pvt *p = ast->tech_pvt;
05210    int res;
05211    int index;
05212    index = zt_get_index(ast, p, 0);
05213    if (index < 0) {
05214       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
05215       return -1;
05216    }
05217 
05218 #if 0
05219 #ifdef HAVE_PRI
05220    ast_mutex_lock(&p->lock);
05221    if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05222       if (p->pri->pri) {      
05223          if (!pri_grab(p, p->pri)) {
05224                pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05225                pri_rel(p->pri);
05226          } else
05227                ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05228       }
05229       p->proceeding=1;
05230    }
05231    ast_mutex_unlock(&p->lock);
05232 #endif
05233 #endif
05234    /* Write a frame of (presumably voice) data */
05235    if (frame->frametype != AST_FRAME_VOICE) {
05236       if (frame->frametype == AST_FRAME_TEXT) {
05237          ast_log(LOG_NOTICE, "text\n");
05238       } else if (frame->frametype != AST_FRAME_IMAGE)
05239          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
05240       return 0;
05241    }
05242    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
05243        (frame->subclass != AST_FORMAT_ULAW) &&
05244        (frame->subclass != AST_FORMAT_ALAW)) {
05245       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
05246       return -1;
05247    }
05248    if (p->dialing) {
05249       if (option_debug)
05250          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
05251       return 0;
05252    }
05253    if (!p->owner) {
05254       if (option_debug)
05255          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
05256       return 0;
05257    }
05258    if (p->cidspill) {
05259       if (option_debug)
05260          ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
05261       return 0;
05262    }
05263    /* Return if it's not valid data */
05264    if (!frame->data || !frame->datalen)
05265       return 0;
05266 
05267    if (frame->subclass == AST_FORMAT_SLINEAR) {
05268       if (!p->subs[index].linear) {
05269          p->subs[index].linear = 1;
05270          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05271          if (res)
05272             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05273       }
05274       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05275    } else {
05276       /* x-law already */
05277       if (p->subs[index].linear) {
05278          p->subs[index].linear = 0;
05279          res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
05280          if (res)
05281             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05282       }
05283       res = my_zt_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05284    }
05285    if (res < 0) {
05286       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05287       return -1;
05288    } 
05289    return 0;
05290 }
05291 
05292 static int zt_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05293 {
05294    struct zt_pvt *p = chan->tech_pvt;
05295    int res=-1;
05296    int index;
05297    int func = ZT_FLASH;
05298    ast_mutex_lock(&p->lock);
05299    index = zt_get_index(chan, p, 0);
05300    if (option_debug)
05301       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05302    if (index == SUB_REAL) {
05303       switch (condition) {
05304       case AST_CONTROL_BUSY:
05305 #ifdef HAVE_PRI
05306          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05307             chan->hangupcause = AST_CAUSE_USER_BUSY;
05308             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05309             res = 0;
05310          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05311             if (p->pri->pri) {      
05312                if (!pri_grab(p, p->pri)) {
05313                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05314                   pri_rel(p->pri);
05315                }
05316                else
05317                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05318             }
05319             p->progress = 1;
05320             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05321          } else
05322 #endif
05323             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_BUSY);
05324          break;
05325       case AST_CONTROL_RINGING:
05326 #ifdef HAVE_PRI
05327          if ((!p->alerting) && p->sig==SIG_PRI && p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
05328             if (p->pri->pri) {      
05329                if (!pri_grab(p, p->pri)) {
05330                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05331                   pri_rel(p->pri);
05332                }
05333                else
05334                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05335             }
05336             p->alerting = 1;
05337          }
05338 #endif
05339          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_RINGTONE);
05340          if (chan->_state != AST_STATE_UP) {
05341             if ((chan->_state != AST_STATE_RING) ||
05342                ((p->sig != SIG_FXSKS) &&
05343                 (p->sig != SIG_FXSLS) &&
05344                 (p->sig != SIG_FXSGS)))
05345                ast_setstate(chan, AST_STATE_RINGING);
05346          }
05347          break;
05348       case AST_CONTROL_PROCEEDING:
05349          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05350 #ifdef HAVE_PRI
05351          if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05352             if (p->pri->pri) {      
05353                if (!pri_grab(p, p->pri)) {
05354                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05355                   pri_rel(p->pri);
05356                }
05357                else
05358                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05359             }
05360             p->proceeding = 1;
05361          }
05362 #endif
05363          /* don't continue in ast_indicate */
05364          res = 0;
05365          break;
05366       case AST_CONTROL_PROGRESS:
05367          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05368 #ifdef HAVE_PRI
05369          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05370          if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05371             if (p->pri->pri) {      
05372                if (!pri_grab(p, p->pri)) {
05373                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05374                   pri_rel(p->pri);
05375                }
05376                else
05377                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05378             }
05379             p->progress = 1;
05380          }
05381 #endif
05382          /* don't continue in ast_indicate */
05383          res = 0;
05384          break;
05385       case AST_CONTROL_CONGESTION:
05386          chan->hangupcause = AST_CAUSE_CONGESTION;
05387 #ifdef HAVE_PRI
05388          if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
05389             chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05390             chan->_softhangup |= AST_SOFTHANGUP_DEV;
05391             res = 0;
05392          } else if (!p->progress && p->sig==SIG_PRI && p->pri && !p->outgoing) {
05393             if (p->pri) {     
05394                if (!pri_grab(p, p->pri)) {
05395                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05396                   pri_rel(p->pri);
05397                } else
05398                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05399             }
05400             p->progress = 1;
05401             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05402          } else
05403 #endif
05404             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
05405          break;
05406       case AST_CONTROL_HOLD:
05407 #ifdef HAVE_PRI
05408          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05409             if (!pri_grab(p, p->pri)) {
05410                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
05411                pri_rel(p->pri);
05412             } else
05413                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05414          } else
05415 #endif
05416             ast_moh_start(chan, data, p->mohinterpret);
05417          break;
05418       case AST_CONTROL_UNHOLD:
05419 #ifdef HAVE_PRI
05420          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
05421             if (!pri_grab(p, p->pri)) {
05422                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
05423                pri_rel(p->pri);
05424             } else
05425                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
05426          } else
05427 #endif
05428             ast_moh_stop(chan);
05429          break;
05430       case AST_CONTROL_RADIO_KEY:
05431          if (p->radio) 
05432              res =  zt_set_hook(p->subs[index].zfd, ZT_OFFHOOK);
05433          res = 0;
05434          break;
05435       case AST_CONTROL_RADIO_UNKEY:
05436          if (p->radio)
05437              res =  zt_set_hook(p->subs[index].zfd, ZT_RINGOFF);
05438          res = 0;
05439          break;
05440       case AST_CONTROL_FLASH:
05441          /* flash hookswitch */
05442          if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
05443             /* Clear out the dial buffer */
05444             p->dop.dialstr[0] = '\0';
05445             if ((ioctl(p->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
05446                ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
05447                   chan->name, strerror(errno));
05448             } else
05449                res = 0;
05450          } else
05451             res = 0;
05452          break;
05453       case -1:
05454          res = tone_zone_play_tone(p->subs[index].zfd, -1);
05455          break;
05456       }
05457    } else
05458       res = 0;
05459    ast_mutex_unlock(&p->lock);
05460    return res;
05461 }
05462 
05463 static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
05464 {
05465    struct ast_channel *tmp;
05466    int deflaw;
05467    int res;
05468    int x,y;
05469    int features;
05470    char *b2 = NULL;
05471    ZT_PARAMS ps;
05472    if (i->subs[index].owner) {
05473       ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
05474       return NULL;
05475    }
05476    y = 1;
05477    do {
05478       if (b2)
05479          free(b2);
05480 #ifdef HAVE_PRI
05481       if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
05482          b2 = ast_safe_string_alloc("%d:%d-%d", i->pri->trunkgroup, i->channel, y);
05483       else
05484 #endif
05485       if (i->channel == CHAN_PSEUDO)
05486          b2 = ast_safe_string_alloc("pseudo-%ld", ast_random());
05487       else  
05488          b2 = ast_safe_string_alloc("%d-%d", i->channel, y);
05489       for (x = 0; x < 3; x++) {
05490          if ((index != x) && i->subs[x].owner && !strcasecmp(b2, i->subs[x].owner->name))
05491             break;
05492       }
05493       y++;
05494    } while (x < 3);
05495    tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "Zap/%s", b2);
05496    if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */
05497       free(b2);
05498    if (!tmp)
05499       return NULL;
05500    tmp->tech = &zap_tech;
05501    ps.channo = i->channel;
05502    res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
05503    if (res) {
05504       ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n");
05505       ps.curlaw = ZT_LAW_MULAW;
05506    }
05507    if (ps.curlaw == ZT_LAW_ALAW)
05508       deflaw = AST_FORMAT_ALAW;
05509    else
05510       deflaw = AST_FORMAT_ULAW;
05511    if (law) {
05512       if (law == ZT_LAW_ALAW)
05513          deflaw = AST_FORMAT_ALAW;
05514       else
05515          deflaw = AST_FORMAT_ULAW;
05516    }
05517    tmp->fds[0] = i->subs[index].zfd;
05518    tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
05519    /* Start out assuming ulaw since it's smaller :) */
05520    tmp->rawreadformat = deflaw;
05521    tmp->readformat = deflaw;
05522    tmp->rawwriteformat = deflaw;
05523    tmp->writeformat = deflaw;
05524    i->subs[index].linear = 0;
05525    zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
05526    features = 0;
05527    if (index == SUB_REAL) {
05528       if (i->busydetect && CANBUSYDETECT(i))
05529          features |= DSP_FEATURE_BUSY_DETECT;
05530       if ((i->callprogress & 1) && CANPROGRESSDETECT(i))
05531          features |= DSP_FEATURE_CALL_PROGRESS;
05532       if ((!i->outgoing && (i->callprogress & 4)) || 
05533           (i->outgoing && (i->callprogress & 2))) {
05534          features |= DSP_FEATURE_FAX_DETECT;
05535       }
05536 #ifdef ZT_TONEDETECT
05537       x = ZT_TONEDETECT_ON | ZT_TONEDETECT_MUTE;
05538       if (ioctl(i->subs[index].zfd, ZT_TONEDETECT, &x)) {
05539 #endif      
05540          i->hardwaredtmf = 0;
05541          features |= DSP_FEATURE_DTMF_DETECT;
05542 #ifdef ZT_TONEDETECT
05543       } else if (NEED_MFDETECT(i)) {
05544          i->hardwaredtmf = 1;
05545          features |= DSP_FEATURE_DTMF_DETECT;
05546       }
05547 #endif
05548    }
05549    if (features) {
05550       if (i->dsp) {
05551          ast_log(LOG_DEBUG, "Already have a dsp on %s?\n", tmp->name);
05552       } else {
05553          if (i->channel != CHAN_PSEUDO)
05554             i->dsp = ast_dsp_new();
05555          else
05556             i->dsp = NULL;
05557          if (i->dsp) {
05558             i->dsp_features = features & ~DSP_PROGRESS_TALK;
05559 #ifdef HAVE_PRI
05560             /* We cannot do progress detection until receives PROGRESS message */
05561             if (i->outgoing && (i->sig == SIG_PRI)) {
05562                /* Remember requested DSP features, don't treat
05563                   talking as ANSWER */
05564                features = 0;
05565             }
05566 #endif
05567             ast_dsp_set_features(i->dsp, features);
05568             ast_dsp_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
05569             if (!ast_strlen_zero(progzone))
05570                ast_dsp_set_call_progress_zone(i->dsp, progzone);
05571             if (i->busydetect && CANBUSYDETECT(i)) {
05572                ast_dsp_set_busy_count(i->dsp, i->busycount);
05573                ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
05574             }
05575          }
05576       }
05577    }
05578       
05579    if (state == AST_STATE_RING)
05580       tmp->rings = 1;
05581    tmp->tech_pvt = i;
05582 #ifdef HAVE_PRI
05583    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) {
05584 #else
05585    if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
05586 #endif
05587       /* Only FXO signalled stuff can be picked up */ /* i dont think so, mr. ulaw! we alaws like to pick up BRIs/PRIs */
05588       tmp->callgroup = i->callgroup;
05589       tmp->pickupgroup = i->pickupgroup;
05590    }
05591    if (!ast_strlen_zero(i->language))
05592       ast_string_field_set(tmp, language, i->language);
05593    if (!i->owner)
05594       i->owner = tmp;
05595    if (!ast_strlen_zero(i->accountcode))
05596       ast_string_field_set(tmp, accountcode, i->accountcode);
05597    if (i->amaflags)
05598       tmp->amaflags = i->amaflags;
05599    i->subs[index].owner = tmp;
05600    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05601    ast_string_field_set(tmp, call_forward, i->call_forward);
05602    /* If we've been told "no ADSI" then enforce it */
05603    if (!i->adsi)
05604       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05605    if (!ast_strlen_zero(i->exten))
05606       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05607    if (!ast_strlen_zero(i->rdnis))
05608       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05609    if (!ast_strlen_zero(i->dnid))
05610       tmp->cid.cid_dnid = ast_strdup(i->dnid);
05611 
05612    /* Don't use ast_set_callerid() here because it will
05613     * generate a needless NewCallerID event */
05614 #ifdef PRI_ANI
05615    if (!ast_strlen_zero(i->cid_ani))
05616       tmp->cid.cid_ani = ast_strdup(i->cid_ani);
05617    else  
05618       tmp->cid.cid_ani = ast_strdup(i->cid_num);
05619 #else
05620    tmp->cid.cid_ani = ast_strdup(i->cid_num);
05621 #endif
05622    tmp->cid.cid_pres = i->callingpres;
05623    tmp->cid.cid_ton = i->cid_ton;
05624 #ifdef HAVE_PRI
05625    tmp->transfercapability = transfercapability;
05626    pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
05627    if (transfercapability & PRI_TRANS_CAP_DIGITAL)
05628       i->digital = 1;
05629    /* Assume calls are not idle calls unless we're told differently */
05630    i->isidlecall = 0;
05631    i->alreadyhungup = 0;
05632 #endif
05633    /* clear the fake event in case we posted one before we had ast_channel */
05634    i->fake_event = 0;
05635    /* Assure there is no confmute on this channel */
05636    zt_confmute(i, 0);
05637    /* Configure the new channel jb */
05638    ast_jb_configure(tmp, &global_jbconf);
05639    if (startpbx) {
05640       if (ast_pbx_start(tmp)) {
05641          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05642          ast_hangup(tmp);
05643          i->owner = NULL;
05644          return NULL;
05645       }
05646    }
05647 
05648    ast_module_ref(ast_module_info->self);
05649    
05650    return tmp;
05651 }
05652 
05653 
05654 static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
05655 {
05656    char c;
05657 
05658    *str = 0; /* start with empty output buffer */
05659    for (;;)
05660    {
05661       /* Wait for the first digit (up to specified ms). */
05662       c = ast_waitfordigit(chan, ms);
05663       /* if timeout, hangup or error, return as such */
05664       if (c < 1)
05665          return c;
05666       *str++ = c;
05667       *str = 0;
05668       if (strchr(term, c))
05669          return 1;
05670    }
05671 }
05672 
05673 static int zt_wink(struct zt_pvt *p, int index)
05674 {
05675    int j;
05676    zt_set_hook(p->subs[index].zfd, ZT_WINK);
05677    for (;;)
05678    {
05679          /* set bits of interest */
05680       j = ZT_IOMUX_SIGEVENT;
05681           /* wait for some happening */
05682       if (ioctl(p->subs[index].zfd,ZT_IOMUX,&j) == -1) return(-1);
05683          /* exit loop if we have it */
05684       if (j & ZT_IOMUX_SIGEVENT) break;
05685    }
05686      /* get the event info */
05687    if (ioctl(p->subs[index].zfd,ZT_GETEVENT,&j) == -1) return(-1);
05688    return 0;
05689 }
05690 
05691 static void *ss_thread(void *data)
05692 {
05693    struct ast_channel *chan = data;
05694    struct zt_pvt *p = chan->tech_pvt;
05695    char exten[AST_MAX_EXTENSION] = "";
05696    char exten2[AST_MAX_EXTENSION] = "";
05697    unsigned char buf[256];
05698    char dtmfcid[300];
05699    char dtmfbuf[300];
05700    struct callerid_state *cs = NULL;
05701    char *name = NULL, *number = NULL;
05702    int distMatches;
05703    int curRingData[3];
05704    int receivedRingT;
05705    int counter1;
05706    int counter;
05707    int samples = 0;
05708    struct ast_smdi_md_message *smdi_msg = NULL;
05709    int flags;
05710    int i;
05711    int timeout;
05712    int getforward = 0;
05713    char *s1, *s2;
05714    int len = 0;
05715    int res;
05716    int index;
05717    int network;
05718 
05719    /* in the bizarre case where the channel has become a zombie before we
05720       even get started here, abort safely
05721    */
05722    if (!p) {
05723       ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
05724       ast_hangup(chan);
05725       return NULL;
05726    }
05727 
05728    if (option_verbose > 2) 
05729       ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
05730    index = zt_get_index(chan, p, 1);
05731    if (index < 0) {
05732       ast_log(LOG_WARNING, "Huh?\n");
05733       ast_hangup(chan);
05734       return NULL;
05735    }
05736    if (p->dsp)
05737       ast_dsp_digitreset(p->dsp);
05738    switch (p->sig) {
05739 #ifdef HAVE_PRI
05740    case SIG_PRI:
05741       /* Now loop looking for an extension */
05742       ast_copy_string(exten, p->exten, sizeof(exten));
05743       len = strlen(exten);
05744       res = 0;
05745       while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
05746          if (len && !ast_ignore_pattern(chan->context, exten)) {
05747             tone_zone_play_tone(p->subs[index].zfd, -1);
05748          } else {
05749             network = p->pri->nodetype == PRI_NETWORK || p->pri->nodetype == BRI_NETWORK || p->pri->nodetype == BRI_NETWORK_PTMP;
05750             if (network) {
05751                 tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
05752             } else {
05753                 /* cpe be quiet */
05754                 tone_zone_play_tone(p->subs[index].zfd, -1);
05755             }
05756          }
05757          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
05758             timeout = matchdigittimeout;
05759          else
05760             timeout = gendigittimeout;
05761          res = ast_waitfordigit(chan, timeout);
05762          if (res < 0) {
05763             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05764             ast_hangup(chan);
05765             return NULL;
05766          } else if (res) {
05767             exten[len++] = res;
05768             exten[len] = '\0';
05769          } else
05770             break;
05771       }
05772       /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
05773       if (ast_strlen_zero(exten)) {
05774          if (option_verbose > 2)
05775             ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of empty extension received on overlap call\n");
05776          exten[0] = 's';
05777          exten[1] = '\0';
05778       }
05779       tone_zone_play_tone(p->subs[index].zfd, -1);
05780       if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
05781          /* Start the real PBX */
05782          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
05783          if (p->dsp) ast_dsp_digitreset(p->dsp);
05784          zt_enable_ec(p);
05785          ast_setstate(chan, AST_STATE_RING);
05786          res = ast_pbx_run(chan);
05787          if (res) {
05788             ast_log(LOG_WARNING, "PBX exited non-zero!\n");
05789          }
05790       } else {
05791          ast_log(LOG_DEBUG, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
05792          chan->hangupcause = AST_CAUSE_UNALLOCATED;
05793          ast_hangup(chan);
05794          p->exten[0] = '\0';
05795          /* Since we send release complete here, we won't get one */
05796          p->call = NULL;
05797       }
05798       return NULL;
05799       break;
05800 #endif
05801    case SIG_FEATD:
05802    case SIG_FEATDMF:
05803    case SIG_FEATDMF_TA:
05804    case SIG_E911:
05805    case SIG_FGC_CAMAMF:
05806    case SIG_FEATB:
05807    case SIG_EMWINK:
05808    case SIG_SF_FEATD:
05809    case SIG_SF_FEATDMF:
05810    case SIG_SF_FEATB:
05811    case SIG_SFWINK:
05812       if (zt_wink(p, index))  
05813          return NULL;
05814       /* Fall through */
05815    case SIG_EM:
05816    case SIG_EM_E1:
05817    case SIG_SF:
05818    case SIG_FGC_CAMA:
05819       res = tone_zone_play_tone(p->subs[index].zfd, -1);
05820       if (p->dsp)
05821          ast_dsp_digitreset(p->dsp);
05822       /* set digit mode appropriately */
05823       if (p->dsp) {
05824          if (NEED_MFDETECT(p))
05825             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax); 
05826          else 
05827             ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05828       }
05829       memset(dtmfbuf, 0, sizeof(dtmfbuf));
05830       /* Wait for the first digit only if immediate=no */
05831       if (!p->immediate)
05832          /* Wait for the first digit (up to 5 seconds). */
05833          res = ast_waitfordigit(chan, 5000);
05834       else
05835          res = 0;
05836       if (res > 0) {
05837          /* save first char */
05838          dtmfbuf[0] = res;
05839          switch (p->sig) {
05840          case SIG_FEATD:
05841          case SIG_SF_FEATD:
05842             res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05843             if (res > 0)
05844                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05845             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05846             break;
05847          case SIG_FEATDMF_TA:
05848             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05849             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05850             if (zt_wink(p, index)) return NULL;
05851             dtmfbuf[0] = 0;
05852             /* Wait for the first digit (up to 5 seconds). */
05853             res = ast_waitfordigit(chan, 5000);
05854             if (res <= 0) break;
05855             dtmfbuf[0] = res;
05856             /* fall through intentionally */
05857          case SIG_FEATDMF:
05858          case SIG_E911:
05859          case SIG_FGC_CAMAMF:
05860          case SIG_SF_FEATDMF:
05861             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05862             /* if international caca, do it again to get real ANO */
05863             if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
05864             {
05865                if (zt_wink(p, index)) return NULL;
05866                dtmfbuf[0] = 0;
05867                /* Wait for the first digit (up to 5 seconds). */
05868                res = ast_waitfordigit(chan, 5000);
05869                if (res <= 0) break;
05870                dtmfbuf[0] = res;
05871                res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05872             }
05873             if (res > 0) {
05874                /* if E911, take off hook */
05875                if (p->sig == SIG_E911)
05876                   zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05877                res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
05878             }
05879             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05880             break;
05881          case SIG_FEATB:
05882          case SIG_SF_FEATB:
05883             res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
05884             if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05885             break;
05886          case SIG_EMWINK:
05887             /* if we received a '*', we are actually receiving Feature Group D
05888                dial syntax, so use that mode; otherwise, fall through to normal
05889                mode
05890             */
05891             if (res == '*') {
05892                res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
05893                if (res > 0)
05894                   res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
05895                if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
05896                break;
05897             }
05898          default:
05899             /* If we got the first digit, get the rest */
05900             len = 1;
05901             dtmfbuf[len] = '\0';
05902             while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05903                if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
05904                   timeout = matchdigittimeout;
05905                } else {
05906                   timeout = gendigittimeout;
05907                }
05908                res = ast_waitfordigit(chan, timeout);
05909                if (res < 0) {
05910                   ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
05911                   ast_hangup(chan);
05912                   return NULL;
05913                } else if (res) {
05914                   dtmfbuf[len++] = res;
05915                   dtmfbuf[len] = '\0';
05916                } else {
05917                   break;
05918                }
05919             }
05920             break;
05921          }
05922       }
05923       if (res == -1) {
05924          ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
05925          ast_hangup(chan);
05926          return NULL;
05927       } else if (res < 0) {
05928          ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
05929          ast_hangup(chan);
05930          return NULL;
05931       }
05932 
05933       if (p->sig == SIG_FGC_CAMA) {
05934          char anibuf[100];
05935 
05936          if (ast_safe_sleep(chan,1000) == -1) {
05937                            ast_hangup(chan);
05938                            return NULL;
05939          }
05940                         zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
05941                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MF | p->dtmfrelax);
05942                         res = my_getsigstr(chan, anibuf, "#", 10000);
05943                         if ((res > 0) && (strlen(anibuf) > 2)) {
05944             if (anibuf[strlen(anibuf) - 1] == '#')
05945                anibuf[strlen(anibuf) - 1] = 0;
05946             ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
05947          }
05948                         ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
05949       }
05950 
05951       ast_copy_string(exten, dtmfbuf, sizeof(exten));
05952       if (ast_strlen_zero(exten))
05953          ast_copy_string(exten, "s", sizeof(exten));
05954       if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
05955          /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
05956          if (exten[0] == '*') {
05957             char *stringp=NULL;
05958             ast_copy_string(exten2, exten, sizeof(exten2));
05959             /* Parse out extension and callerid */
05960             stringp=exten2 +1;
05961             s1 = strsep(&stringp, "*");
05962             s2 = strsep(&stringp, "*");
05963             if (s2) {
05964                if (!ast_strlen_zero(p->cid_num))
05965                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05966                else
05967                   ast_set_callerid(chan, s1, NULL, s1);
05968                ast_copy_string(exten, s2, sizeof(exten));
05969             } else
05970                ast_copy_string(exten, s1, sizeof(exten));
05971          } else if (p->sig == SIG_FEATD)
05972             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05973       }
05974       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
05975          if (exten[0] == '*') {
05976             char *stringp=NULL;
05977             ast_copy_string(exten2, exten, sizeof(exten2));
05978             /* Parse out extension and callerid */
05979             stringp=exten2 +1;
05980             s1 = strsep(&stringp, "#");
05981             s2 = strsep(&stringp, "#");
05982             if (s2) {
05983                if (!ast_strlen_zero(p->cid_num))
05984                   ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
05985                else
05986                   if (*(s1 + 2))
05987                      ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
05988                ast_copy_string(exten, s2 + 1, sizeof(exten));
05989             } else
05990                ast_copy_string(exten, s1 + 2, sizeof(exten));
05991          } else
05992             ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
05993       }
05994       if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
05995          if (exten[0] == '*') {
05996             char *stringp=NULL;
05997             ast_copy_string(exten2, exten, sizeof(exten2));
05998             /* Parse out extension and callerid */
05999             stringp=exten2 +1;
06000             s1 = strsep(&stringp, "#");
06001             s2 = strsep(&stringp, "#");
06002             if (s2 && (*(s2 + 1) == '0')) {
06003                if (*(s2 + 2))
06004                   ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
06005             }
06006             if (s1)  ast_copy_string(exten, s1, sizeof(exten));
06007             else ast_copy_string(exten, "911", sizeof(exten));
06008          } else
06009             ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d.  Assuming E&M Wink instead\n", p->channel);
06010       }
06011       if (p->sig == SIG_FEATB) {
06012          if (exten[0] == '*') {
06013             char *stringp=NULL;
06014             ast_copy_string(exten2, exten, sizeof(exten2));
06015             /* Parse out extension and callerid */
06016             stringp=exten2 +1;
06017             s1 = strsep(&stringp, "#");
06018             ast_copy_string(exten, exten2 + 1, sizeof(exten));
06019          } else
06020             ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d.  Assuming E&M Wink instead\n", p->channel);
06021       }
06022       if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
06023          zt_wink(p, index);
06024                         /* some switches require a minimum guard time between
06025                            the last FGD wink and something that answers
06026                            immediately. This ensures it */
06027                         if (ast_safe_sleep(chan,100)) return NULL;
06028       }
06029       zt_enable_ec(p);
06030       if (NEED_MFDETECT(p)) {
06031          if (p->dsp) {
06032             if (!p->hardwaredtmf)
06033                ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax); 
06034             else {
06035                ast_dsp_free(p->dsp);
06036                p->dsp = NULL;
06037             }
06038          }
06039       }
06040 
06041       if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
06042          ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06043          if (p->dsp) ast_dsp_digitreset(p->dsp);
06044          res = ast_pbx_run(chan);
06045          if (res) {
06046             ast_log(LOG_WARNING, "PBX exited non-zero\n");
06047             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06048          }
06049          return NULL;
06050       } else {
06051          if (option_verbose > 2)
06052             ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
06053          sleep(2);
06054          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_INFO);
06055          if (res < 0)
06056             ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
06057          else
06058             sleep(1);
06059          res = ast_streamfile(chan, "ss-noservice", chan->language);
06060          if (res >= 0)
06061             ast_waitstream(chan, "");
06062          res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06063          ast_hangup(chan);
06064          return NULL;
06065       }
06066       break;
06067    case SIG_FXOLS:
06068    case SIG_FXOGS:
06069    case SIG_FXOKS:
06070       /* Read the first digit */
06071       timeout = firstdigittimeout;
06072       /* If starting a threeway call, never timeout on the first digit so someone
06073          can use flash-hook as a "hold" feature */
06074       if (p->subs[SUB_THREEWAY].owner) 
06075          timeout = 999999;
06076       while (len < AST_MAX_EXTENSION-1) {
06077          /* Read digit unless it's supposed to be immediate, in which case the
06078             only answer is 's' */
06079          if (p->immediate) 
06080             res = 's';
06081          else
06082             res = ast_waitfordigit(chan, timeout);
06083          timeout = 0;
06084          if (res < 0) {
06085             ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
06086             res = tone_zone_play_tone(p->subs[index].zfd, -1);
06087             ast_hangup(chan);
06088             return NULL;
06089          } else if (res)  {
06090             exten[len++]=res;
06091             exten[len] = '\0';
06092          }
06093          if (!ast_ignore_pattern(chan->context, exten))
06094             tone_zone_play_tone(p->subs[index].zfd, -1);
06095          else
06096             tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
06097          if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
06098             if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
06099                if (getforward) {
06100                   /* Record this as the forwarding extension */
06101                   ast_copy_string(p->call_forward, exten, sizeof(p->call_forward)); 
06102                   if (option_verbose > 2)
06103                      ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
06104                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06105                   if (res)
06106                      break;
06107                   usleep(500000);
06108                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06109                   sleep(1);
06110                   memset(exten, 0, sizeof(exten));
06111                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);
06112                   len = 0;
06113                   getforward = 0;
06114                } else  {
06115                   res = tone_zone_play_tone(p->subs[index].zfd, -1);
06116                   ast_copy_string(chan->exten, exten, sizeof(chan->exten));
06117                   if (!ast_strlen_zero(p->cid_num)) {
06118                      if (!p->hidecallerid)
06119                         ast_set_callerid(chan, p->cid_num, NULL, p->cid_num); 
06120                      else
06121                         ast_set_callerid(chan, NULL, NULL, p->cid_num); 
06122                   }
06123                   if (!ast_strlen_zero(p->cid_name)) {
06124                      if (!p->hidecallerid)
06125                         ast_set_callerid(chan, NULL, p->cid_name, NULL);
06126                   }
06127                   ast_setstate(chan, AST_STATE_RING);
06128                   zt_enable_ec(p);
06129                   res = ast_pbx_run(chan);
06130                   if (res) {
06131                      ast_log(LOG_WARNING, "PBX exited non-zero\n");
06132                      res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06133                   }
06134                   return NULL;
06135                }
06136             } else {
06137                /* It's a match, but they just typed a digit, and there is an ambiguous match,
06138                   so just set the timeout to matchdigittimeout and wait some more */
06139                timeout = matchdigittimeout;
06140             }
06141          } else if (res == 0) {
06142             ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
06143             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06144             zt_wait_event(p->subs[index].zfd);
06145             ast_hangup(chan);
06146             return NULL;
06147          } else if (p->callwaiting && !strcmp(exten, "*70")) {
06148             if (option_verbose > 2) 
06149                ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
06150             /* Disable call waiting if enabled */
06151             p->callwaiting = 0;
06152             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06153             if (res) {
06154                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06155                   chan->name, strerror(errno));
06156             }
06157             len = 0;
06158             ioctl(p->subs[index].zfd,ZT_CONFDIAG,&len);
06159             memset(exten, 0, sizeof(exten));
06160             timeout = firstdigittimeout;
06161                
06162          } else if (!strcmp(exten,ast_pickup_ext())) {
06163             /* Scan all channels and see if any there
06164              * ringing channqels with that have call groups
06165              * that equal this channels pickup group  
06166              */
06167             if (index == SUB_REAL) {
06168                /* Switch us from Third call to Call Wait */
06169                if (p->subs[SUB_THREEWAY].owner) {
06170                   /* If you make a threeway call and the *8# a call, it should actually 
06171                      look like a callwait */
06172                   alloc_sub(p, SUB_CALLWAIT);   
06173                   swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
06174                   unalloc_sub(p, SUB_THREEWAY);
06175                }
06176                zt_enable_ec(p);
06177                if (ast_pickup_call(chan)) {
06178                   ast_log(LOG_DEBUG, "No call pickup possible...\n");
06179                   res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06180                   zt_wait_event(p->subs[index].zfd);
06181                }
06182                ast_hangup(chan);
06183                return NULL;
06184             } else {
06185                ast_log(LOG_WARNING, "Huh?  Got *8# on call not on real\n");
06186                ast_hangup(chan);
06187                return NULL;
06188             }
06189             
06190          } else if (!p->hidecallerid && !strcmp(exten, "*67")) {
06191             if (option_verbose > 2) 
06192                ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
06193             /* Disable Caller*ID if enabled */
06194             p->hidecallerid = 1;
06195             if (chan->cid.cid_num)
06196                free(chan->cid.cid_num);
06197             chan->cid.cid_num = NULL;
06198             if (chan->cid.cid_name)
06199                free(chan->cid.cid_name);
06200             chan->cid.cid_name = NULL;
06201             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06202             if (res) {
06203                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06204                   chan->name, strerror(errno));
06205             }
06206             len = 0;
06207             memset(exten, 0, sizeof(exten));
06208             timeout = firstdigittimeout;
06209          } else if (p->callreturn && !strcmp(exten, "*69")) {
06210             res = 0;
06211             if (!ast_strlen_zero(p->lastcid_num)) {
06212                res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
06213             }
06214             if (!res)
06215                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06216             break;
06217          } else if (!strcmp(exten, "*78")) {
06218             /* Do not disturb */
06219             if (option_verbose > 2)
06220                ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %d\n", p->channel);
06221             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06222                      "Channel: Zap/%d\r\n"
06223                      "Status: enabled\r\n", p->channel);
06224             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06225             p->dnd = 1;
06226             getforward = 0;
06227             memset(exten, 0, sizeof(exten));
06228             len = 0;
06229          } else if (!strcmp(exten, "*79")) {
06230             /* Do not disturb */
06231             if (option_verbose > 2)
06232                ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %d\n", p->channel);
06233             manager_event(EVENT_FLAG_SYSTEM, "DNDState",
06234                      "Channel: Zap/%d\r\n"
06235                      "Status: disabled\r\n", p->channel);
06236             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06237             p->dnd = 0;
06238             getforward = 0;
06239             memset(exten, 0, sizeof(exten));
06240             len = 0;
06241          } else if (p->cancallforward && !strcmp(exten, "*72")) {
06242             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06243             getforward = 1;
06244             memset(exten, 0, sizeof(exten));
06245             len = 0;
06246          } else if (p->cancallforward && !strcmp(exten, "*73")) {
06247             if (option_verbose > 2)
06248                ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %d\n", p->channel);
06249             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06250             memset(p->call_forward, 0, sizeof(p->call_forward));
06251             getforward = 0;
06252             memset(exten, 0, sizeof(exten));
06253             len = 0;
06254          } else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) && 
06255                   p->subs[SUB_THREEWAY].owner &&
06256                   ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
06257             /* This is a three way call, the main call being a real channel, 
06258                and we're parking the first call. */
06259             ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
06260             if (option_verbose > 2)
06261                ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name);
06262             break;
06263          } else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
06264             if (option_verbose > 2)
06265                ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcid_num);
06266             res = ast_db_put("blacklist", p->lastcid_num, "1");
06267             if (!res) {
06268                res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06269                memset(exten, 0, sizeof(exten));
06270                len = 0;
06271             }
06272          } else if (p->hidecallerid && !strcmp(exten, "*82")) {
06273             if (option_verbose > 2) 
06274                ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
06275             /* Enable Caller*ID if enabled */
06276             p->hidecallerid = 0;
06277             if (chan->cid.cid_num)
06278                free(chan->cid.cid_num);
06279             chan->cid.cid_num = NULL;
06280             if (chan->cid.cid_name)
06281                free(chan->cid.cid_name);
06282             chan->cid.cid_name = NULL;
06283             ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
06284             res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);
06285             if (res) {
06286                ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
06287                   chan->name, strerror(errno));
06288             }
06289             len = 0;
06290             memset(exten, 0, sizeof(exten));
06291             timeout = firstdigittimeout;
06292          } else if (!strcmp(exten, "*0")) {
06293             struct ast_channel *nbridge = 
06294                p->subs[SUB_THREEWAY].owner;
06295             struct zt_pvt *pbridge = NULL;
06296               /* set up the private struct of the bridged one, if any */
06297             if (nbridge && ast_bridged_channel(nbridge)) 
06298                pbridge = ast_bridged_channel(nbridge)->tech_pvt;
06299             if (nbridge && pbridge && 
06300                 (nbridge->tech == &zap_tech) && 
06301                 (ast_bridged_channel(nbridge)->tech == &zap_tech) &&
06302                 ISTRUNK(pbridge)) {
06303                int func = ZT_FLASH;
06304                /* Clear out the dial buffer */
06305                p->dop.dialstr[0] = '\0';
06306                /* flash hookswitch */
06307                if ((ioctl(pbridge->subs[SUB_REAL].zfd,ZT_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
06308                   ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n", 
06309                      nbridge->name, strerror(errno));
06310                }
06311                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06312                unalloc_sub(p, SUB_THREEWAY);
06313                p->owner = p->subs[SUB_REAL].owner;
06314                if (ast_bridged_channel(p->subs[SUB_REAL].owner))
06315                   ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
06316                ast_hangup(chan);
06317                return NULL;
06318             } else {
06319                tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06320                zt_wait_event(p->subs[index].zfd);
06321                tone_zone_play_tone(p->subs[index].zfd, -1);
06322                swap_subs(p, SUB_REAL, SUB_THREEWAY);
06323                unalloc_sub(p, SUB_THREEWAY);
06324                p->owner = p->subs[SUB_REAL].owner;
06325                ast_hangup(chan);
06326                return NULL;
06327             }              
06328          } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
06329                      ((exten[0] != '*') || (strlen(exten) > 2))) {
06330             if (option_debug)
06331                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);
06332             break;
06333          }
06334          if (!timeout)
06335             timeout = gendigittimeout;
06336          if (len && !ast_ignore_pattern(chan->context, exten))
06337             tone_zone_play_tone(p->subs[index].zfd, -1);
06338       }
06339       break;
06340    case SIG_FXSLS:
06341    case SIG_FXSGS:
06342    case SIG_FXSKS:
06343 #ifdef HAVE_PRI
06344       if (p->pri) {
06345          /* This is a GR-303 trunk actually.  Wait for the first ring... */
06346          struct ast_frame *f;
06347          int res;
06348          time_t start;
06349 
06350          time(&start);
06351          ast_setstate(chan, AST_STATE_RING);
06352          while (time(NULL) < start + 3) {
06353             res = ast_waitfor(chan, 1000);
06354             if (res) {
06355                f = ast_read(chan);
06356                if (!f) {
06357                   ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
06358                   ast_hangup(chan);
06359                   return NULL;
06360                } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
06361                   res = 1;
06362                } else
06363                   res = 0;
06364                ast_frfree(f);
06365                if (res) {
06366                   ast_log(LOG_DEBUG, "Got ring!\n");
06367                   res = 0;
06368                   break;
06369                }
06370             }
06371          }
06372       }
06373 #endif
06374       /* check for SMDI messages */
06375       if (p->use_smdi && p->smdi_iface) {
06376          smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
06377 
06378          if (smdi_msg != NULL) {
06379             ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
06380 
06381             if (smdi_msg->type == 'B')
06382                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
06383             else if (smdi_msg->type == 'N')
06384                pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
06385 
06386             ast_log(LOG_DEBUG, "Recieved SMDI message on %s\n", chan->name);
06387          } else {
06388             ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
06389          }
06390       }
06391 
06392       if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
06393             number = smdi_msg->calling_st;
06394 
06395       /* If we want caller id, we're in a prering state due to a polarity reversal
06396        * and we're set to use a polarity reversal to trigger the start of caller id,
06397        * grab the caller id and wait for ringing to start... */
06398       } else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && p->cid_start == CID_START_POLARITY)) {
06399          /* If set to use DTMF CID signalling, listen for DTMF */
06400          if (p->cid_signalling == CID_SIG_DTMF) {
06401             int i = 0;
06402             cs = NULL;
06403             ast_log(LOG_DEBUG, "Receiving DTMF cid on "
06404                "channel %s\n", chan->name);
06405             zt_setlinear(p->subs[index].zfd, 0);
06406             res = 2000;
06407             for (;;) {
06408                struct ast_frame *f;
06409                res = ast_waitfor(chan, res);
06410                if (res <= 0) {
06411                   ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
06412                      "Exiting simple switch\n");
06413                   ast_hangup(chan);
06414                   return NULL;
06415                } 
06416                f = ast_read(chan);
06417                if (!f)
06418                   break;
06419                if (f->frametype == AST_FRAME_DTMF) {
06420                   dtmfbuf[i++] = f->subclass;
06421                   ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
06422                   res = 2000;
06423                }
06424                ast_frfree(f);
06425                if (chan->_state == AST_STATE_RING ||
06426                    chan->_state == AST_STATE_RINGING) 
06427                   break; /* Got ring */
06428             }
06429             dtmfbuf[i] = '\0';
06430             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06431             /* Got cid and ring. */
06432             ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
06433             callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
06434             ast_log(LOG_DEBUG, "CID is '%s', flags %d\n", 
06435                dtmfcid, flags);
06436             /* If first byte is NULL, we have no cid */
06437             if (!ast_strlen_zero(dtmfcid)) 
06438                number = dtmfcid;
06439             else
06440                number = NULL;
06441          /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
06442          } else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
06443             cs = callerid_new(p->cid_signalling);
06444             if (cs) {
06445                samples = 0;
06446 #if 1
06447                bump_gains(p);
06448 #endif            
06449                /* Take out of linear mode for Caller*ID processing */
06450                zt_setlinear(p->subs[index].zfd, 0);
06451                
06452                /* First we wait and listen for the Caller*ID */
06453                for (;;) {  
06454                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06455                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06456                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06457                      callerid_free(cs);
06458                      ast_hangup(chan);
06459                      return NULL;
06460                   }
06461                   if (i & ZT_IOMUX_SIGEVENT) {
06462                      res = zt_get_event(p->subs[index].zfd);
06463                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06464 
06465                      if (p->cid_signalling == CID_SIG_V23_JP) {
06466 #ifdef ZT_EVENT_RINGBEGIN
06467                         if (res == ZT_EVENT_RINGBEGIN) {
06468                            res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06469                            usleep(1);
06470                         }
06471 #endif
06472                      } else {
06473                         res = 0;
06474                         break;
06475                      }
06476                   } else if (i & ZT_IOMUX_READ) {
06477                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06478                      if (res < 0) {
06479                         if (errno != ELAST) {
06480                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06481                            callerid_free(cs);
06482                            ast_hangup(chan);
06483                            return NULL;
06484                         }
06485                         break;
06486                      }
06487                      samples += res;
06488 
06489                      if  (p->cid_signalling == CID_SIG_V23_JP) {
06490                         res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
06491                      } else {
06492                         res = callerid_feed(cs, buf, res, AST_LAW(p));
06493                      }
06494 
06495                      if (res < 0) {
06496                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06497                         break;
06498                      } else if (res)
06499                         break;
06500                      else if (samples > (8000 * 10))
06501                         break;
06502                   }
06503                }
06504                if (res == 1) {
06505                   callerid_get(cs, &name, &number, &flags);
06506                   ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06507                }
06508                if (res < 0) {
06509                   ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06510                }
06511 
06512                if (p->cid_signalling == CID_SIG_V23_JP) {
06513                   res = zt_set_hook(p->subs[SUB_REAL].zfd, ZT_ONHOOK);
06514                   usleep(1);
06515                   res = 4000;
06516                } else {
06517 
06518                   /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
06519                   res = 2000;
06520                }
06521 
06522                for (;;) {
06523                   struct ast_frame *f;
06524                   res = ast_waitfor(chan, res);
06525                   if (res <= 0) {
06526                      ast_log(LOG_WARNING, "CID timed out waiting for ring. "
06527                         "Exiting simple switch\n");
06528                      ast_hangup(chan);
06529                      return NULL;
06530                   } 
06531                   f = ast_read(chan);
06532                   ast_frfree(f);
06533                   if (chan->_state == AST_STATE_RING ||
06534                       chan->_state == AST_STATE_RINGING) 
06535                      break; /* Got ring */
06536                }
06537    
06538                /* We must have a ring by now, so, if configured, lets try to listen for
06539                 * distinctive ringing */ 
06540                if (p->usedistinctiveringdetection == 1) {
06541                   len = 0;
06542                   distMatches = 0;
06543                   /* Clear the current ring data array so we dont have old data in it. */
06544                   for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06545                      curRingData[receivedRingT] = 0;
06546                   receivedRingT = 0;
06547                   counter = 0;
06548                   counter1 = 0;
06549                   /* Check to see if context is what it should be, if not set to be. */
06550                   if (strcmp(p->context,p->defcontext) != 0) {
06551                      ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06552                      ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06553                   }
06554       
06555                   for (;;) {  
06556                      i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06557                      if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06558                         ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06559                         callerid_free(cs);
06560                         ast_hangup(chan);
06561                         return NULL;
06562                      }
06563                      if (i & ZT_IOMUX_SIGEVENT) {
06564                         res = zt_get_event(p->subs[index].zfd);
06565                         ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06566                         res = 0;
06567                         /* Let us detect distinctive ring */
06568       
06569                         curRingData[receivedRingT] = p->ringt;
06570       
06571                         if (p->ringt < p->ringt_base/2)
06572                            break;
06573                         /* Increment the ringT counter so we can match it against
06574                            values in zapata.conf for distinctive ring */
06575                         if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06576                            break;
06577                      } else if (i & ZT_IOMUX_READ) {
06578                         res = read(p->subs[index].zfd, buf, sizeof(buf));
06579                         if (res < 0) {
06580                            if (errno != ELAST) {
06581                               ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06582                               callerid_free(cs);
06583                               ast_hangup(chan);
06584                               return NULL;
06585                            }
06586                            break;
06587                         }
06588                         if (p->ringt) 
06589                            p->ringt--;
06590                         if (p->ringt == 1) {
06591                            res = -1;
06592                            break;
06593                         }
06594                      }
06595                   }
06596                   if (option_verbose > 2)
06597                      /* this only shows up if you have n of the dring patterns filled in */
06598                      ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06599    
06600                   for (counter = 0; counter < 3; counter++) {
06601                      /* Check to see if the rings we received match any of the ones in zapata.conf for this
06602                      channel */
06603                      distMatches = 0;
06604                      for (counter1 = 0; counter1 < 3; counter1++) {
06605                         if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06606                         (p->drings.ringnum[counter].ring[counter1]-10)) {
06607                            distMatches++;
06608                         }
06609                      }
06610                      if (distMatches == 3) {
06611                         /* The ring matches, set the context to whatever is for distinctive ring.. */
06612                         ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06613                         ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06614                         if (option_verbose > 2)
06615                            ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06616                         break;
06617                      }
06618                   }
06619                }
06620                /* Restore linear mode (if appropriate) for Caller*ID processing */
06621                zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06622 #if 1
06623                restore_gains(p);
06624 #endif            
06625             } else
06626                ast_log(LOG_WARNING, "Unable to get caller ID space\n");       
06627          } else {
06628             ast_log(LOG_WARNING, "Channel %s in prering "
06629                "state, but I have nothing to do. "
06630                "Terminating simple switch, should be "
06631                "restarted by the actual ring.\n", 
06632                chan->name);
06633             ast_hangup(chan);
06634             return NULL;
06635          }
06636       } else if (p->use_callerid && p->cid_start == CID_START_RING) {
06637          /* FSK Bell202 callerID */
06638          cs = callerid_new(p->cid_signalling);
06639          if (cs) {
06640 #if 1
06641             bump_gains(p);
06642 #endif            
06643             samples = 0;
06644             len = 0;
06645             distMatches = 0;
06646             /* Clear the current ring data array so we dont have old data in it. */
06647             for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
06648                curRingData[receivedRingT] = 0;
06649             receivedRingT = 0;
06650             counter = 0;
06651             counter1 = 0;
06652             /* Check to see if context is what it should be, if not set to be. */
06653             if (strcmp(p->context,p->defcontext) != 0) {
06654                ast_copy_string(p->context, p->defcontext, sizeof(p->context));
06655                ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
06656             }
06657 
06658             /* Take out of linear mode for Caller*ID processing */
06659             zt_setlinear(p->subs[index].zfd, 0);
06660             for (;;) {  
06661                i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06662                if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))  {
06663                   ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06664                   callerid_free(cs);
06665                   ast_hangup(chan);
06666                   return NULL;
06667                }
06668                if (i & ZT_IOMUX_SIGEVENT) {
06669                   res = zt_get_event(p->subs[index].zfd);
06670                   ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06671                   /* If we get a PR event, they hung up while processing calerid */
06672                   if ( res == ZT_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
06673                      ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
06674                      p->polarity = POLARITY_IDLE;
06675                      callerid_free(cs);
06676                      ast_hangup(chan);
06677                      return NULL;
06678                   }
06679                   res = 0;
06680                   /* Let us detect callerid when the telco uses distinctive ring */
06681 
06682                   curRingData[receivedRingT] = p->ringt;
06683 
06684                   if (p->ringt < p->ringt_base/2)
06685                      break;
06686                   /* Increment the ringT counter so we can match it against
06687                      values in zapata.conf for distinctive ring */
06688                   if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06689                      break;
06690                } else if (i & ZT_IOMUX_READ) {
06691                   res = read(p->subs[index].zfd, buf, sizeof(buf));
06692                   if (res < 0) {
06693                      if (errno != ELAST) {
06694                         ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06695                         callerid_free(cs);
06696                         ast_hangup(chan);
06697                         return NULL;
06698                      }
06699                      break;
06700                   }
06701                   if (p->ringt) 
06702                      p->ringt--;
06703                   if (p->ringt == 1) {
06704                      res = -1;
06705                      break;
06706                   }
06707                   samples += res;
06708                   res = callerid_feed(cs, buf, res, AST_LAW(p));
06709                   if (res < 0) {
06710                      ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
06711                      break;
06712                   } else if (res)
06713                      break;
06714                   else if (samples > (8000 * 10))
06715                      break;
06716                }
06717             }
06718             if (res == 1) {
06719                callerid_get(cs, &name, &number, &flags);
06720                if (option_debug)
06721                   ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
06722             }
06723             if (distinctiveringaftercid == 1) {
06724                /* Clear the current ring data array so we dont have old data in it. */
06725                for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
06726                   curRingData[receivedRingT] = 0;
06727                }
06728                receivedRingT = 0;
06729                if (option_verbose > 2)
06730                   ast_verbose( VERBOSE_PREFIX_3 "Detecting post-CID distinctive ring\n");
06731                for (;;) {
06732                   i = ZT_IOMUX_READ | ZT_IOMUX_SIGEVENT;
06733                   if ((res = ioctl(p->subs[index].zfd, ZT_IOMUX, &i)))    {
06734                      ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
06735                      callerid_free(cs);
06736                      ast_hangup(chan);
06737                      return NULL;
06738                   }
06739                   if (i & ZT_IOMUX_SIGEVENT) {
06740                      res = zt_get_event(p->subs[index].zfd);
06741                      ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
06742                      res = 0;
06743                      /* Let us detect callerid when the telco uses distinctive ring */
06744 
06745                      curRingData[receivedRingT] = p->ringt;
06746 
06747                      if (p->ringt < p->ringt_base/2)
06748                         break;
06749                      /* Increment the ringT counter so we can match it against
06750                         values in zapata.conf for distinctive ring */
06751                      if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
06752                         break;
06753                   } else if (i & ZT_IOMUX_READ) {
06754                      res = read(p->subs[index].zfd, buf, sizeof(buf));
06755                      if (res < 0) {
06756                         if (errno != ELAST) {
06757                            ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
06758                            callerid_free(cs);
06759                            ast_hangup(chan);
06760                            return NULL;
06761                         }
06762                         break;
06763                      }
06764                   if (p->ringt)
06765                      p->ringt--;
06766                      if (p->ringt == 1) {
06767                         res = -1;
06768                         break;
06769                      }
06770                   }
06771                }
06772             }
06773             if (p->usedistinctiveringdetection == 1) {
06774                if (option_verbose > 2)
06775                   /* this only shows up if you have n of the dring patterns filled in */
06776                   ast_verbose( VERBOSE_PREFIX_3 "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
06777 
06778                for (counter = 0; counter < 3; counter++) {
06779                   /* Check to see if the rings we received match any of the ones in zapata.conf for this
06780                   channel */
06781                   if (option_verbose > 2)
06782                      /* this only shows up if you have n of the dring patterns filled in */
06783                      ast_verbose( VERBOSE_PREFIX_3 "Checking %d,%d,%d\n",
06784                         p->drings.ringnum[counter].ring[0],
06785                         p->drings.ringnum[counter].ring[1],
06786                         p->drings.ringnum[counter].ring[2]);
06787                   distMatches = 0;
06788                   for (counter1 = 0; counter1 < 3; counter1++) {
06789                      if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1]+10) && curRingData[counter1] >=
06790                      (p->drings.ringnum[counter].ring[counter1]-10)) {
06791                         distMatches++;
06792                      }
06793                   }
06794                   if (distMatches == 3) {
06795                      /* The ring matches, set the context to whatever is for distinctive ring.. */
06796                      ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
06797                      ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
06798                      if (option_verbose > 2)
06799                         ast_verbose( VERBOSE_PREFIX_3 "Distinctive Ring matched context %s\n",p->context);
06800                      break;
06801                   }
06802                }
06803             }
06804             /* Restore linear mode (if appropriate) for Caller*ID processing */
06805             zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
06806 #if 1
06807             restore_gains(p);
06808 #endif            
06809             if (res < 0) {
06810                ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
06811             }
06812          } else
06813             ast_log(LOG_WARNING, "Unable to get caller ID space\n");
06814       }
06815       else
06816          cs = NULL;
06817 
06818       if (number)
06819          ast_shrink_phone_number(number);
06820       ast_set_callerid(chan, number, name, number);
06821 
06822       if (smdi_msg)
06823          ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
06824 
06825       if (cs)
06826          callerid_free(cs);
06827 
06828       ast_setstate(chan, AST_STATE_RING);
06829       chan->rings = 1;
06830       p->ringt = p->ringt_base;
06831       res = ast_pbx_run(chan);
06832       if (res) {
06833          ast_hangup(chan);
06834          ast_log(LOG_WARNING, "PBX exited non-zero\n");
06835       }
06836       return NULL;
06837    default:
06838       ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
06839       res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06840       if (res < 0)
06841             ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06842    }
06843    res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);
06844    if (res < 0)
06845          ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
06846    ast_hangup(chan);
06847    return NULL;
06848 }
06849 
06850 /* destroy a zaptel channel, identified by its number */
06851 static int zap_destroy_channel_bynum(int channel)
06852 {
06853    struct zt_pvt *tmp = NULL;
06854    struct zt_pvt *prev = NULL;
06855 
06856    tmp = iflist;
06857    while (tmp) {
06858       if (tmp->channel == channel) {
06859          destroy_channel(prev, tmp, 1);
06860          return RESULT_SUCCESS;
06861       }
06862       prev = tmp;
06863       tmp = tmp->next;
06864    }
06865    return RESULT_FAILURE;
06866 }
06867 
06868 static int handle_init_event(struct zt_pvt *i, int event)
06869 {
06870    int res;
06871    pthread_t threadid;
06872    pthread_attr_t attr;
06873    struct ast_channel *chan;
06874    pthread_attr_init(&attr);
06875    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06876    /* Handle an event on a given channel for the monitor thread. */
06877    switch (event) {
06878    case ZT_EVENT_NONE:
06879    case ZT_EVENT_BITSCHANGED:
06880       break;
06881    case ZT_EVENT_WINKFLASH:
06882    case ZT_EVENT_RINGOFFHOOK:
06883       if (i->inalarm) break;
06884       if (i->radio) break;
06885       /* Got a ring/answer.  What kind of channel are we? */
06886       switch (i->sig) {
06887       case SIG_FXOLS:
06888       case SIG_FXOGS:
06889       case SIG_FXOKS:
06890          res = zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
06891          if (res && (errno == EBUSY))
06892             break;
06893          if (i->cidspill) {
06894             /* Cancel VMWI spill */
06895             free(i->cidspill);
06896             i->cidspill = NULL;
06897          }
06898          if (i->immediate) {
06899             zt_enable_ec(i);
06900             /* The channel is immediately up.  Start right away */
06901             res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
06902             chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
06903             if (!chan) {
06904                ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
06905                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06906                if (res < 0)
06907                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06908             }
06909          } else {
06910             /* Check for callerid, digits, etc */
06911             chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
06912             if (chan) {
06913                if (has_voicemail(i))
06914                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER);
06915                else
06916                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
06917                if (res < 0) 
06918                   ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
06919                if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06920                   ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06921                   res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06922                   if (res < 0)
06923                      ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06924                   ast_hangup(chan);
06925                }
06926             } else
06927                ast_log(LOG_WARNING, "Unable to create channel\n");
06928          }
06929          break;
06930       case SIG_FXSLS:
06931       case SIG_FXSGS:
06932       case SIG_FXSKS:
06933             i->ringt = i->ringt_base;
06934             /* Fall through */
06935       case SIG_EMWINK:
06936       case SIG_FEATD:
06937       case SIG_FEATDMF:
06938       case SIG_FEATDMF_TA:
06939       case SIG_E911:
06940       case SIG_FGC_CAMA:
06941       case SIG_FGC_CAMAMF:
06942       case SIG_FEATB:
06943       case SIG_EM:
06944       case SIG_EM_E1:
06945       case SIG_SFWINK:
06946       case SIG_SF_FEATD:
06947       case SIG_SF_FEATDMF:
06948       case SIG_SF_FEATB:
06949       case SIG_SF:
06950             /* Check for callerid, digits, etc */
06951             chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
06952             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
06953                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
06954                res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06955                if (res < 0)
06956                   ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06957                ast_hangup(chan);
06958             } else if (!chan) {
06959                ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
06960             }
06961             break;
06962       default:
06963          ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
06964          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
06965          if (res < 0)
06966                ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
06967          return -1;
06968       }
06969       break;
06970    case ZT_EVENT_NOALARM:
06971       i->inalarm = 0;
06972 #ifdef HAVE_PRI
06973       if (i->pri) {
06974           if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06975          /* dont annoy BRI TE mode users with layer2layer alarms */
06976           } else {
06977          ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06978          manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06979                     "Channel: %d\r\n", i->channel);
06980           }
06981       }
06982 #else
06983       ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
06984       manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
06985          "Channel: %d\r\n", i->channel);
06986 #endif
06987       break;
06988    case ZT_EVENT_ALARM:
06989       i->inalarm = 1;
06990       res = get_alarms(i);
06991 #ifdef HAVE_PRI
06992       if (i->pri) {
06993           if ((i->pri->nodetype == BRI_CPE_PTMP) || (i->pri->nodetype == BRI_CPE)) {
06994          /* dont annoy BRI TE mode users with layer2layer alarms */
06995           } else {
06996          ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
06997          manager_event(EVENT_FLAG_SYSTEM, "Alarm",
06998                     "Alarm: %s\r\n"
06999                     "Channel: %d\r\n",
07000                     alarm2str(res), i->channel);
07001           }
07002       }
07003 #else
07004       ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", i->channel, alarm2str(res));
07005       manager_event(EVENT_FLAG_SYSTEM, "Alarm",
07006          "Alarm: %s\r\n"
07007          "Channel: %d\r\n",
07008          alarm2str(res), i->channel);
07009 #endif
07010       /* fall thru intentionally */
07011    case ZT_EVENT_ONHOOK:
07012       if (i->radio)
07013          break;
07014       /* Back on hook.  Hang up. */
07015       switch (i->sig) {
07016       case SIG_FXOLS:
07017       case SIG_FXOGS:
07018       case SIG_FEATD:
07019       case SIG_FEATDMF:
07020       case SIG_FEATDMF_TA:
07021       case SIG_E911:
07022       case SIG_FGC_CAMA:
07023       case SIG_FGC_CAMAMF:
07024       case SIG_FEATB:
07025       case SIG_EM:
07026       case SIG_EM_E1:
07027       case SIG_EMWINK:
07028       case SIG_SF_FEATD:
07029       case SIG_SF_FEATDMF:
07030       case SIG_SF_FEATB:
07031       case SIG_SF:
07032       case SIG_SFWINK:
07033       case SIG_FXSLS:
07034       case SIG_FXSGS:
07035       case SIG_FXSKS:
07036       case SIG_GR303FXSKS:
07037          zt_disable_ec(i);
07038          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07039          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
07040          break;
07041       case SIG_GR303FXOKS:
07042       case SIG_FXOKS:
07043          zt_disable_ec(i);
07044          /* Diddle the battery for the zhone */
07045 #ifdef ZHONE_HACK
07046          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_OFFHOOK);
07047          usleep(1);
07048 #endif         
07049          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07050          zt_set_hook(i->subs[SUB_REAL].zfd, ZT_ONHOOK);
07051          break;
07052       case SIG_PRI:
07053          if (event != ZT_EVENT_ALARM) {
07054              zt_disable_ec(i);
07055              res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07056          }
07057          break;
07058       default:
07059          ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
07060          res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, -1);
07061          return -1;
07062       }
07063       break;
07064    case ZT_EVENT_POLARITY:
07065       switch (i->sig) {
07066       case SIG_FXSLS:
07067       case SIG_FXSKS:
07068       case SIG_FXSGS:
07069          /* We have already got a PR before the channel was 
07070             created, but it wasn't handled. We need polarity 
07071             to be REV for remote hangup detection to work. 
07072             At least in Spain */
07073          if (i->hanguponpolarityswitch)
07074             i->polarity = POLARITY_REV;
07075 
07076          if (i->cid_start == CID_START_POLARITY) {
07077             i->polarity = POLARITY_REV;
07078             ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity "
07079                    "CID detection on channel %d\n",
07080                    i->channel);
07081             chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
07082             if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
07083                ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
07084             }
07085          }
07086          break;
07087       default:
07088          ast_log(LOG_WARNING, "handle_init_event detected "
07089             "polarity reversal on non-FXO (SIG_FXS) "
07090             "interface %d\n", i->channel);
07091       }
07092       break;
07093    case ZT_EVENT_REMOVED: /* destroy channel */
07094       ast_log(LOG_NOTICE, 
07095             "Got ZT_EVENT_REMOVED. Destroying channel %d\n", 
07096             i->channel);
07097       zap_destroy_channel_bynum(i->channel);
07098       break;
07099    }
07100    pthread_attr_destroy(&attr);
07101    return 0;
07102 }
07103 
07104 static void *do_monitor(void *data)
07105 {
07106    int count, res, res2, spoint, pollres=0;
07107    struct zt_pvt *i;
07108    struct zt_pvt *last = NULL;
07109    time_t thispass = 0, lastpass = 0;
07110    int found;
07111    char buf[1024];
07112    struct pollfd *pfds=NULL;
07113    int lastalloc = -1;
07114    /* This thread monitors all the frame relay interfaces which are not yet in use
07115       (and thus do not have a separate thread) indefinitely */
07116    /* From here on out, we die whenever asked */
07117 #if 0
07118    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
07119       ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
07120       return NULL;
07121    }
07122    ast_log(LOG_DEBUG, "Monitor starting...\n");
07123 #endif
07124    for (;;) {
07125       /* Lock the interface list */
07126       ast_mutex_lock(&iflock);
07127       if (!pfds || (lastalloc != ifcount)) {
07128          if (pfds) {
07129             free(pfds);
07130             pfds = NULL;
07131          }
07132          if (ifcount) {
07133             if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
07134                ast_mutex_unlock(&iflock);
07135                return NULL;
07136             }
07137          }
07138          lastalloc = ifcount;
07139       }
07140       /* Build the stuff we're going to poll on, that is the socket of every
07141          zt_pvt that does not have an associated owner channel */
07142       count = 0;
07143       i = iflist;
07144       while (i) {
07145          if ((i->subs[SUB_REAL].zfd > -1) && i->sig && (!i->radio)) {
07146             if (!i->owner && !i->subs[SUB_REAL].owner) {
07147                /* This needs to be watched, as it lacks an owner */
07148                pfds[count].fd = i->subs[SUB_REAL].zfd;
07149                pfds[count].events = POLLPRI;
07150                pfds[count].revents = 0;
07151                /* Message waiting or r2 channels also get watched for reading */
07152                if (i->cidspill)
07153                   pfds[count].events |= POLLIN;
07154                count++;
07155             }
07156          }
07157          i = i->next;
07158       }
07159       /* Okay, now that we know what to do, release the interface lock */
07160       ast_mutex_unlock(&iflock);
07161       
07162       pthread_testcancel();
07163       /* Wait at least a second for something to happen */
07164       res = poll(pfds, count, 1000);
07165       pthread_testcancel();
07166       /* Okay, poll has finished.  Let's see what happened.  */
07167       if (res < 0) {
07168          if ((errno != EAGAIN) && (errno != EINTR))
07169             ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
07170          continue;
07171       }
07172       /* Alright, lock the interface list again, and let's look and see what has
07173          happened */
07174       ast_mutex_lock(&iflock);
07175       found = 0;
07176       spoint = 0;
07177       lastpass = thispass;
07178       thispass = time(NULL);
07179       i = iflist;
07180       while (i) {
07181          if (thispass != lastpass) {
07182             if (!found && ((i == last) || ((i == iflist) && !last))) {
07183                last = i;
07184                if (last) {
07185                   if (!last->cidspill && !last->owner && !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3) &&
07186                      (last->sig & __ZT_SIG_FXO)) {
07187                      res = ast_app_has_voicemail(last->mailbox, NULL);
07188                      if (last->msgstate != res) {
07189                         int x;
07190                         ast_log(LOG_DEBUG, "Message status for %s changed from %d to %d on %d\n", last->mailbox, last->msgstate, res, last->channel);
07191                         x = ZT_FLUSH_BOTH;
07192                         res2 = ioctl(last->subs[SUB_REAL].zfd, ZT_FLUSH, &x);
07193                         if (res2)
07194                            ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", last->channel);
07195                         if ((last->cidspill = ast_calloc(1, MAX_CALLERID_SIZE))) {
07196                            /* Turn on on hook transfer for 4 seconds */
07197                            x = 4000;
07198                            ioctl(last->subs[SUB_REAL].zfd, ZT_ONHOOKTRANSFER, &x);
07199                            last->cidlen = vmwi_generate(last->cidspill, res, 1, AST_LAW(last));
07200                            last->cidpos = 0;
07201                            last->msgstate = res;
07202                            last->onhooktime = thispass;
07203                         }
07204                         found ++;
07205                      }
07206                   }
07207                   last = last->next;
07208                }
07209             }
07210          }
07211          if ((i->subs[SUB_REAL].zfd > -1) && i->sig) {
07212             if (i->radio && !i->owner)
07213             {
07214                res = zt_get_event(i->subs[SUB_REAL].zfd);
07215                if (res)
07216                {
07217                   if (option_debug)
07218                      ast_log(LOG_DEBUG, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
07219                   /* Don't hold iflock while handling init events */
07220                   ast_mutex_unlock(&iflock);
07221                   handle_init_event(i, res);
07222                   ast_mutex_lock(&iflock);   
07223                }
07224                i = i->next;
07225                continue;
07226             }              
07227             pollres = ast_fdisset(pfds, i->subs[SUB_REAL].zfd, count, &spoint);
07228             if (pollres & POLLIN) {
07229                if (i->owner || i->subs[SUB_REAL].owner) {
07230 #ifdef HAVE_PRI
07231                   if (!i->pri)
07232 #endif                  
07233                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].zfd);
07234                   i = i->next;
07235                   continue;
07236                }
07237                if (!i->cidspill) {
07238                   ast_log(LOG_WARNING, "Whoa....  I'm reading but have no cidspill (%d)...\n", i->subs[SUB_REAL].zfd);
07239                   i = i->next;
07240                   continue;
07241                }
07242                res = read(i->subs[SUB_REAL].zfd, buf, sizeof(buf));
07243                if (res > 0) {
07244                   /* We read some number of bytes.  Write an equal amount of data */
07245                   if (res > i->cidlen - i->cidpos) 
07246                      res = i->cidlen - i->cidpos;
07247                   res2 = write(i->subs[SUB_REAL].zfd, i->cidspill + i->cidpos, res);
07248                   if (res2 > 0) {
07249                      i->cidpos += res2;
07250                      if (i->cidpos >= i->cidlen) {
07251                         free(i->cidspill);
07252                         i->cidspill = 0;
07253                         i->cidpos = 0;
07254                         i->cidlen = 0;
07255                      }
07256                   } else {
07257                      ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
07258                      i->msgstate = -1;
07259                   }
07260                } else {
07261                   ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
07262                }
07263                if (option_debug)
07264                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07265                /* Don't hold iflock while handling init events -- race with chlock */
07266                ast_mutex_unlock(&iflock);
07267                handle_init_event(i, res);
07268                ast_mutex_lock(&iflock);   
07269             }
07270             if (pollres & POLLPRI) {
07271                if (i->owner || i->subs[SUB_REAL].owner) {
07272 #ifdef HAVE_PRI
07273                   if (!i->pri)
07274 #endif                  
07275                      ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", i->subs[SUB_REAL].zfd);
07276                   i = i->next;
07277                   continue;
07278                }
07279                res = zt_get_event(i->subs[SUB_REAL].zfd);
07280                if (option_debug)
07281                   ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
07282                /* Don't hold iflock while handling init events */
07283                ast_mutex_unlock(&iflock);
07284                handle_init_event(i, res);
07285                ast_mutex_lock(&iflock);   
07286             }
07287          }
07288          i=i->next;
07289       }
07290       ast_mutex_unlock(&iflock);
07291    }
07292    /* Never reached */
07293    return NULL;
07294    
07295 }
07296 
07297 static int restart_monitor(void)
07298 {
07299    pthread_attr_t attr;
07300    pthread_attr_init(&attr);
07301    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07302    /* If we're supposed to be stopped -- stay stopped */
07303    if (monitor_thread == AST_PTHREADT_STOP)
07304       return 0;
07305    ast_mutex_lock(&monlock);
07306    if (monitor_thread == pthread_self()) {
07307       ast_mutex_unlock(&monlock);
07308       ast_log(LOG_WARNING, "Cannot kill myself\n");
07309       return -1;
07310    }
07311    if (monitor_thread != AST_PTHREADT_NULL) {
07312       /* Wake up the thread */
07313       pthread_kill(monitor_thread, SIGURG);
07314    } else {
07315       /* Start a new monitor */
07316       if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) {
07317          ast_mutex_unlock(&monlock);
07318          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
07319          pthread_attr_destroy(&attr);
07320          return -1;
07321       }
07322    }
07323    ast_mutex_unlock(&monlock);
07324    pthread_attr_destroy(&attr);
07325    return 0;
07326 }
07327 
07328 #ifdef HAVE_PRI
07329 static int pri_resolve_span(int *span, int channel, int offset, struct zt_spaninfo *si)
07330 {
07331    int x;
07332    int trunkgroup;
07333    /* Get appropriate trunk group if there is one */
07334    trunkgroup = pris[*span].mastertrunkgroup;
07335    if (trunkgroup) {
07336       /* Select a specific trunk group */
07337       for (x = 0; x < NUM_SPANS; x++) {
07338          if (pris[x].trunkgroup == trunkgroup) {
07339             *span = x;
07340             return 0;
07341          }
07342       }
07343       ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
07344       *span = -1;
07345    } else {
07346       if (pris[*span].trunkgroup) {
07347          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
07348          *span = -1;
07349       } else if (pris[*span].mastertrunkgroup) {
07350          ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
07351          *span = -1;
07352       } else {
07353          if (si->totalchans == 31) { /* if it's an E1 */
07354             pris[*span].dchannels[0] = 16 + offset;
07355          } else if (si->totalchans == 3) { /* if it's an S0 ZAPBRI */
07356             pris[*span].dchannels[0] = 3 + offset;
07357          } else {
07358             pris[*span].dchannels[0] = 24 + offset;
07359          }
07360          pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
07361          pris[*span].offset = offset;
07362          pris[*span].span = *span + 1;
07363       }
07364    }
07365    return 0;
07366 }
07367 
07368 static int pri_create_trunkgroup(int trunkgroup, int *channels)
07369 {
07370    struct zt_spaninfo si;
07371    ZT_PARAMS p;
07372    int fd;
07373    int span;
07374    int ospan=0;
07375    int x,y;
07376    for (x = 0; x < NUM_SPANS; x++) {
07377       if (pris[x].trunkgroup == trunkgroup) {
07378          ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
07379          return -1;
07380       }
07381    }
07382    for (y = 0; y < NUM_DCHANS; y++) {
07383       if (!channels[y]) 
07384          break;
07385       memset(&si, 0, sizeof(si));
07386       memset(&p, 0, sizeof(p));
07387       fd = open("/dev/zap/channel", O_RDWR);
07388       if (fd < 0) {
07389          ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
07390          return -1;
07391       }
07392       x = channels[y];
07393       if (ioctl(fd, ZT_SPECIFY, &x)) {
07394          ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
07395          zt_close(fd);
07396          return -1;
07397       }
07398       if (ioctl(fd, ZT_GET_PARAMS, &p)) {
07399          ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
07400          return -1;
07401       }
07402       if (ioctl(fd, ZT_SPANSTAT, &si)) {
07403          ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d)\n", channels[y], p.spanno);
07404          zt_close(fd);
07405          return -1;
07406       }
07407       span = p.spanno - 1;
07408       if (pris[span].trunkgroup) {
07409          ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
07410          zt_close(fd);
07411          return -1;
07412       }
07413       if (pris[span].pvts[0]) {
07414          ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
07415          zt_close(fd);
07416          return -1;
07417       }
07418       if (!y) {
07419          pris[span].trunkgroup = trunkgroup;
07420          pris[span].offset = channels[y] - p.chanpos;
07421          ospan = span;
07422       }
07423       pris[ospan].dchannels[y] = channels[y];
07424       pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
07425       pris[span].span = span + 1;
07426       zt_close(fd);
07427    }
07428    return 0;   
07429 }
07430 
07431 static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
07432 {
07433    if (pris[span].mastertrunkgroup) {
07434       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);
07435       return -1;
07436    }
07437    pris[span].mastertrunkgroup = trunkgroup;
07438    pris[span].prilogicalspan = logicalspan;
07439    return 0;
07440 }
07441 
07442 #endif
07443 
07444 #ifdef HAVE_GSMAT
07445 static void *gsm_dchannel(void *vgsm);
07446 #endif
07447 
07448 static struct zt_pvt *mkintf(int channel, struct zt_chan_conf conf, struct zt_pri *pri, int reloading)
07449 {
07450    /* Make a zt_pvt structure for this interface (or CRV if "pri" is specified) */
07451    struct zt_pvt *tmp = NULL, *tmp2,  *prev = NULL;
07452    char fn[80];
07453 #if 1
07454    struct zt_bufferinfo bi;
07455 #endif
07456    struct zt_spaninfo si;
07457    int res;
07458    int span=0;
07459    int here = 0;
07460    int x;
07461    struct zt_pvt **wlist;
07462    struct zt_pvt **wend;
07463    ZT_PARAMS p;
07464 
07465    wlist = &iflist;
07466    wend = &ifend;
07467 
07468 #ifdef HAVE_PRI
07469    if (pri) {
07470       wlist = &pri->crvs;
07471       wend = &pri->crvend;
07472    }
07473 #endif
07474 
07475    tmp2 = *wlist;
07476    prev = NULL;
07477 
07478    while (tmp2) {
07479       if (!tmp2->destroy) {
07480          if (tmp2->channel == channel) {
07481             tmp = tmp2;
07482             here = 1;
07483             break;
07484          }
07485          if (tmp2->channel > channel) {
07486             break;
07487          }
07488       }
07489       prev = tmp2;
07490       tmp2 = tmp2->next;
07491    }
07492 
07493    if (!here && !reloading) {
07494       if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
07495          destroy_zt_pvt(&tmp);
07496          return NULL;
07497       }
07498       ast_mutex_init(&tmp->lock);
07499       ifcount++;
07500       for (x = 0; x < 3; x++)
07501          tmp->subs[x].zfd = -1;
07502       tmp->channel = channel;
07503    }
07504 
07505    if (tmp) {
07506       if (!here) {
07507          if ((channel != CHAN_PSEUDO) && !pri) {
07508             snprintf(fn, sizeof(fn), "%d", channel);
07509             /* Open non-blocking */
07510             if (!here)
07511                tmp->subs[SUB_REAL].zfd = zt_open(fn);
07512             /* Allocate a zapata structure */
07513             if (tmp->subs[SUB_REAL].zfd < 0) {
07514                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);
07515                destroy_zt_pvt(&tmp);
07516                return NULL;
07517             }
07518             memset(&p, 0, sizeof(p));
07519             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07520             if (res < 0) {
07521                ast_log(LOG_ERROR, "Unable to get parameters\n");
07522                destroy_zt_pvt(&tmp);
07523                return NULL;
07524             }
07525             if (p.sigtype != (conf.chan.sig & 0x3ffff)) {
07526                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));
07527                destroy_zt_pvt(&tmp);
07528                return NULL;
07529             }
07530             tmp->law = p.curlaw;
07531             tmp->span = p.spanno;
07532             span = p.spanno - 1;
07533          } else {
07534             if (channel == CHAN_PSEUDO)
07535                conf.chan.sig = 0;
07536             else if ((conf.chan.sig != SIG_FXOKS) && (conf.chan.sig != SIG_FXSKS)) {
07537                ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
07538                return NULL;
07539             }
07540          }
07541 #ifdef HAVE_PRI
07542          if ((conf.chan.sig == SIG_PRI) || (conf.chan.sig == SIG_GR303FXOKS) || (conf.chan.sig == SIG_GR303FXSKS)) {
07543             int offset;
07544             int myswitchtype;
07545             int matchesdchan;
07546             int x,y;
07547             offset = 0;
07548             if ((conf.chan.sig == SIG_PRI) && ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &offset)) {
07549                ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
07550                destroy_zt_pvt(&tmp);
07551                return NULL;
07552             }
07553             if (span >= NUM_SPANS) {
07554                ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
07555                destroy_zt_pvt(&tmp);
07556                return NULL;
07557             } else {
07558                si.spanno = 0;
07559                if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07560                   ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07561                   destroy_zt_pvt(&tmp);
07562                   return NULL;
07563                }
07564                /* Store the logical span first based upon the real span */
07565                tmp->logicalspan = pris[span].prilogicalspan;
07566                pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
07567                if (span < 0) {
07568                   ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
07569                   destroy_zt_pvt(&tmp);
07570                   return NULL;
07571                }
07572                if (conf.chan.sig == SIG_PRI)
07573                   myswitchtype = conf.pri.switchtype;
07574                else
07575                   myswitchtype = PRI_SWITCH_GR303_TMC;
07576                /* Make sure this isn't a d-channel */
07577                matchesdchan=0;
07578                for (x = 0; x < NUM_SPANS; x++) {
07579                   for (y = 0; y < NUM_DCHANS; y++) {
07580                      if (pris[x].dchannels[y] == tmp->channel) {
07581                         matchesdchan = 1;
07582                         break;
07583                      }
07584                   }
07585                }
07586                offset = p.chanpos;
07587                if (!matchesdchan) {
07588                   if (pris[span].nodetype && (pris[span].nodetype != conf.pri.nodetype)) {
07589                      ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
07590                      destroy_zt_pvt(&tmp);
07591                      return NULL;
07592                   }
07593                   if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
07594                      ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
07595                      destroy_zt_pvt(&tmp);
07596                      return NULL;
07597                   }
07598                   if ((pris[span].dialplan) && (pris[span].dialplan != conf.pri.dialplan)) {
07599                      ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
07600                      destroy_zt_pvt(&tmp);
07601                      return NULL;
07602                   }
07603                   if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf.pri.idledial)) {
07604                      ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf.pri.idledial);
07605                      destroy_zt_pvt(&tmp);
07606                      return NULL;
07607                   }
07608                   if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf.pri.idleext)) {
07609                      ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf.pri.idleext);
07610                      destroy_zt_pvt(&tmp);
07611                      return NULL;
07612                   }
07613                                              if ((pris[span].localdialplan) && (pris[span].localdialplan != conf.pri.localdialplan)) {
07614                      ast_log(LOG_ERROR, "Span %d is already a %s local dialing plan\n", span + 1, dialplan2str(pris[span].localdialplan));
07615                      destroy_zt_pvt(&tmp);
07616                                                    return NULL;
07617                      }
07618                   if (pris[span].minunused && (pris[span].minunused != conf.pri.minunused)) {
07619                      ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf.pri.minunused);
07620                      destroy_zt_pvt(&tmp);
07621                      return NULL;
07622                   }
07623                   if (pris[span].minidle && (pris[span].minidle != conf.pri.minidle)) {
07624                      ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf.pri.minidle);
07625                      destroy_zt_pvt(&tmp);
07626                      return NULL;
07627                   }
07628                   if (pris[span].numchans >= MAX_CHANNELS) {
07629                      ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
07630                         pris[span].trunkgroup);
07631                      destroy_zt_pvt(&tmp);
07632                      return NULL;
07633                   }
07634                   pris[span].nodetype = conf.pri.nodetype;
07635 
07636                   if (conf.pri.nodetype == BRI_NETWORK_PTMP) {
07637                       pris[span].dchanavail[0] =  DCHAN_AVAILABLE;
07638                       pri_find_dchan(&pris[span]);
07639                   }
07640                   pris[span].switchtype = myswitchtype;
07641                   pris[span].nsf = conf.pri.nsf;
07642                   pris[span].dialplan = conf.pri.dialplan;
07643                   pris[span].localdialplan = conf.pri.localdialplan;
07644                   pris[span].pvts[pris[span].numchans++] = tmp;
07645                   pris[span].minunused = conf.pri.minunused;
07646                   pris[span].minidle = conf.pri.minidle;
07647                   pris[span].overlapdial = conf.pri.overlapdial;
07648                   pris[span].usercid = conf.pri.usercid;
07649                   pris[span].suspended_calls = NULL;
07650                   pris[span].holded_calls = NULL;
07651                   pris[span].facilityenable = conf.pri.facilityenable;
07652                   ast_copy_string(pris[span].idledial, conf.pri.idledial, sizeof(pris[span].idledial));
07653                   ast_copy_string(pris[span].idleext, conf.pri.idleext, sizeof(pris[span].idleext));
07654                   ast_copy_string(pris[span].nocid, conf.pri.nocid, sizeof(pris[span].nocid));
07655                   ast_copy_string(pris[span].withheldcid, conf.pri.withheldcid, sizeof(pris[span].withheldcid));
07656                   ast_copy_string(pris[span].internationalprefix, conf.pri.internationalprefix, sizeof(pris[span].internationalprefix));
07657                   ast_copy_string(pris[span].nationalprefix, conf.pri.nationalprefix, sizeof(pris[span].nationalprefix));
07658                   ast_copy_string(pris[span].localprefix, conf.pri.localprefix, sizeof(pris[span].localprefix));
07659                   ast_copy_string(pris[span].privateprefix, conf.pri.privateprefix, sizeof(pris[span].privateprefix));
07660                   ast_copy_string(pris[span].unknownprefix, conf.pri.unknownprefix, sizeof(pris[span].unknownprefix));
07661                   pris[span].resetinterval = conf.pri.resetinterval;
07662                   
07663                   tmp->pri = &pris[span];
07664                   tmp->prioffset = offset;
07665                   tmp->call = NULL;
07666                } else {
07667                   ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
07668                   destroy_zt_pvt(&tmp);
07669                   return NULL;
07670                }
07671             }
07672          } else {
07673             tmp->prioffset = 0;
07674          }
07675 #endif
07676 #ifdef HAVE_GSMAT
07677       if (chan_conf.signalling == SIG_GSM) {
07678           struct zt_bufferinfo bi;
07679           ast_mutex_init(&tmp->gsm.lock);
07680           strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1);
07681           strncpy(tmp->gsm.exten, gsm_modem_exten, sizeof(tmp->gsm.exten) - 1);
07682           tmp->gsm.available = 0;
07683           snprintf(fn, sizeof(fn), "%d", channel + 1);
07684           /* Open non-blocking */
07685           tmp->gsm.fd = zt_open(fn);
07686           bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07687           bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07688           bi.numbufs = 16;
07689           bi.bufsize = 1024;
07690           if (ioctl(tmp->gsm.fd, ZT_SET_BUFINFO, &bi)) {
07691          ast_log(LOG_ERROR, "Unable to set buffer info on channel '%s': %s\n", fn, strerror(errno));
07692          return NULL;
07693           }
07694           tmp->gsm.pvt = tmp;
07695           tmp->gsm.span = tmp->span;
07696           tmp->gsm.modul = gsm_new(tmp->gsm.fd, 0, tmp->gsm.pin, tmp->span, tmp->channel);
07697           if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_AUDIOMODE, tmp->channel)) {
07698          ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d: %s\n", tmp->channel, strerror(errno));
07699          destroy_zt_pvt(&tmp);
07700          return NULL;
07701           }
07702           if (ast_pthread_create(&tmp->gsm.master, NULL, gsm_dchannel, &tmp->gsm)) {
07703          zt_close(tmp->gsm.fd);
07704           }
07705       }
07706 #endif
07707       } else {
07708          conf.chan.sig = tmp->sig;
07709          conf.chan.radio = tmp->radio;
07710          memset(&p, 0, sizeof(p));
07711          if (tmp->subs[SUB_REAL].zfd > -1)
07712             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &p);
07713       }
07714       /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
07715       if ((conf.chan.sig == SIG_FXSKS) || (conf.chan.sig == SIG_FXSLS) ||
07716           (conf.chan.sig == SIG_EM) || (conf.chan.sig == SIG_EM_E1) ||  (conf.chan.sig == SIG_EMWINK) ||
07717          (conf.chan.sig == SIG_FEATD) || (conf.chan.sig == SIG_FEATDMF) || (conf.chan.sig == SIG_FEATDMF_TA) ||
07718            (conf.chan.sig == SIG_FEATB) || (conf.chan.sig == SIG_E911) ||
07719           (conf.chan.sig == SIG_SF) || (conf.chan.sig == SIG_SFWINK) || (conf.chan.sig == SIG_FGC_CAMA) || (conf.chan.sig == SIG_FGC_CAMAMF) ||
07720          (conf.chan.sig == SIG_SF_FEATD) || (conf.chan.sig == SIG_SF_FEATDMF) ||
07721            (conf.chan.sig == SIG_SF_FEATB)) {
07722          p.starttime = 250;
07723       }
07724       if (conf.chan.radio) {
07725          /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
07726          p.channo = channel;
07727          p.rxwinktime = 1;
07728          p.rxflashtime = 1;
07729          p.starttime = 1;
07730          p.debouncetime = 5;
07731       }
07732       if (!conf.chan.radio) {
07733          p.channo = channel;
07734          /* Override timing settings based on config file */
07735          if (conf.timing.prewinktime >= 0)
07736             p.prewinktime = conf.timing.prewinktime;
07737          if (conf.timing.preflashtime >= 0)
07738             p.preflashtime = conf.timing.preflashtime;
07739          if (conf.timing.winktime >= 0)
07740             p.winktime = conf.timing.winktime;
07741          if (conf.timing.flashtime >= 0)
07742             p.flashtime = conf.timing.flashtime;
07743          if (conf.timing.starttime >= 0)
07744             p.starttime = conf.timing.starttime;
07745          if (conf.timing.rxwinktime >= 0)
07746             p.rxwinktime = conf.timing.rxwinktime;
07747          if (conf.timing.rxflashtime >= 0)
07748             p.rxflashtime = conf.timing.rxflashtime;
07749          if (conf.timing.debouncetime >= 0)
07750             p.debouncetime = conf.timing.debouncetime;
07751       }
07752       
07753       /* dont set parms on a pseudo-channel (or CRV) */
07754       if (tmp->subs[SUB_REAL].zfd >= 0)
07755       {
07756          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_PARAMS, &p);
07757          if (res < 0) {
07758             ast_log(LOG_ERROR, "Unable to set parameters\n");
07759             destroy_zt_pvt(&tmp);
07760             return NULL;
07761          }
07762       }
07763 #if 1
07764       if (!here && (tmp->subs[SUB_REAL].zfd > -1)) {
07765          memset(&bi, 0, sizeof(bi));
07766          res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
07767          if (!res) {
07768             bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
07769             bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
07770             bi.numbufs = numbufs;
07771             res = ioctl(tmp->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
07772             if (res < 0) {
07773                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
07774             }
07775          } else
07776             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
07777       }
07778 #endif
07779       tmp->immediate = conf.chan.immediate;
07780       tmp->transfertobusy = conf.chan.transfertobusy;
07781       tmp->sig = conf.chan.sig;
07782       tmp->outsigmod = conf.chan.outsigmod;
07783       tmp->radio = conf.chan.radio;
07784       tmp->ringt_base = ringt_base;
07785       tmp->firstradio = 0;
07786       if ((conf.chan.sig == SIG_FXOKS) || (conf.chan.sig == SIG_FXOLS) || (conf.chan.sig == SIG_FXOGS))
07787          tmp->permcallwaiting = conf.chan.callwaiting;
07788       else
07789          tmp->permcallwaiting = 0;
07790       /* Flag to destroy the channel must be cleared on new mkif.  Part of changes for reload to work */
07791       tmp->destroy = 0;
07792       tmp->drings = drings;
07793       tmp->usedistinctiveringdetection = conf.chan.usedistinctiveringdetection;
07794       tmp->callwaitingcallerid = conf.chan.callwaitingcallerid;
07795       tmp->threewaycalling = conf.chan.threewaycalling;
07796       tmp->adsi = conf.chan.adsi;
07797       tmp->use_smdi = conf.chan.use_smdi;
07798       tmp->permhidecallerid = conf.chan.hidecallerid;
07799       tmp->callreturn = conf.chan.callreturn;
07800       tmp->echocancel = conf.chan.echocancel;
07801       tmp->echotraining = conf.chan.echotraining;
07802       tmp->pulse = conf.chan.pulse;
07803       tmp->echocanbridged = conf.chan.echocanbridged;
07804       tmp->busydetect = conf.chan.busydetect;
07805       tmp->busycount = conf.chan.busycount;
07806       tmp->busy_tonelength = conf.chan.busy_tonelength;
07807       tmp->busy_quietlength = conf.chan.busy_quietlength;
07808       tmp->callprogress = conf.chan.callprogress;
07809       tmp->cancallforward = conf.chan.cancallforward;
07810       tmp->dtmfrelax = conf.chan.dtmfrelax;
07811       tmp->callwaiting = tmp->permcallwaiting;
07812       tmp->hidecallerid = tmp->permhidecallerid;
07813       tmp->channel = channel;
07814       tmp->stripmsd = conf.chan.stripmsd;
07815       tmp->use_callerid = conf.chan.use_callerid;
07816       tmp->cid_signalling = conf.chan.cid_signalling;
07817       tmp->cid_start = conf.chan.cid_start;
07818       tmp->zaptrcallerid = conf.chan.zaptrcallerid;
07819       tmp->restrictcid = conf.chan.restrictcid;
07820       tmp->use_callingpres = conf.chan.use_callingpres;
07821       tmp->priindication_oob = conf.chan.priindication_oob;
07822       tmp->pritransfer = conf.chan.pritransfer;
07823       tmp->priexclusive = conf.chan.priexclusive;
07824       if (tmp->usedistinctiveringdetection) {
07825          if (!tmp->use_callerid) {
07826             ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
07827             tmp->use_callerid = 1;
07828          }
07829       }
07830 
07831       if (tmp->cid_signalling == CID_SIG_SMDI) {
07832          if (!tmp->use_smdi) {
07833             ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
07834             tmp->use_smdi = 1;
07835          }
07836       }
07837       if (tmp->use_smdi) {
07838          tmp->smdi_iface = ast_smdi_interface_find(conf.smdi_port);
07839          if (!(tmp->smdi_iface)) {
07840             ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
07841             tmp->use_smdi = 0;
07842          }
07843       }
07844 
07845       ast_copy_string(tmp->accountcode, conf.chan.accountcode, sizeof(tmp->accountcode));
07846       tmp->amaflags = conf.chan.amaflags;
07847       if (!here) {
07848          tmp->confno = -1;
07849          tmp->propconfno = -1;
07850       }
07851       tmp->canpark = conf.chan.canpark;
07852       tmp->transfer = conf.chan.transfer;
07853       ast_copy_string(tmp->defcontext,conf.chan.context,sizeof(tmp->defcontext));
07854       ast_copy_string(tmp->language, conf.chan.language, sizeof(tmp->language));
07855       ast_copy_string(tmp->mohinterpret, conf.chan.mohinterpret, sizeof(tmp->mohinterpret));
07856       ast_copy_string(tmp->mohsuggest, conf.chan.mohsuggest, sizeof(tmp->mohsuggest));
07857       ast_copy_string(tmp->context, conf.chan.context, sizeof(tmp->context));
07858       ast_copy_string(tmp->cid_num, conf.chan.cid_num, sizeof(tmp->cid_num));
07859       tmp->cid_ton = 0;
07860       ast_copy_string(tmp->cid_name, conf.chan.cid_name, sizeof(tmp->cid_name));
07861       ast_copy_string(tmp->mailbox, conf.chan.mailbox, sizeof(tmp->mailbox));
07862       tmp->msgstate = -1;
07863       tmp->group = conf.chan.group;
07864       tmp->callgroup = conf.chan.callgroup;
07865       tmp->pickupgroup= conf.chan.pickupgroup;
07866       tmp->rxgain = conf.chan.rxgain;
07867       tmp->txgain = conf.chan.txgain;
07868       tmp->tonezone = conf.chan.tonezone;
07869       tmp->onhooktime = time(NULL);
07870       if (tmp->subs[SUB_REAL].zfd > -1) {
07871          set_actual_gain(tmp->subs[SUB_REAL].zfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
07872          if (tmp->dsp)
07873             ast_dsp_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
07874          update_conf(tmp);
07875          if (!here) {
07876             if (conf.chan.sig != SIG_PRI)
07877                /* Hang it up to be sure it's good */
07878                zt_set_hook(tmp->subs[SUB_REAL].zfd, ZT_ONHOOK);
07879          }
07880          ioctl(tmp->subs[SUB_REAL].zfd,ZT_SETTONEZONE,&tmp->tonezone);
07881 #ifdef HAVE_PRI
07882          /* the dchannel is down so put the channel in alarm */
07883          if (tmp->pri && !pri_is_up(tmp->pri))
07884             tmp->inalarm = 1;
07885          else
07886             tmp->inalarm = 0;
07887 #endif            
07888          memset(&si, 0, sizeof(si));
07889          if (ioctl(tmp->subs[SUB_REAL].zfd,ZT_SPANSTAT,&si) == -1) {
07890             ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
07891             destroy_zt_pvt(&tmp);
07892             return NULL;
07893          }
07894          if (si.alarms) tmp->inalarm = 1;
07895       }
07896 
07897       tmp->polarityonanswerdelay = conf.chan.polarityonanswerdelay;
07898       tmp->answeronpolarityswitch = conf.chan.answeronpolarityswitch;
07899       tmp->hanguponpolarityswitch = conf.chan.hanguponpolarityswitch;
07900       tmp->sendcalleridafter = conf.chan.sendcalleridafter;
07901 
07902    }
07903    if (tmp && !here) {
07904       /* nothing on the iflist */
07905       if (!*wlist) {
07906          *wlist = tmp;
07907          tmp->prev = NULL;
07908          tmp->next = NULL;
07909          *wend = tmp;
07910       } else {
07911          /* at least one member on the iflist */
07912          struct zt_pvt *working = *wlist;
07913 
07914          /* check if we maybe have to put it on the begining */
07915          if (working->channel > tmp->channel) {
07916             tmp->next = *wlist;
07917             tmp->prev = NULL;
07918             (*wlist)->prev = tmp;
07919             *wlist = tmp;
07920          } else {
07921          /* go through all the members and put the member in the right place */
07922             while (working) {
07923                /* in the middle */
07924                if (working->next) {
07925                   if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
07926                      tmp->next = working->next;
07927                      tmp->prev = working;
07928                      working->next->prev = tmp;
07929                      working->next = tmp;
07930                      break;
07931                   }
07932                } else {
07933                /* the last */
07934                   if (working->channel < tmp->channel) {
07935                      working->next = tmp;
07936                      tmp->next = NULL;
07937                      tmp->prev = working;
07938                      *wend = tmp;
07939                      break;
07940                   }
07941                }
07942                working = working->next;
07943             }
07944          }
07945       }
07946    }
07947    return tmp;
07948 }
07949 
07950 static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch, int *busy, int *channelmatched, int *groupmatched)
07951 {
07952    int res;
07953    ZT_PARAMS par;
07954 
07955    /* First, check group matching */
07956    if (groupmatch) {
07957       if ((p->group & groupmatch) != groupmatch)
07958          return 0;
07959       *groupmatched = 1;
07960    }
07961    /* Check to see if we have a channel match */
07962    if (channelmatch != -1) {
07963       if (p->channel != channelmatch)
07964          return 0;
07965       *channelmatched = 1;
07966    }
07967    /* We're at least busy at this point */
07968    if (busy) {
07969       if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
07970          *busy = 1;
07971    }
07972    /* If do not disturb, definitely not */
07973    if (p->dnd)
07974       return 0;
07975    /* If guard time, definitely not */
07976    if (p->guardtime && (time(NULL) < p->guardtime)) 
07977       return 0;
07978       
07979    /* If no owner definitely available */
07980    if (!p->owner) {
07981 #ifdef HAVE_PRI
07982       /* Trust PRI */
07983       if (p->pri) {
07984          if (p->resetting || p->call)
07985             return 0;
07986          else
07987             return 1;
07988       }
07989 #endif
07990 #ifdef HAVE_GSMAT
07991       if (p->gsm.modul) {
07992           return gsm_available(p->gsm.modul);
07993       }
07994 
07995 #endif
07996       if (!(p->radio || (p->oprmode < 0)))
07997       {
07998          if (!p->sig || (p->sig == SIG_FXSLS))
07999             return 1;
08000          /* Check hook state */
08001          if (p->subs[SUB_REAL].zfd > -1)
08002             res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par);
08003          else {
08004             /* Assume not off hook on CVRS */
08005             res = 0;
08006             par.rxisoffhook = 0;
08007          }
08008          if (res) {
08009             ast_log(LOG_WARNING, "Unable to check hook state on channel %d\n", p->channel);
08010          } else if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
08011             /* When "onhook" that means no battery on the line, and thus
08012               it is out of service..., if it's on a TDM card... If it's a channel
08013               bank, there is no telling... */
08014             if (par.rxbits > -1)
08015                return 1;
08016             if (par.rxisoffhook)
08017                return 1;
08018             else
08019 #ifdef ZAP_CHECK_HOOKSTATE
08020                return 0;
08021 #else
08022                return 1;
08023 #endif
08024          } else if (par.rxisoffhook) {
08025             ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
08026             /* Not available when the other end is off hook */
08027             return 0;
08028          }
08029       }
08030       return 1;
08031    }
08032 
08033    /* If it's not an FXO, forget about call wait */
08034    if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS)) 
08035       return 0;
08036 
08037    if (!p->callwaiting) {
08038       /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
08039       return 0;
08040    }
08041 
08042    if (p->subs[SUB_CALLWAIT].zfd > -1) {
08043       /* If there is already a call waiting call, then we can't take a second one */
08044       return 0;
08045    }
08046    
08047    if ((p->owner->_state != AST_STATE_UP) &&
08048        ((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
08049       /* If the current call is not up, then don't allow the call */
08050       return 0;
08051    }
08052    if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
08053       /* Can't take a call wait when the three way calling hasn't been merged yet. */
08054       return 0;
08055    }
08056    /* We're cool */
08057    return 1;
08058 }
08059 
08060 static struct zt_pvt *chandup(struct zt_pvt *src)
08061 {
08062    struct zt_pvt *p;
08063    ZT_BUFFERINFO bi;
08064    int res;
08065    
08066    if ((p = ast_malloc(sizeof(*p)))) {
08067       memcpy(p, src, sizeof(struct zt_pvt));
08068       ast_mutex_init(&p->lock);
08069       p->subs[SUB_REAL].zfd = zt_open("/dev/zap/pseudo");
08070       /* Allocate a zapata structure */
08071       if (p->subs[SUB_REAL].zfd < 0) {
08072          ast_log(LOG_ERROR, "Unable to dup channel: %s\n",  strerror(errno));
08073          destroy_zt_pvt(&p);
08074          return NULL;
08075       }
08076       res = ioctl(p->subs[SUB_REAL].zfd, ZT_GET_BUFINFO, &bi);
08077       if (!res) {
08078          bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
08079          bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
08080          bi.numbufs = numbufs;
08081          res = ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BUFINFO, &bi);
08082          if (res < 0) {
08083             ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel\n");
08084          }
08085       } else
08086          ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel\n");
08087    }
08088    p->destroy = 1;
08089    p->next = iflist;
08090    iflist = p;
08091    return p;
08092 }
08093    
08094 
08095 #ifdef HAVE_PRI
08096 static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
08097 {
08098    int x;
08099    if (backwards)
08100       x = pri->numchans;
08101    else
08102       x = 0;
08103    for (;;) {
08104       if (backwards && (x < 0))
08105          break;
08106       if (!backwards && (x >= pri->numchans))
08107          break;
08108       if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner && !pri->pvts[x]->call) {
08109          ast_log(LOG_DEBUG, "Found empty available channel %d/%d\n", 
08110             pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
08111          return x;
08112       }
08113       if (backwards)
08114          x--;
08115       else
08116          x++;
08117    }
08118    return -1;
08119 }
08120 #endif
08121 
08122 static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
08123 {
08124    int groupmatch = 0;
08125    int channelmatch = -1;
08126    int roundrobin = 0;
08127    int callwait = 0;
08128    int busy = 0;
08129    struct zt_pvt *p;
08130    struct ast_channel *tmp = NULL;
08131    char *dest=NULL;
08132    int x;
08133    char *s;
08134    char opt=0;
08135    int res=0, y=0;
08136    int backwards = 0;
08137 #ifdef HAVE_PRI
08138    int crv;
08139    int bearer = -1;
08140    int trunkgroup;
08141    struct zt_pri *pri=NULL;
08142 #endif   
08143    struct zt_pvt *exit, *start, *end;
08144    ast_mutex_t *lock;
08145    int channelmatched = 0;
08146    int groupmatched = 0;
08147    
08148    /* Assume we're locking the iflock */
08149    lock = &iflock;
08150    start = iflist;
08151    end = ifend;
08152    if (data) {
08153       dest = ast_strdupa((char *)data);
08154    } else {
08155       ast_log(LOG_WARNING, "Channel requested with no data\n");
08156       return NULL;
08157    }
08158    if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
08159       /* Retrieve the group number */
08160       char *stringp=NULL;
08161       stringp=dest + 1;
08162       s = strsep(&stringp, "/");
08163       if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08164          ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
08165          return NULL;
08166       }
08167       groupmatch = 1 << x;
08168       if (toupper(dest[0]) == 'G') {
08169          if (dest[0] == 'G') {
08170             backwards = 1;
08171             p = ifend;
08172          } else
08173             p = iflist;
08174       } else {
08175          if (dest[0] == 'R') {
08176             backwards = 1;
08177             p = round_robin[x]?round_robin[x]->prev:ifend;
08178             if (!p)
08179                p = ifend;
08180          } else {
08181             p = round_robin[x]?round_robin[x]->next:iflist;
08182             if (!p)
08183                p = iflist;
08184          }
08185          roundrobin = 1;
08186       }
08187    } else {
08188       char *stringp=NULL;
08189       stringp=dest;
08190       s = strsep(&stringp, "/");
08191       p = iflist;
08192       if (!strcasecmp(s, "pseudo")) {
08193          /* Special case for pseudo */
08194          x = CHAN_PSEUDO;
08195          channelmatch = x;
08196       } 
08197 #ifdef HAVE_PRI
08198       else if ((res = sscanf(s, "%d:%d%c%d", &trunkgroup, &crv, &opt, &y)) > 1) {
08199          if ((trunkgroup < 1) || (crv < 1)) {
08200             ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
08201             return NULL;
08202          }
08203          res--;
08204          for (x = 0; x < NUM_SPANS; x++) {
08205             if (pris[x].trunkgroup == trunkgroup) {
08206                pri = pris + x;
08207                lock = &pri->lock;
08208                start = pri->crvs;
08209                end = pri->crvend;
08210                break;
08211             }
08212          }
08213          if (!pri) {
08214             ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
08215             return NULL;
08216          }
08217          channelmatch = crv;
08218          p = pris[x].crvs;
08219       }
08220 #endif   
08221       else if ((res = sscanf(s, "%d%c%d", &x, &opt, &y)) < 1) {
08222          ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
08223          return NULL;
08224       } else {
08225          channelmatch = x;
08226       }
08227    }
08228    /* Search for an unowned channel */
08229    ast_mutex_lock(lock);
08230    exit = p;
08231    while (p && !tmp) {
08232       if (roundrobin)
08233          round_robin[x] = p;
08234 #if 0
08235       ast_verbose("name = %s, %d, %d, %d\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
08236 #endif
08237 
08238       if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
08239          if (option_debug)
08240             ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
08241             if (p->inalarm) 
08242                goto next;
08243 
08244          callwait = (p->owner != NULL);
08245 #ifdef HAVE_PRI
08246          if (pri && (p->subs[SUB_REAL].zfd < 0)) {
08247             if (p->sig != SIG_FXSKS) {
08248                /* Gotta find an actual channel to use for this
08249                   CRV if this isn't a callwait */
08250                bearer = pri_find_empty_chan(pri, 0);
08251                if (bearer < 0) {
08252                   ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
08253                   p = NULL;
08254                   break;
08255                }
08256                pri_assign_bearer(p, pri, pri->pvts[bearer]);
08257             } else {
08258                if (alloc_sub(p, 0)) {
08259                   ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
08260                   p = NULL;
08261                   break;
08262                } else
08263                   ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
08264                p->pri = pri;
08265             }
08266          }
08267 #endif         
08268          if (p->channel == CHAN_PSEUDO) {
08269             p = chandup(p);
08270             if (!p) {
08271                break;
08272             }
08273          }
08274          if (p->owner) {
08275             if (alloc_sub(p, SUB_CALLWAIT)) {
08276                p = NULL;
08277                break;
08278             }
08279          }
08280          p->outgoing = 1;
08281          tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
08282 #ifdef HAVE_PRI
08283          if (p->bearer) {
08284             /* Log owner to bearer channel, too */
08285             p->bearer->owner = tmp;
08286          }
08287 #endif         
08288          /* Make special notes */
08289          if (res > 1) {
08290             if (opt == 'c') {
08291                /* Confirm answer */
08292                p->confirmanswer = 1;
08293             } else if (opt == 'r') {
08294                /* Distinctive ring */
08295                if (res < 3)
08296                   ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
08297                else
08298                   p->distinctivering = y;
08299             } else if (opt == 'd') {
08300                /* If this is an ISDN call, make it digital */
08301                p->digital = 1;
08302                if (tmp)
08303                   tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
08304             } else if (opt == 'm') {
08305                /* If this is a modem/fax call, pretend to have the fax handled and dont do EC */
08306                p->faxhandled = 1;
08307                if (tmp)
08308                    tmp->transfercapability = AST_TRANS_CAP_3_1K_AUDIO;
08309             } else {
08310                ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
08311             }
08312          }
08313          /* Note if the call is a call waiting call */
08314          if (tmp && callwait)
08315             tmp->cdrflags |= AST_CDR_CALLWAIT;
08316          break;
08317       }
08318 next:
08319       if (backwards) {
08320          p = p->prev;
08321          if (!p)
08322             p = end;
08323       } else {
08324          p = p->next;
08325          if (!p)
08326             p = start;
08327       }
08328       /* stop when you roll to the one that we started from */
08329       if (p == exit)
08330          break;
08331    }
08332    ast_mutex_unlock(lock);
08333    restart_monitor();
08334    if (callwait)
08335       *cause = AST_CAUSE_BUSY;
08336    else if (!tmp) {
08337       if (channelmatched) {
08338          if (busy)
08339             *cause = AST_CAUSE_BUSY;
08340       } else if (groupmatched) {
08341          *cause = AST_CAUSE_CONGESTION;
08342       } else {
08343          *cause = AST_CAUSE_CONGESTION;
08344       }
08345    }
08346       
08347    return tmp;
08348 }
08349 
08350 #ifdef HAVE_GSMAT
08351 static int zt_reset_span(int span, int sleep) {
08352    int ctl;
08353    int res;
08354 
08355    ctl = open("/dev/zap/ctl", O_RDWR);
08356    if (ctl < 0) {
08357       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
08358       return -1;
08359    }
08360    ast_verbose(VERBOSE_PREFIX_2 "Shutting down span %d. Please wait...\n", span);
08361    res = ioctl(ctl, ZT_SHUTDOWN, &span);
08362    if (res) {
08363       ast_log(LOG_WARNING, "error shutting down span %d\n", span);
08364       return -1;
08365    }
08366    usleep(sleep * 1000);
08367    ast_verbose(VERBOSE_PREFIX_2 "Starting up span %d. Please wait...\n", span);
08368    res = ioctl(ctl, ZT_STARTUP, &span);
08369    if (res) {
08370       ast_log(LOG_WARNING, "error starting up span %d\n", span);
08371       return -1;
08372    }
08373    ast_verbose(VERBOSE_PREFIX_2 "Reset of span %d completed.\n", span);
08374    return 0;
08375 }
08376 
08377 
08378 static void handle_gsm_event(struct zt_gsm *gsm, gsm_event *e)
08379 {
08380    struct ast_channel *c = NULL;
08381    int law = ZT_LAW_ALAW;
08382    int res = 0;
08383 
08384    switch(e->e) {
08385    case GSM_EVENT_DCHAN_UP:
08386       if (option_verbose > 2)
08387           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d registered to network!\n", gsm->span);
08388       gsm->available = 1;
08389       break;
08390    case GSM_EVENT_DCHAN_DOWN:
08391       if (option_verbose > 2)
08392           ast_verbose(VERBOSE_PREFIX_3 "GSM Span %d unregistered from network!\n", gsm->span);
08393       gsm->available = 0;
08394 /*    ast_mutex_lock(&gsm->pvt->lock);
08395       gsm->pvt->alreadyhungup = 1;
08396       if (gsm->pvt->owner) {
08397           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08398       }
08399       ast_mutex_unlock(&gsm->pvt->lock); */
08400       break;
08401    case GSM_EVENT_RING:
08402       ast_mutex_lock(&gsm->pvt->lock);
08403       if (!ast_strlen_zero(e->ring.callingnum)) {
08404           strncpy(gsm->pvt->cid_num, e->ring.callingnum, sizeof(gsm->pvt->cid_num) - 1);
08405       } else {
08406           strncpy(gsm->pvt->cid_name, withheldcid, sizeof(gsm->pvt->cid_name));
08407       }
08408       if (!ast_strlen_zero(gsm->exten)) {
08409           strncpy(gsm->pvt->exten, gsm->exten, sizeof(gsm->pvt->exten) - 1);
08410       } else {
08411           gsm->pvt->exten[0] = 's';
08412           gsm->pvt->exten[1] = '\0';
08413       }
08414       c = zt_new(gsm->pvt, AST_STATE_RING, 1, SUB_REAL, ZT_LAW_ALAW, AST_TRANS_CAP_SPEECH);
08415       if (c) {
08416           if (option_verbose > 2)
08417          ast_verbose(VERBOSE_PREFIX_3 "Ring on channel %d (from %s to %s)\n", e->ring.channel, e->ring.callingnum, gsm->exten);
08418           gsm->pvt->owner = c;
08419           if (ioctl(gsm->pvt->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
08420          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", gsm->pvt->channel, law);
08421           res = zt_setlaw(gsm->pvt->subs[SUB_REAL].zfd, law);
08422           res = set_actual_gain(gsm->pvt->subs[SUB_REAL].zfd, 0, gsm->pvt->rxgain, gsm->pvt->txgain, law);
08423           if (res < 0) {
08424               ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", gsm->pvt->channel);
08425 //        } else {
08426 //            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);
08427           }
08428       }
08429       ast_mutex_unlock(&gsm->pvt->lock);
08430       break;
08431    case GSM_EVENT_HANGUP:
08432       ast_verbose(VERBOSE_PREFIX_3 "Got hang up on channel %d\n", e->hangup.channel);
08433       ast_mutex_lock(&gsm->pvt->lock);
08434       gsm->pvt->alreadyhungup = 1;
08435       if (gsm->pvt->owner) {
08436           gsm->pvt->owner->hangupcause = e->hangup.cause;
08437           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08438       }
08439       ast_mutex_unlock(&gsm->pvt->lock);
08440       break;
08441    case GSM_EVENT_ERROR:
08442       ast_log(LOG_WARNING, "Got error on channel\n");
08443       ast_mutex_lock(&gsm->pvt->lock);
08444       gsm->pvt->alreadyhungup = 1;
08445       if (gsm->pvt->owner) {
08446           gsm->pvt->owner->hangupcause = e->error.cause;
08447           gsm->pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
08448       }
08449       ast_mutex_unlock(&gsm->pvt->lock);
08450       if (e->error.hard) {
08451 //        gsm_poweroff(gsm->modul);
08452           zt_reset_span(gsm->span, 8000);
08453 //        gsm_restart(gsm->modul, 10000);
08454       } else {
08455 //        gsm_poweroff(gsm->modul);
08456           zt_reset_span(gsm->span, 8000);
08457 //        gsm_restart(gsm->modul, 10000);
08458       }
08459       break;
08460    case GSM_EVENT_ALERTING:
08461       ast_mutex_lock(&gsm->pvt->lock);
08462       gsm->pvt->subs[SUB_REAL].needringing =1;
08463       ast_mutex_unlock(&gsm->pvt->lock);
08464       break;
08465    case GSM_EVENT_ANSWER:
08466       ast_mutex_lock(&gsm->pvt->lock);
08467       gsm->pvt->dialing = 0;
08468       gsm->pvt->subs[SUB_REAL].needanswer =1;
08469       gsm->pvt->ignoredtmf = 0;
08470       ast_mutex_unlock(&gsm->pvt->lock);
08471       break;
08472    case GSM_EVENT_PIN_REQUIRED:
08473       gsm_send_pin(gsm->modul, gsm->pin);
08474       break;
08475    case GSM_EVENT_SM_RECEIVED:
08476       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);
08477       manager_event(EVENT_FLAG_CALL, "Message received",
08478          "Span: %d\r\n"
08479          "Sender: %s\r\n"
08480          "SMSC: %s\r\n"
08481                "Length: %d\r\n"
08482          "Text: %s\r\n"
08483          "PDU: %s\r\n",
08484          gsm->span, 
08485          e->sm_received.sender,
08486          e->sm_received.smsc,
08487          e->sm_received.len,
08488          e->sm_received.text,
08489          e->sm_received.pdu);
08490       break;
08491    default:
08492       ast_log(LOG_WARNING,"!! Unknown GSM event %d !!\n", e->e);
08493    }
08494 }
08495 
08496 static void *gsm_dchannel(void *vgsm)
08497 {
08498    struct zt_gsm *gsm = vgsm;
08499    gsm_event *e;
08500    struct timeval tv = {0,0}, *next;
08501    fd_set rfds, efds;
08502    int res,x;
08503 
08504    if (!gsm) return NULL;
08505 
08506    if (!gsm->modul) {
08507       fprintf(stderr, "No gsm_mod\n");
08508       return NULL;
08509    }
08510    gsm_set_debug(gsm->modul, GSM_DEBUG_NONE);
08511    for (;;) {
08512       
08513       /* Run the D-Channel */
08514       FD_ZERO(&rfds);
08515       FD_ZERO(&efds);
08516       FD_SET(gsm->fd, &rfds);
08517       FD_SET(gsm->fd, &efds);
08518 
08519       if ((next = gsm_schedule_next(gsm->modul))) {
08520          gettimeofday(&tv, NULL);
08521          tv.tv_sec = next->tv_sec - tv.tv_sec;
08522          tv.tv_usec = next->tv_usec - tv.tv_usec;
08523          if (tv.tv_usec < 0) {
08524             tv.tv_usec += 1000000;
08525             tv.tv_sec -= 1;
08526          }
08527          if (tv.tv_sec < 0) {
08528             tv.tv_sec = 0;
08529             tv.tv_usec = 0;
08530          }
08531       }
08532       res = select(gsm->fd + 1, &rfds, NULL, &efds, next ? &tv : NULL);
08533       e = NULL;
08534 
08535       ast_mutex_lock(&gsm->lock);
08536       if (!res) {
08537          e = gsm_schedule_run(gsm->modul);
08538       } else if (res > 0) {
08539          e = gsm_check_event(gsm->modul, 1);
08540       } else if (errno == ELAST) {
08541          res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08542          printf("Got Zaptel event: %d\n", x);
08543       } else if (errno != EINTR) 
08544          fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno));
08545 
08546       if (!e) {
08547           e = gsm_check_event(gsm->modul, 0);
08548       }
08549 
08550       if (e) {
08551          handle_gsm_event(gsm, e);
08552       }
08553       ast_mutex_unlock(&gsm->lock);
08554 
08555       res = ioctl(gsm->fd, ZT_GETEVENT, &x);
08556 
08557       if (!res && x) {
08558          switch (x) {
08559              case ZT_EVENT_NOALARM:
08560             ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", gsm->span);
08561             usleep(1000);
08562             gsm_restart(gsm->modul, 10000);
08563              break;
08564              case ZT_EVENT_ALARM:
08565             ast_log(LOG_NOTICE, "Alarm detected on span %d\n", gsm->span);
08566              break;
08567              default:
08568             fprintf(stderr, "Got event on GSM interface: %d\n", x);
08569          }
08570       }
08571 
08572 
08573    }
08574    return NULL;
08575 }
08576 
08577 #endif
08578 
08579 #ifdef HAVE_PRI
08580 static struct zt_pvt *pri_find_crv(struct zt_pri *pri, int crv)
08581 {
08582    struct zt_pvt *p;
08583    p = pri->crvs;
08584    while (p) {
08585       if (p->channel == crv)
08586          return p;
08587       p = p->next;
08588    }
08589    return NULL;
08590 }
08591 
08592 static int pri_find_tei(struct zt_pri *pri, q931_call *c, int tei)
08593 {
08594    int x=0;
08595    for (x=0;x<pri->numchans;x++) {
08596       if (!pri->pvts[x]) continue;
08597       if ((pri->pvts[x]->tei == tei) && (pri->pvts[x]-> call != c)) {
08598           return x;
08599       }
08600    }
08601    return -1;
08602 }
08603 
08604 static struct zt_holded_call *pri_get_callonhold(struct zt_pri *pri, int cref, int tei) {
08605    struct zt_holded_call *zhc = pri->holded_calls;
08606    struct zt_holded_call *zhctemp = NULL;
08607 
08608    while (zhc) {
08609        if ((zhc->tei == tei) && ((zhc->cref == cref) || (cref == -1))) {
08610       return zhc;
08611        }       
08612        zhctemp = zhc;
08613        if (zhc) zhc = zhc->next;
08614    }
08615    return NULL;   
08616 }
08617 
08618 static int pri_destroy_callonhold(struct zt_pri *pri, struct zt_holded_call *onhold) {
08619    struct zt_holded_call *zhc = pri->holded_calls;
08620    struct zt_holded_call *zhctemp = NULL;
08621 
08622    while (zhc) {
08623        if (zhc == onhold) {
08624       if (zhctemp) {
08625           zhctemp->next = zhc->next;
08626           zhc = zhctemp;
08627       } else {
08628           pri->holded_calls = zhc->next;
08629           zhc = pri->holded_calls;
08630           zhctemp = NULL;
08631       }
08632        }       
08633        zhctemp = zhc;
08634        if (zhc) zhc = zhc->next;
08635    }
08636    if (onhold) {
08637        free(onhold);
08638        onhold = NULL;
08639        return 1;  
08640    }
08641    return 0;   
08642 }
08643 
08644 
08645 static int pri_find_principle(struct zt_pri *pri, int channel)
08646 {
08647    int x;
08648    int span = PRI_SPAN(channel);
08649    int spanfd;
08650    ZT_PARAMS param;
08651    int principle = -1;
08652    int explicit = PRI_EXPLICIT(channel);
08653    channel = PRI_CHANNEL(channel);
08654 
08655    if (!explicit) {
08656       spanfd = pri_active_dchan_fd(pri);
08657       if (ioctl(spanfd, ZT_GET_PARAMS, &param))
08658          return -1;
08659       span = pris[param.spanno - 1].prilogicalspan;
08660    }
08661 
08662    for (x = 0; x < pri->numchans; x++) {
08663       if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
08664          principle = x;
08665          break;
08666       }
08667    }
08668    
08669    return principle;
08670 }
08671 
08672 static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
08673 {
08674    int x;
08675    int res = 0;
08676    struct zt_pvt *crv;
08677    char tmpname[256];
08678    if (!c) {
08679       if (principle < 0)
08680          return -1;
08681       return principle;
08682    }
08683    if ((principle > -1) && 
08684       (principle < pri->numchans) && 
08685       (pri->pvts[principle]) && 
08686       (pri->pvts[principle]->call == c))
08687       return principle;
08688    /* First, check for other bearers */
08689    for (x = 0; x < pri->numchans; x++) {
08690       if (!pri->pvts[x])
08691          continue;
08692       if (pri->pvts[x]->call == c) {
08693          /* Found our call */
08694          if (principle != x) {
08695             if (option_verbose > 2)
08696                ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
08697                   pri->pvts[x]->channel, pri->pvts[principle]->channel);
08698             if (pri->pvts[principle]->owner) {
08699                ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
08700                   pri->pvts[x]->channel, pri->pvts[principle]->channel, pri->pvts[principle]->channel);
08701                return -1;
08702             }
08703             /* Fix it all up now */
08704             pri->pvts[principle]->owner = pri->pvts[x]->owner;
08705             pri->pvts[principle]->outgoing = pri->pvts[x]->outgoing;
08706             if (pri->pvts[principle]->owner) {
08707                ast_string_field_build(pri->pvts[principle]->owner, name, 
08708                             "Zap/%d:%d-%d", pri->trunkgroup,
08709                             pri->pvts[principle]->channel, 1);
08710                pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
08711                pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
08712                pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
08713             } else {
08714                ast_log(LOG_WARNING, "Whoa, there's no  owner, and we're having to fix up channel %d to channel %d\n", pri->pvts[x]->channel, pri->pvts[principle]->channel);
08715             }
08716             pri->pvts[principle]->call = pri->pvts[x]->call;
08717             pri->pvts[principle]->dsp = pri->pvts[x]->dsp;
08718             pri->pvts[principle]->alreadyhungup = pri->pvts[x]->alreadyhungup;
08719             pri->pvts[principle]->digital = pri->pvts[x]->digital;
08720             pri->pvts[principle]->faxhandled = pri->pvts[x]->faxhandled;
08721   
08722             if ((pri->nodetype == BRI_CPE_PTMP) || (pri->nodetype == BRI_CPE)) { 
08723                 /* this might also apply for other pri types! */
08724                 pri->pvts[principle]->law = pri->pvts[x]->law;
08725                 if (ioctl(pri->pvts[principle]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &pri->pvts[principle]->law) == -1)
08726                ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[principle]->channel, pri->pvts[principle]->law);
08727                 res = zt_setlaw(pri->pvts[principle]->subs[SUB_REAL].zfd, pri->pvts[principle]->law);
08728                 if (res < 0) 
08729                ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[principle]->channel);
08730                 if (!pri->pvts[principle]->digital) {
08731                res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, pri->pvts[principle]->rxgain, pri->pvts[principle]->txgain, pri->pvts[principle]->law);
08732                 } else {
08733                res = set_actual_gain(pri->pvts[principle]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[principle]->law);
08734                 }
08735                 if (res < 0) 
08736                ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[principle]->channel);
08737                 zt_confmute(pri->pvts[x], 0);
08738                 update_conf(pri->pvts[x]);
08739                 reset_conf(pri->pvts[x]);
08740                 restore_gains(pri->pvts[x]);
08741                 zt_disable_ec(pri->pvts[x]);
08742                 zt_setlinear(pri->pvts[x]->subs[SUB_REAL].zfd, 0);
08743             }
08744   
08745             if (pri->pvts[principle]->owner) {
08746                 snprintf(tmpname, sizeof(tmpname), "Zap/%d-1", pri->pvts[principle]->channel);
08747                 ast_change_name(pri->pvts[principle]->owner, tmpname);
08748             }
08749 
08750             /* Free up the old channel, now not in use */
08751             pri->pvts[x]->subs[SUB_REAL].owner = NULL;
08752             pri->pvts[x]->owner = NULL;
08753             pri->pvts[x]->call = NULL;
08754             pri->pvts[x]->dsp = NULL;
08755          }
08756          return principle;
08757       }
08758    }
08759    /* Now check for a CRV with no bearer */
08760    crv = pri->crvs;
08761    while (crv) {
08762       if (crv->call == c) {
08763          /* This is our match...  Perform some basic checks */
08764          if (crv->bearer)
08765             ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
08766          else if (pri->pvts[principle]->owner) 
08767             ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
08768          else {
08769             /* Looks good.  Drop the pseudo channel now, clear up the assignment, and
08770                wakeup the potential sleeper */
08771             zt_close(crv->subs[SUB_REAL].zfd);
08772             pri->pvts[principle]->call = crv->call;
08773             pri_assign_bearer(crv, pri, pri->pvts[principle]);
08774             ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
08775                            pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
08776                            pri->trunkgroup, crv->channel);
08777             wakeup_sub(crv, SUB_REAL, pri);
08778          }
08779          return principle;
08780       }
08781       crv = crv->next;
08782    }
08783    if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
08784        ast_log(LOG_WARNING, "Call specified, but not found?\n");
08785    }
08786    return -1;
08787 }
08788 
08789 static void *do_idle_thread(void *vchan)
08790 {
08791    struct ast_channel *chan = vchan;
08792    struct zt_pvt *pvt = chan->tech_pvt;
08793    struct ast_frame *f;
08794    char ex[80];
08795    /* Wait up to 30 seconds for an answer */
08796    int newms, ms = 30000;
08797    if (option_verbose > 2) 
08798       ast_verbose(VERBOSE_PREFIX_3 "Initiating idle call on channel %s\n", chan->name);
08799    snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
08800    if (ast_call(chan, ex, 0)) {
08801       ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
08802       ast_hangup(chan);
08803       return NULL;
08804    }
08805    while ((newms = ast_waitfor(chan, ms)) > 0) {
08806       f = ast_read(chan);
08807       if (!f) {
08808          /* Got hangup */
08809          break;
08810       }
08811       if (f->frametype == AST_FRAME_CONTROL) {
08812          switch (f->subclass) {
08813          case AST_CONTROL_ANSWER:
08814             /* Launch the PBX */
08815             ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
08816             ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
08817             chan->priority = 1;
08818             if (option_verbose > 3) 
08819                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
08820             ast_pbx_run(chan);
08821             /* It's already hungup, return immediately */
08822             return NULL;
08823          case AST_CONTROL_BUSY:
08824             if (option_verbose > 3) 
08825                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' busy, waiting...\n", chan->name);
08826             break;
08827          case AST_CONTROL_CONGESTION:
08828             if (option_verbose > 3) 
08829                ast_verbose(VERBOSE_PREFIX_3 "Idle channel '%s' congested, waiting...\n", chan->name);
08830             break;
08831          };
08832       }
08833       ast_frfree(f);
08834       ms = newms;
08835    }
08836    /* Hangup the channel since nothing happend */
08837    ast_hangup(chan);
08838    return NULL;
08839 }
08840 
08841 #ifndef PRI_RESTART
08842 #error "Upgrade your libpri"
08843 #endif
08844 static void zt_pri_message(char *s, int span)
08845 {
08846    ast_verbose("%d %s", span, s);
08847 }
08848 
08849 static void zt_pri_error(char *s, int span)
08850 {
08851    ast_log(LOG_WARNING, "%d %s", span, s);
08852 }
08853 
08854 #ifdef HAVE_GSMAT
08855 static void zt_gsm_message(char *s, int channel)
08856 {
08857    ast_verbose("GSM %d: %s", channel, s);
08858 }
08859 
08860 static void zt_gsm_error(char *s, int channel)
08861 {
08862    ast_log(LOG_WARNING, "GSM %d: %s", channel, s);
08863 }
08864 #endif
08865 
08866 static int pri_check_restart(struct zt_pri *pri)
08867 {
08868    if ((pri->nodetype != PRI_NETWORK) && (pri->nodetype != PRI_CPE)) {
08869        return 0;
08870    }
08871    do {
08872       pri->resetpos++;
08873    } while ((pri->resetpos < pri->numchans) &&
08874        (!pri->pvts[pri->resetpos] ||
08875         pri->pvts[pri->resetpos]->call ||
08876         pri->pvts[pri->resetpos]->resetting));
08877    if (pri->resetpos < pri->numchans) {
08878       /* Mark the channel as resetting and restart it */
08879       pri->pvts[pri->resetpos]->resetting = 1;
08880       pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
08881    } else {
08882       pri->resetting = 0;
08883       time(&pri->lastreset);
08884    }
08885    return 0;
08886 }
08887 
08888 static int pri_hangup_all(struct zt_pvt *p, struct zt_pri *pri)
08889 {
08890    int x;
08891    int redo;
08892    ast_mutex_unlock(&pri->lock);
08893    ast_mutex_lock(&p->lock);
08894    do {
08895       redo = 0;
08896       for (x = 0; x < 3; x++) {
08897          while (p->subs[x].owner && ast_mutex_trylock(&p->subs[x].owner->lock)) {
08898             redo++;
08899             ast_mutex_unlock(&p->lock);
08900             usleep(1);
08901             ast_mutex_lock(&p->lock);
08902          }
08903          if (p->subs[x].owner) {
08904             ast_queue_hangup(p->subs[x].owner);
08905             ast_mutex_unlock(&p->subs[x].owner->lock);
08906          }
08907       }
08908    } while (redo);
08909    ast_mutex_unlock(&p->lock);
08910    ast_mutex_lock(&pri->lock);
08911    return 0;
08912 }
08913 
08914 static char * redirectingreason2str(int redirectingreason)
08915 {
08916    switch (redirectingreason) {
08917    case 0:
08918       return "UNKNOWN";
08919    case 1:
08920       return "BUSY";
08921    case 2:
08922       return "NO_REPLY";
08923    case 0xF:
08924       return "UNCONDITIONAL";
08925    default:
08926       return "NOREDIRECT";
08927    }
08928 }
08929 
08930 static void apply_plan_to_number(char *buf, size_t size, const struct zt_pri *pri, const char *number, const int plan)
08931 {
08932    switch (plan) {
08933    case PRI_INTERNATIONAL_ISDN:     /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
08934       snprintf(buf, size, "%s%s", pri->internationalprefix, number);
08935       break;
08936    case PRI_NATIONAL_ISDN:       /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
08937       snprintf(buf, size, "%s%s", pri->nationalprefix, number);
08938       break;
08939    case PRI_LOCAL_ISDN:       /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
08940       snprintf(buf, size, "%s%s", pri->localprefix, number);
08941       break;
08942    case PRI_PRIVATE:       /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
08943       snprintf(buf, size, "%s%s", pri->privateprefix, number);
08944       break;
08945    case PRI_UNKNOWN:       /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
08946       snprintf(buf, size, "%s%s", pri->unknownprefix, number);
08947       break;
08948    default:          /* other Q.931 dialplan => don't twiddle with callingnum */
08949       snprintf(buf, size, "%s", number);
08950       break;
08951    }
08952 }
08953 
08954 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) {
08955     if (callingnum && (callingnum_len > stripmsd)) {
08956    callingnum += stripmsd;
08957     }
08958     switch (callingplan) {
08959    case PRI_INTERNATIONAL_ISDN:
08960        snprintf(callerid, callerid_len, "%s%s", pri->internationalprefix, callingnum);
08961        break;
08962    case PRI_NATIONAL_ISDN:
08963        snprintf(callerid, callerid_len, "%s%s", pri->nationalprefix, callingnum);
08964        break;
08965    case PRI_LOCAL_ISDN:
08966        snprintf(callerid, callerid_len, "%s%s", pri->localprefix, callingnum);
08967        break;
08968    case PRI_PRIVATE:
08969        snprintf(callerid, callerid_len, "%s%s", pri->privateprefix, callingnum);
08970        break;
08971    case PRI_UNKNOWN:
08972        snprintf(callerid, callerid_len, "%s%s", pri->unknownprefix, callingnum);
08973        break;
08974    default:
08975        snprintf(callerid, callerid_len, "%s", callingnum);
08976        break;
08977     }
08978 }
08979 
08980 static void *pri_dchannel(void *vpri)
08981 {
08982    struct zt_pri *pri = vpri;
08983    pri_event *e;
08984    struct pollfd fds[NUM_DCHANS];
08985    int res;
08986    int chanpos = 0;
08987    int x;
08988    int haveidles;
08989    int activeidles;
08990    int nextidle = -1;
08991    struct ast_channel *c;
08992    struct timeval tv, lowest, *next;
08993    struct timeval lastidle = { 0, 0 };
08994    int doidling=0;
08995    char *cc;
08996    char idlen[80];
08997    struct ast_channel *idle;
08998    pthread_t p;
08999    time_t t;
09000    int i, which=-1;
09001    int numdchans;
09002    int cause=0;
09003    struct zt_pvt *crv;
09004    pthread_t threadid;
09005    pthread_attr_t attr;
09006    char ani2str[6];
09007    char plancallingnum[256];
09008    char plancallingani[256];
09009    char calledtonstr[10];
09010    
09011    gettimeofday(&lastidle, NULL);
09012    if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
09013       /* Need to do idle dialing, check to be sure though */
09014       cc = strchr(pri->idleext, '@');
09015       if (cc) {
09016          *cc = '\0';
09017          cc++;
09018          ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
09019 #if 0
09020          /* Extensions may not be loaded yet */
09021          if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
09022             ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
09023          else
09024 #endif
09025             doidling = 1;
09026       } else
09027          ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
09028    }
09029    for (;;) {
09030       for (i = 0; i < NUM_DCHANS; i++) {
09031          if (!pri->dchannels[i])
09032             break;
09033          fds[i].fd = pri->fds[i];
09034          fds[i].events = POLLIN | POLLPRI;
09035          fds[i].revents = 0;
09036       }
09037       numdchans = i;
09038       time(&t);
09039       ast_mutex_lock(&pri->lock);
09040       if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->resetinterval > 0)) {
09041          if (pri->resetting && pri_is_up(pri)) {
09042             if (pri->resetpos < 0)
09043                pri_check_restart(pri);
09044          } else {
09045             if (!pri->resetting  && (t - pri->lastreset) >= pri->resetinterval) {
09046                pri->resetting = 1;
09047                pri->resetpos = -1;
09048             }
09049          }
09050       }
09051       /* Look for any idle channels if appropriate */
09052       if (doidling && pri_is_up(pri)) {
09053          nextidle = -1;
09054          haveidles = 0;
09055          activeidles = 0;
09056          for (x = pri->numchans; x >= 0; x--) {
09057             if (pri->pvts[x] && !pri->pvts[x]->owner && 
09058                 !pri->pvts[x]->call) {
09059                if (haveidles < pri->minunused) {
09060                   haveidles++;
09061                } else if (!pri->pvts[x]->resetting) {
09062                   nextidle = x;
09063                   break;
09064                }
09065             } else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
09066                activeidles++;
09067          }
09068          if (nextidle > -1) {
09069             if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
09070                /* Don't create a new idle call more than once per second */
09071                snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
09072                idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
09073                if (idle) {
09074                   pri->pvts[nextidle]->isidlecall = 1;
09075                   if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
09076                      ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
09077                      zt_hangup(idle);
09078                   }
09079                } else
09080                   ast_log(LOG_WARNING, "Unable to request channel 'Zap/%s' for idle call\n", idlen);
09081                gettimeofday(&lastidle, NULL);
09082             }
09083          } else if ((haveidles < pri->minunused) &&
09084                (activeidles > pri->minidle)) {
09085             /* Mark something for hangup if there is something 
09086                that can be hungup */
09087             for (x = pri->numchans; x >= 0; x--) {
09088                /* find a candidate channel */
09089                if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
09090                   pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09091                   haveidles++;
09092                   /* Stop if we have enough idle channels or
09093                     can't spare any more active idle ones */
09094                   if ((haveidles >= pri->minunused) ||
09095                       (activeidles <= pri->minidle))
09096                      break;
09097                } 
09098             }
09099          }
09100       }
09101       /* Start with reasonable max */
09102       lowest = ast_tv(60, 0);
09103       for (i = 0; i < NUM_DCHANS; i++) {
09104          /* Find lowest available d-channel */
09105          if (!pri->dchannels[i])
09106             break;
09107          if ((next = pri_schedule_next(pri->dchans[i]))) {
09108             /* We need relative time here */
09109             tv = ast_tvsub(*next, ast_tvnow());
09110             if (tv.tv_sec < 0) {
09111                tv = ast_tv(0,0);
09112             }
09113             if (doidling || pri->resetting) {
09114                if (tv.tv_sec > 1) {
09115                   tv = ast_tv(1, 0);
09116                }
09117             } else {
09118                if (tv.tv_sec > 60) {
09119                   tv = ast_tv(60, 0);
09120                }
09121             }
09122          } else if (doidling || pri->resetting) {
09123             /* Make sure we stop at least once per second if we're
09124                monitoring idle channels */
09125             tv = ast_tv(1,0);
09126          } else {
09127             /* Don't poll for more than 60 seconds */
09128             tv = ast_tv(60, 0);
09129          }
09130          if (!i || ast_tvcmp(tv, lowest) < 0) {
09131             lowest = tv;
09132          }
09133       }
09134       ast_mutex_unlock(&pri->lock);
09135 
09136       e = NULL;
09137       res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
09138 
09139       ast_mutex_lock(&pri->lock);
09140       if (!res) {
09141          for (which = 0; which < NUM_DCHANS; which++) {
09142             if (!pri->dchans[which])
09143                break;
09144             /* Just a timeout, run the scheduler */
09145             e = pri_schedule_run(pri->dchans[which]);
09146             if (e)
09147                break;
09148          }
09149       } else if (res > -1) {
09150          for (which = 0; which < NUM_DCHANS; which++) {
09151             if (!pri->dchans[which])
09152                break;
09153             if (fds[which].revents & POLLPRI) {
09154                /* Check for an event */
09155                x = 0;
09156                res = ioctl(pri->fds[which], ZT_GETEVENT, &x);
09157                if ((pri->nodetype != BRI_CPE) && (pri->nodetype != BRI_CPE_PTMP)) {
09158                    /* dont annoy BRI TE mode users with layer2layer alarms */
09159                    if (x)
09160                   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);
09161                }
09162                /* Keep track of alarm state */  
09163                if (x == ZT_EVENT_ALARM) {
09164                   pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
09165                   pri_find_dchan(pri);
09166                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09167                       if (pri->pri) {
09168                      for (i=0; i<pri->numchans; i++) {
09169                          struct zt_pvt *p = pri->pvts[i];
09170                          if (p) {
09171                         if (p->call) {
09172                             if (p->pri && p->pri->pri) {
09173                               pri_destroycall(p->pri->pri, p->call);
09174                            p->call = NULL;
09175                            p->tei = -1;
09176                             } else
09177                            ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09178                         }
09179                         if (p->owner)
09180                             p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09181                         p->inalarm = 1;
09182                          }
09183                      }
09184                      pri_shutdown(pri->pri);
09185                       }
09186                   }
09187                } else if (x == ZT_EVENT_NOALARM) {
09188                   if ((pri->nodetype == BRI_CPE) || (pri->nodetype == BRI_CPE_PTMP)) {
09189                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09190                   //    pri->dchanavail[which] |= DCHAN_UP;
09191                   } else {
09192                       pri->dchanavail[which] |= DCHAN_NOTINALARM;
09193                       pri_restart(pri->dchans[which]);
09194                   }
09195                }
09196             
09197                if (option_debug)
09198                   ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
09199             } else if (fds[which].revents & POLLIN) {
09200                e = pri_check_event(pri->dchans[which]);
09201             }
09202             if (e)
09203                break;
09204          }
09205       } else if (errno != EINTR)
09206          ast_log(LOG_WARNING, "pri_event returned error %d (%s) on span %d\n", errno, strerror(errno), pri->span);
09207       if (e) {
09208          if (pri->debug)
09209             pri_dump_event(pri->dchans[which], e);
09210          if (e->e != PRI_EVENT_DCHAN_DOWN)
09211             pri->dchanavail[which] |= DCHAN_UP;
09212 
09213          if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
09214             /* Must be an NFAS group that has the secondary dchan active */
09215             pri->pri = pri->dchans[which];
09216 
09217          switch (e->e) {
09218          case PRI_EVENT_DCHAN_UP:
09219             if (pri->nodetype == BRI_NETWORK_PTMP) {
09220                 if (option_verbose > 3) 
09221                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09222                 pri->dchanavail[which] |= DCHAN_UP;
09223                 if (!pri->pri) pri_find_dchan(pri);
09224   
09225                 /* Note presense of D-channel */
09226                 time(&pri->lastreset);
09227   
09228                 pri->resetting = 0;
09229                 /* Take the channels from inalarm condition */
09230                 for (i=0; i<pri->numchans; i++)
09231                if (pri->pvts[i]) {
09232                   pri->pvts[i]->inalarm = 0;
09233                }
09234             } else {
09235                 if (pri->nodetype == BRI_CPE_PTMP) {
09236                if (option_verbose > 3) 
09237                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09238                 } else {
09239                if (option_verbose > 1) 
09240                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d up\n", pri_order(which), pri->span);
09241                 }
09242                 pri->dchanavail[which] |= DCHAN_UP;
09243                 if (!pri->pri) pri_find_dchan(pri);
09244 
09245                 /* Note presense of D-channel */
09246                 time(&pri->lastreset);
09247 
09248                 /* Restart in 5 seconds */
09249                 if (pri->resetinterval > -1) {
09250                pri->lastreset -= pri->resetinterval;
09251                pri->lastreset += 5;
09252                 }
09253                 pri->resetting = 0;
09254                 /* Take the channels from inalarm condition */
09255                 for (i = 0; i < pri->numchans; i++)
09256                if (pri->pvts[i]) {
09257                   pri->pvts[i]->inalarm = 0;
09258                }
09259             }
09260             break;
09261          case PRI_EVENT_DCHAN_DOWN:
09262             if (pri->nodetype == BRI_NETWORK_PTMP) {
09263                 if (option_verbose > 3) 
09264                ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down for TEI %d\n", pri_order(which), pri->span, e->gen.tei);
09265                 // PTMP BRIs have N dchans, handled by libpri
09266                 if (e->gen.tei == 0) break;
09267                 /* Hangup active channels */
09268                 for (i=0; i<pri->numchans; i++) {
09269                   struct zt_pvt *p = pri->pvts[i];
09270                if (p) {
09271          //    ast_log(LOG_NOTICE, "chan %d tei %d\n",i,p->tei);
09272                    if (p->tei == e->gen.tei) {
09273                   if (p->call) {
09274                      if (p->pri && p->pri->pri) {
09275                         pri_hangup(p->pri->pri, p->call, -1, -1);
09276                         pri_destroycall(p->pri->pri, p->call);
09277                         p->call = NULL;
09278                      } else
09279                         ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09280                   }
09281                   if (p->owner)
09282                       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09283                   p->inalarm = 1;
09284                   p->tei = -1;
09285                    }
09286                }
09287                 } 
09288             } else {
09289                 if (pri->nodetype == BRI_CPE_PTMP) {
09290                if (option_verbose > 3) 
09291                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
09292                 } else {
09293                if (option_verbose > 1) 
09294                    ast_verbose(VERBOSE_PREFIX_2 "%s D-Channel on span %d down\n", pri_order(which), pri->span);
09295                 }
09296                 pri->dchanavail[which] &= ~DCHAN_UP;
09297                 pri_find_dchan(pri);
09298                 if (!pri_is_up(pri)) {
09299                pri->resetting = 0;
09300                /* Hangup active channels and put them in alarm mode */
09301                for (i = 0; i < pri->numchans; i++) {
09302                   struct zt_pvt *p = pri->pvts[i];
09303                   if (p) {
09304                      if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
09305                         /* T309 is not enabled : hangup calls when alarm occurs */
09306                         if (p->call) {
09307                            if (p->pri && p->pri->pri) {
09308                               pri_hangup(p->pri->pri, p->call, -1, -1);
09309                               pri_destroycall(p->pri->pri, p->call);
09310                               p->call = NULL;
09311                            } else
09312                               ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
09313                         }
09314                         p->tei = -1;
09315                         if (p->realcall) {
09316                            pri_hangup_all(p->realcall, pri);
09317                         } else if (p->owner)
09318                            p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09319                      }
09320                      p->inalarm = 1;
09321                   }
09322                }
09323                 }
09324             }
09325             break;
09326          case PRI_EVENT_RESTART:
09327             if (e->restart.channel > -1) {
09328                chanpos = pri_find_principle(pri, e->restart.channel);
09329                if (chanpos < 0)
09330                   ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n", 
09331                      PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09332                else {
09333                   if (option_verbose > 2)
09334                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d restarted on span %d\n", 
09335                         PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
09336                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09337                   if (pri->pvts[chanpos]->call) {
09338                      pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
09339                      pri->pvts[chanpos]->call = NULL;
09340                   }
09341                   /* Force soft hangup if appropriate */
09342                   if (pri->pvts[chanpos]->realcall) 
09343                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09344                   else if (pri->pvts[chanpos]->owner)
09345                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09346                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09347                }
09348             } else {
09349                if (option_verbose > 2)
09350                   ast_verbose(VERBOSE_PREFIX_2 "Restart on requested on entire span %d\n", pri->span);
09351                for (x = 0; x < pri->numchans; x++)
09352                   if (pri->pvts[x]) {
09353                      ast_mutex_lock(&pri->pvts[x]->lock);
09354                      if (pri->pvts[x]->call) {
09355                         pri_destroycall(pri->pri, pri->pvts[x]->call);
09356                         pri->pvts[x]->call = NULL;
09357                      }
09358                      if (pri->pvts[x]->realcall) 
09359                         pri_hangup_all(pri->pvts[x]->realcall, pri);
09360                      else if (pri->pvts[x]->owner)
09361                         pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09362                      ast_mutex_unlock(&pri->pvts[x]->lock);
09363                   }
09364             }
09365             break;
09366          case PRI_EVENT_KEYPAD_DIGIT:
09367             chanpos = pri_find_principle(pri, e->digit.channel);
09368             if (chanpos < 0) {
09369                ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n", 
09370                   PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
09371             } else {
09372                chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
09373                if (chanpos > -1) {
09374                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09375                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
09376                   if (pri->overlapdial && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
09377                      /* how to do that */
09378                      int digitlen = strlen(e->digit.digits);
09379                      char digit;
09380                      int i;               
09381                      for (i = 0; i < digitlen; i++) { 
09382                         digit = e->digit.digits[i];
09383                         {
09384                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09385                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09386                         }
09387                      }
09388                   }
09389                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09390                }
09391             }
09392             break;
09393          case PRI_EVENT_INFO_RECEIVED:
09394             chanpos = pri_find_principle(pri, e->ring.channel);
09395             if (chanpos < 0) {
09396                ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n", 
09397                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09398             } else {
09399                chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
09400                if (chanpos > -1) {
09401 //             ast_log(LOG_NOTICE, "INFO received on  channel %d/%d span %d\n", 
09402 //                PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09403                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09404                   /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
09405                   if (pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
09406                      /* how to do that */
09407                      int digitlen = strlen(e->ring.callednum);
09408                      char digit;
09409                      int i;               
09410                      for (i = 0; i < digitlen; i++) { 
09411                         digit = e->ring.callednum[i];
09412                         {
09413                            struct ast_frame f = { AST_FRAME_DTMF, digit, };
09414                            zap_queue_frame(pri->pvts[chanpos], &f, pri);
09415                         }
09416                      }
09417                      if (!pri->overlapdial) {
09418                          strncat(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
09419                          if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09420                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09421                          } else {
09422                         tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09423                          }
09424                      } 
09425                   }
09426                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09427                }
09428             }
09429             break;
09430          case PRI_EVENT_RING:
09431             crv = NULL;
09432             if (e->ring.channel == -1) {
09433                /* if no channel specified find one empty */
09434                chanpos = pri_find_empty_chan(pri, 1);
09435             } else {
09436                chanpos = pri_find_principle(pri, e->ring.channel);
09437             }
09438             /* if no channel specified find one empty */
09439             if (chanpos < 0) {
09440                /* no channel specified and no free channel. this is a callwating SETUP */
09441                if (e->ring.channel <= 0) {
09442                    if (option_verbose > 2)
09443                   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);
09444                    pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_USER_BUSY, -1);
09445                    break;
09446                }
09447             } else {
09448                /* ok, we got a b channel for this call, lock it */
09449                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09450                if (pri->pvts[chanpos]->owner) {
09451                    /* safety check, for messed up retransmissions? */
09452                    if (pri->pvts[chanpos]->call == e->ring.call) {
09453                   ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n", 
09454                         PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09455                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09456                   chanpos = -1;
09457                   break;
09458                    } else {
09459                   ast_log(LOG_WARNING, "Ring requested on channel %d/%d already in use on span %d. Hanging up owner.\n", 
09460                   PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
09461                   if (pri->pvts[chanpos]->realcall) {
09462                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
09463                   } else {
09464                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09465                      /* XXX destroy the call here, so we can accept the retransmission as a new call */
09466                      pri_destroycall(pri->pri, e->ring.call);
09467                   }
09468                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09469                   chanpos = -1;
09470                   break;
09471                    }
09472                }
09473                if (chanpos > -1) {
09474                   /* everything is ok with the b channel */
09475                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09476                }
09477             }
09478             /* actually, we already got a valid channel by now */
09479             if (chanpos > -1) {
09480                ast_mutex_lock(&pri->pvts[chanpos]->lock);
09481                /* dont detect dtmfs before the signalling is done */
09482                disable_dtmf_detect(pri->pvts[chanpos]);
09483                /* this channel is owned by this TEI */
09484                pri->pvts[chanpos]->tei = e->ring.tei;
09485                if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
09486                   /* Should be safe to lock CRV AFAIK while bearer is still locked */
09487                   crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
09488                   if (crv)
09489                      ast_mutex_lock(&crv->lock);
09490                   if (!crv || crv->owner) {
09491                      pri->pvts[chanpos]->call = NULL;
09492                      if (crv) {
09493                         if (crv->owner)
09494                            crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09495                         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);
09496                      } else
09497                         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);
09498                      pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE, -1);
09499                      if (crv)
09500                         ast_mutex_unlock(&crv->lock);
09501                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09502                      break;
09503                   }
09504                }
09505                /* assign call to b channel */
09506                pri->pvts[chanpos]->call = e->ring.call;
09507                apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
09508                if (pri->pvts[chanpos]->use_callerid) {
09509                   ast_shrink_phone_number(plancallingnum);
09510                   ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
09511 #ifdef PRI_ANI
09512                   if (!ast_strlen_zero(e->ring.callingani)) {
09513                      apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
09514                      ast_shrink_phone_number(plancallingani);
09515                      ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
09516                   } else {
09517                      pri->pvts[chanpos]->cid_ani[0] = '\0';
09518                   }
09519 #endif
09520                   ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
09521                   pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
09522                } else {
09523                   pri->pvts[chanpos]->cid_num[0] = '\0';
09524                   pri->pvts[chanpos]->cid_ani[0] = '\0';
09525                   pri->pvts[chanpos]->cid_name[0] = '\0';
09526                   pri->pvts[chanpos]->cid_ton = 0;
09527                }
09528                apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
09529                           e->ring.redirectingnum, e->ring.callingplanrdnis);
09530                /* get callingpres */
09531                pri->pvts[chanpos]->cid_pres = e->ring.callingpres;
09532                switch (e->ring.callingpres) {
09533                    case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
09534                    case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
09535                    case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
09536                    case PRES_PROHIB_NETWORK_NUMBER:
09537                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->withheldcid, sizeof(pri->pvts[chanpos]->cid_name));
09538                   break;
09539                    case PRES_NUMBER_NOT_AVAILABLE:
09540                   ast_copy_string(pri->pvts[chanpos]->cid_name, pri->nocid, sizeof(pri->pvts[chanpos]->cid_name));
09541                   break;
09542                }
09543                /* If immediate=yes go to s|1 */
09544                if (pri->pvts[chanpos]->immediate) {
09545                   if (option_verbose > 2)
09546                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of immediate=yes\n");
09547                   pri->pvts[chanpos]->exten[0] = 's';
09548                   pri->pvts[chanpos]->exten[1] = '\0';
09549                } else if (ast_strlen_zero(e->ring.callednum)) {
09550                    /* called party number is empty */
09551                    if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09552                   if (!pri->overlapdial) {
09553                       // be able to set digittimeout for BRI phones
09554                       pri->pvts[chanpos]->exten[0] = 's';
09555                       pri->pvts[chanpos]->exten[1] = '\0';
09556                       tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09557                   } else {
09558                       pri->pvts[chanpos]->exten[0] = '\0';
09559                   }
09560                    } else {
09561                   if (pri->nodetype == BRI_CPE) { 
09562                       /* fix for .at p2p bri lines */
09563                       pri->pvts[chanpos]->exten[0] = 's';
09564                       pri->pvts[chanpos]->exten[1] = '\0';
09565                   } else if (pri->overlapdial) {
09566                       pri->pvts[chanpos]->exten[0] = '\0';
09567                   } else {
09568                       /* Some PRI circuits are set up to send _no_ digits.  Handle them as 's'. */
09569                       pri->pvts[chanpos]->exten[0] = 's';
09570                       pri->pvts[chanpos]->exten[1] = '\0';
09571                   }
09572                    }
09573                    /* No number yet, but received "sending complete"? */
09574                       if (e->ring.complete) {
09575                   if (option_verbose > 2)
09576                      ast_verbose(VERBOSE_PREFIX_3 "Going to extension s|1 because of Complete received\n");
09577                   pri->pvts[chanpos]->exten[0] = 's';
09578                   pri->pvts[chanpos]->exten[1] = '\0';
09579                    }
09580                } else {
09581                   /* Get called number */
09582                   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);
09583                   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);
09584                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
09585                       /* if we get the next digit we should stop the dialtone */
09586                       if (!pri->overlapdial) {
09587                      // with overlapdial=no the exten is always prefixed by "s"
09588                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten + 1)) {
09589                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09590                      } else {
09591                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09592                      }
09593                       } else {
09594                      if (!ast_ignore_pattern(pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten)) {
09595                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, -1);
09596                      } else {
09597                          tone_zone_play_tone(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
09598                      }
09599                       }
09600                   }
09601                }
09602                /* Part 3: create channel, setup audio... */
09603                /* Set DNID on all incoming calls -- even immediate */
09604                if (!ast_strlen_zero(e->ring.callednum))
09605                   strncpy(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid) - 1);
09606                /* Make sure extension exists (or in overlap dial mode, can exist) */
09607                if ((pri->overlapdial && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
09608                   ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09609                   /* Setup law */
09610                   int law;
09611                   if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
09612                      /* Set to audio mode at this point */
09613                      law = 1;
09614                      if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
09615                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law);
09616                   }
09617                   if (e->ring.layer1 == PRI_LAYER_1_ALAW)
09618                      law = ZT_LAW_ALAW;
09619                   else
09620                      law = ZT_LAW_MULAW;
09621                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
09622                   if (res < 0) 
09623                      ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
09624                   if (IS_DIGITAL(e->ring.ctype)) {
09625                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
09626                   } else {
09627                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
09628                   }
09629                   if (res < 0)
09630                      ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
09631                   if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09632                       if (e->ring.complete || !pri->overlapdial) {
09633                      /* Just announce proceeding */
09634                      pri->pvts[chanpos]->proceeding = 1;
09635                      pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09636                       } else {
09637                      if (pri->switchtype != PRI_SWITCH_GR303_TMC) 
09638                         pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09639                      else
09640                         pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09641                       }
09642                   } else {
09643                      /* BRI_NETWORK | BRI_NETWORK_PTMP */
09644                      if (pri->overlapdial || (!strcasecmp(pri->pvts[chanpos]->exten, "s"))) {
09645                          /* send a SETUP_ACKNOWLEDGE */
09646                          pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09647                      } else {
09648                          /* send an ALERTING ??? wtf */
09649                      //    pri_acknowledge(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
09650                          pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
09651                      }
09652                   }
09653                   /* overlapdial = yes  and the extension can be valid */
09654                   /* Get the use_callingpres state */
09655                   pri->pvts[chanpos]->callingpres = e->ring.callingpres;
09656                
09657                   /* Start PBX */
09658                   if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
09659                      /* Release the PRI lock while we create the channel */
09660                      ast_mutex_unlock(&pri->lock);
09661                      if (crv) {
09662                         /* Set bearer and such */
09663                         pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
09664                         c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09665                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09666                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09667                         }
09668                         pri->pvts[chanpos]->owner = &inuse;
09669                         ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
09670                      } else {
09671                         c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
09672                         if (c && (e->ring.lowlayercompat[0] > 0)) {
09673                             memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09674                         }
09675                         zt_enable_ec(pri->pvts[chanpos]);  /* XXX rethink */
09676                      }
09677 
09678                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09679 
09680                      if (!ast_strlen_zero(e->ring.callingsubaddr)) {
09681                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09682                      }
09683                         if (!ast_strlen_zero(e->ring.callingnum)) {
09684                          char tmpstr[256];
09685                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09686                          pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09687                      }
09688                      if (!ast_strlen_zero(e->ring.callingani)) {
09689                          char tmpstr[256];
09690                          pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09691                          pbx_builtin_setvar_helper(c, "PRI_USER_CID", tmpstr);
09692                      }
09693                      if (e->ring.ani2 >= 0) {
09694                         snprintf(ani2str, 5, "%.2d", e->ring.ani2);
09695                         pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09696                      }
09697 
09698 #ifdef SUPPORT_USERUSER
09699                      if (!ast_strlen_zero(e->ring.useruserinfo)) {
09700                         pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09701                      }
09702 #endif
09703 
09704                      snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09705                      pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09706                      if (e->ring.redirectingreason >= 0)
09707                         pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09708                   
09709                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09710                      ast_mutex_lock(&pri->lock);
09711 
09712                      pthread_attr_init(&attr);
09713                      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09714                      if (c && !ast_pthread_create(&threadid, &attr, ss_thread, c)) {
09715                         if (option_verbose > 2)
09716                            ast_verbose(VERBOSE_PREFIX_3 "Accepting overlap %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09717                               pri->pvts[chanpos]->digital ? "data" : "voice", plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
09718                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09719                      } else {
09720                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09721                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09722                         if (c)
09723                            ast_hangup(c);
09724                         else {
09725                            pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09726                            pri->pvts[chanpos]->call = NULL;
09727                         }
09728                      }
09729                      pthread_attr_destroy(&attr);
09730                   } else  {
09731                      /* overlapdial = no */    
09732                      ast_mutex_unlock(&pri->lock);
09733                      /* Release PRI lock while we create the channel */
09734                      c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype);
09735                      if (c && (e->ring.lowlayercompat[0] > 0)) {
09736                          memcpy(c->lowlayercompat, e->ring.lowlayercompat, sizeof(c->lowlayercompat));
09737                      }
09738                      if (c) {
09739                         char calledtonstr[10];
09740 
09741                         ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09742 
09743                         if (e->ring.ani2 >= 0) {
09744                            snprintf(ani2str, 5, "%d", e->ring.ani2);
09745                            pbx_builtin_setvar_helper(c, "ANI2", ani2str);
09746                         }
09747 
09748 #ifdef SUPPORT_USERUSER
09749                         if (!ast_strlen_zero(e->ring.useruserinfo)) {
09750                            pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
09751                         }
09752 #endif
09753 
09754                         if (e->ring.redirectingreason >= 0)
09755                            pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
09756                      
09757                         snprintf(calledtonstr, sizeof(calledtonstr)-1, "%d", e->ring.calledplan);
09758                         pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
09759 
09760                         ast_mutex_lock(&pri->pvts[chanpos]->lock);
09761                         ast_mutex_lock(&pri->lock);
09762 
09763                         if (option_verbose > 2)
09764                            ast_verbose(VERBOSE_PREFIX_3 "Accepting %s call from '%s' to '%s' on channel %d/%d, span %d\n",
09765                               pri->pvts[chanpos]->digital ? "data" : "voice", e->ring.callingnum, pri->pvts[chanpos]->exten, 
09766                                  pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09767                         zt_enable_ec(pri->pvts[chanpos]);
09768                          if(!ast_strlen_zero(e->ring.callingsubaddr)) {
09769                         pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
09770                          }
09771                             if (!ast_strlen_zero(e->ring.callingnum)) {
09772                         char tmpstr[256];
09773                              pri_make_callerid(pri, tmpstr, sizeof(tmpstr), e->ring.callingnum, sizeof(e->ring.callingnum), e->ring.callingplan, e->ring.callingpres, 0);
09774                              pbx_builtin_setvar_helper(c, "PRI_NETWORK_CID", tmpstr);
09775                          }
09776                          if (!ast_strlen_zero(e->ring.callingani)) {
09777                         char tmpstr[256];
09778                              pri_make_callerid(pri, tmpstr,sizeof(tmpstr),  e->ring.callingani, sizeof(e->ring.callingani), e->ring.callingplanuser, e->ring.callingpresuser, 0);
09779                              pbx_builtin_setvar_helper(c, "PRI_USER_CID", e->ring.callednum);
09780                          }
09781                          if (!ast_strlen_zero(e->ring.useruserinfo)) {
09782                              pbx_builtin_setvar_helper(c, "UUI", e->ring.useruserinfo);
09783                          }
09784                      } else {
09785 
09786                         ast_mutex_lock(&pri->lock);
09787 
09788                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n", 
09789                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
09790                         pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION, -1);
09791                         pri->pvts[chanpos]->call = NULL;
09792                      }
09793                   }
09794                } else {
09795                /* invalid extension */
09796                   if (option_verbose > 2)
09797                      ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' from '%s' does not exist.  Rejecting call on channel %d/%d, span %d\n",
09798                         pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan, 
09799                            pri->pvts[chanpos]->prioffset, pri->span);
09800                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED, -1);
09801                   pri->pvts[chanpos]->call = NULL;
09802                   pri->pvts[chanpos]->exten[0] = '\0';
09803                }
09804                if (crv)
09805                   ast_mutex_unlock(&crv->lock);
09806                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09807             } else {
09808                if (e->ring.flexible)
09809                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, -1);
09810                else
09811                   pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, -1);
09812             }
09813             break;
09814          case PRI_EVENT_RINGING:
09815             chanpos = pri_find_principle(pri, e->ringing.channel);
09816             if (chanpos < 0) {
09817                ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n", 
09818                   PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09819             } else {
09820                chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
09821                if (chanpos < 0) {
09822                   ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n", 
09823                      PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
09824                } else {
09825                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09826                   if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
09827                   // XXX   zt_enable_ec(pri->pvts[chanpos]);
09828                      pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
09829                      pri->pvts[chanpos]->alerting = 1;
09830                   } else
09831                      ast_log(LOG_DEBUG, "Deferring ringing notification because of extra digits to dial...\n");
09832 #ifdef PRI_PROGRESS_MASK
09833                   if (e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09834 #else
09835                   if (e->ringing.progress == 8) {
09836 #endif
09837                      /* Now we can do call progress detection */
09838                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09839                         /* RINGING detection isn't required because we got ALERTING signal */
09840                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
09841                         pri->pvts[chanpos]->dsp_features = 0;
09842                      }
09843                   }
09844 
09845 #ifdef SUPPORT_USERUSER
09846                   if (!ast_strlen_zero(e->ringing.useruserinfo)) {
09847                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
09848                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09849                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->ringing.useruserinfo);
09850                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
09851                   }
09852 #endif
09853 
09854                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09855                }
09856             }
09857             break;
09858          case PRI_EVENT_PROGRESS:
09859             /* Get chan value if e->e is not PRI_EVENT_RINGING */
09860             chanpos = pri_find_principle(pri, e->proceeding.channel);
09861             if (chanpos > -1) {
09862                 if ((pri->pvts[chanpos]->priindication_oob == 2) && (e->proceeding.cause == PRI_CAUSE_USER_BUSY)) {
09863                /* received PROGRESS with cause BUSY, no inband callprogress wanted => hang up! */
09864                if (pri->pvts[chanpos]->owner) {
09865                    pri->pvts[chanpos]->owner->hangupcause = AST_CAUSE_USER_BUSY;
09866                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
09867                }
09868                 } else {
09869 #ifdef PRI_PROGRESS_MASK
09870                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)) {
09871 #else
09872                if ((!pri->pvts[chanpos]->progress) || (e->proceeding.progress == 8)) {
09873 #endif
09874                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
09875 
09876                   if (e->proceeding.cause > -1) {
09877                      if (option_verbose > 2)
09878                         ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with cause code %d received\n", e->proceeding.cause);
09879 
09880                      /* Work around broken, out of spec USER_BUSY cause in a progress message */
09881                      if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
09882                         if (pri->pvts[chanpos]->owner) {
09883                            if (option_verbose > 2)
09884                               ast_verbose(VERBOSE_PREFIX_3 "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
09885 
09886                            pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
09887                            f.subclass = AST_CONTROL_BUSY;
09888                         }
09889                      }
09890                   }
09891                   
09892                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09893                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
09894                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09895                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09896 #ifdef PRI_PROGRESS_MASK
09897                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09898 #else
09899                   if (e->proceeding.progress == 8) {
09900 #endif
09901                      /* Now we can do call progress detection */
09902                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09903                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09904                         pri->pvts[chanpos]->dsp_features = 0;
09905                      }
09906                   }
09907                   pri->pvts[chanpos]->progress = 1;
09908                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09909                }
09910             }
09911             break;
09912          case PRI_EVENT_PROCEEDING:
09913             chanpos = pri_find_principle(pri, e->proceeding.channel);
09914             if (chanpos > -1) {
09915                 chanpos = pri_fixup_principle(pri, chanpos, e->proceeding.call);
09916                 if (chanpos < 0) {
09917                ast_log(LOG_WARNING, "Received PROCEEDING on channel %d/%d not in use on span %d\n", 
09918                   PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), pri->span);
09919                chanpos = -1;
09920                 } else {
09921                if (!pri->pvts[chanpos]->proceeding) {
09922                   struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
09923                   
09924                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09925                   ast_log(LOG_DEBUG, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
09926                         pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
09927                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
09928 #ifdef PRI_PROGRESS_MASK
09929                   if (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE) {
09930 #else
09931                   if (e->proceeding.progress == 8) {
09932 #endif
09933                      /* Now we can do call progress detection */
09934                      if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
09935                         ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
09936                         pri->pvts[chanpos]->dsp_features = 0;
09937                      }
09938                      /* Bring voice path up */
09939                      f.subclass = AST_CONTROL_PROGRESS;
09940                      zap_queue_frame(pri->pvts[chanpos], &f, pri);
09941                   }
09942                   pri->pvts[chanpos]->proceeding = 1;
09943                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09944                }
09945             }
09946             break;
09947          case PRI_EVENT_FACNAME:
09948             chanpos = pri_find_principle(pri, e->facname.channel);
09949             if (chanpos < 0) {
09950                ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n", 
09951                   PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09952             } else {
09953                chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
09954                if (chanpos < 0) {
09955                   ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n", 
09956                      PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
09957                } else {
09958                   /* Re-use *69 field for PRI */
09959                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
09960                   ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
09961                   ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
09962                   pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
09963                   zt_enable_ec(pri->pvts[chanpos]);
09964                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
09965                }
09966             }
09967             break;            
09968          case PRI_EVENT_SUSPEND_REQ:
09969             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
09970                 pri_suspend_reject(pri->pri, e->suspend_req.call, "");
09971                 break;
09972             }
09973             chanpos = pri_find_principle(pri, e->suspend_req.channel);
09974             if (chanpos < 0)  {
09975                ast_log(LOG_WARNING, "Suspend requested on unconfigured channel %d span %d\n", chanpos, pri->span);
09976                chanpos = -1;
09977             }
09978 
09979             if (chanpos > -1) {
09980                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
09981                 if (pri->pvts[chanpos]->owner) {
09982                if (ast_bridged_channel(pri->pvts[chanpos]->owner)) {
09983                    struct zt_suspended_call *zpc;
09984                    char tmpstr[256];
09985                    zpc = malloc(sizeof(struct zt_suspended_call));
09986                    if (!zpc) {
09987                   ast_log(LOG_ERROR, "unable to malloc zt_suspended_call\n");
09988                   break;
09989                    }
09990                    strncpy(zpc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zpc->msn));
09991                    strncpy(zpc->callid,  e->suspend_req.callid, sizeof(zpc->callid));
09992                    ast_masq_park_call(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, 0, &zpc->parked_at);
09993                    zpc->next = pri->suspended_calls;
09994                    pri->suspended_calls = zpc;
09995                    snprintf(tmpstr, sizeof(tmpstr), "Parked at %d", zpc->parked_at);
09996                    pri_suspend_acknowledge(pri->pri, e->suspend_req.call,tmpstr);
09997                    pri->pvts[chanpos]->call = NULL;
09998                    pri->pvts[chanpos]->tei = -1;
09999                    pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10000                } else {
10001                    pri_suspend_reject(pri->pri, e->suspend_req.call, "cant park a non-bridge");
10002                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10003                    break;
10004                }
10005                 } else {
10006                pri_suspend_reject(pri->pri, e->suspend_req.call, "");
10007                 }
10008                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10009             }
10010             break;
10011          case PRI_EVENT_RESUME_REQ:
10012             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
10013                 break;
10014             }
10015             chanpos = pri_find_empty_chan(pri, 1);
10016             if (chanpos < 0) { 
10017                pri_resume_reject(pri->pri, e->resume_req.call,"All channels busy");
10018                ast_log(LOG_WARNING, "Resume requested on odd channel number %d span %d\n", chanpos, pri->span);
10019                chanpos = -1;
10020             } else if (!pri->pvts[chanpos]) {
10021                pri_resume_reject(pri->pri, e->resume_req.call,"General protection fault in module 0x0BRI");
10022                chanpos = -1;
10023             }
10024 
10025             if (chanpos > -1) {
10026                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10027                 if (!pri->pvts[chanpos]->owner) {
10028                struct zt_suspended_call *zpc, *zpcl;
10029                int unparked=0;
10030                char extenstr[255], temp[255];
10031                zpc = NULL;
10032                zpcl = pri->suspended_calls;
10033                while (zpcl) {
10034                //    ast_log(LOG_NOTICE, "zpc->parked_at %d zpcl->callid %s\n",zpcl->parked_at, zpcl->callid);
10035                    if (((strlen(zpcl->callid) == 0) && (strlen(e->resume_req.callid)==0)) || (!strcmp(zpcl->callid,e->resume_req.callid))) {
10036                   int law;
10037                   // found a parked call
10038                   snprintf(extenstr, sizeof(extenstr), "%d", zpcl->parked_at);
10039                   strncpy(pri->pvts[chanpos]->exten, extenstr, sizeof(pri->pvts[chanpos]->exten));
10040                // strncpy(pri->pvts[chanpos]->context, ast_parking_con(), sizeof(pri->pvts[chanpos]->context));
10041                        pri->pvts[chanpos]->call = e->resume_req.call;
10042                        law = 1;
10043                        if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
10044                          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
10045                // uhh ohh...what shall we do without the bearer cap???
10046                   law = ZT_LAW_ALAW;
10047                   res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
10048                   if (res < 0) 
10049                       ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
10050                   if (!pri->pvts[chanpos]->digital) {
10051                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
10052                   } else {
10053                       res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, 0, 0, pri->pvts[chanpos]->law);
10054                   }
10055                   if (res < 0)
10056                       ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
10057                   /* Start PBX */
10058                   c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 1, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
10059                   if (c) {
10060                       pri->pvts[chanpos]->owner = c;
10061                       pri->pvts[chanpos]->call = e->resume_req.call;
10062                       zt_enable_ec(pri->pvts[chanpos]);
10063                       zt_train_ec(pri->pvts[chanpos]);
10064                   } else {
10065                       ast_log(LOG_ERROR, "unable to start pbx\n");
10066                   }
10067 
10068                   if (zpc) {
10069                       zpc->next = zpcl->next;
10070                       free(zpcl);
10071                       zpcl = zpc->next;
10072                   } else {
10073                       // remove head
10074                       pri->suspended_calls = zpcl->next;
10075                       free(zpcl);
10076                       zpcl = pri->suspended_calls;
10077                       zpc = NULL;
10078                   }
10079                   unparked = 1;
10080                   snprintf(temp, sizeof(temp), "Unparked %s", extenstr);
10081                   pri_resume_acknowledge(pri->pri, e->resume_req.call, chanpos + 1, temp);
10082                        break;
10083                    }
10084                    zpc = zpcl;
10085                    if (zpcl) zpcl = zpcl->next;
10086                }
10087                if (!unparked)
10088                    pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
10089                 } else {
10090                pri_resume_reject(pri->pri, e->resume_req.call,"No suspended call to unpark!");
10091                 }
10092                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10093             }
10094             break;
10095          case PRI_EVENT_HOLD_REQ:
10096             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
10097                 pri_hold_reject(pri->pri, e->hold_req.call);
10098                 break;
10099             }
10100             chanpos = pri_find_principle(pri, e->hold_req.channel);
10101             if (chanpos < 0)  {
10102                ast_log(LOG_WARNING, "Hold requested on unconfigured channel %d span %d\n", chanpos, pri->span);
10103                chanpos = -1;
10104             }
10105             if (chanpos > -1) {
10106             //    ast_log(LOG_NOTICE, "Hold request for channel number %d span %d\n", chanpos, pri->span);
10107                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10108                 if (pri->pvts[chanpos]->owner) {
10109                struct zt_pvt *p = pri->pvts[chanpos];
10110                struct zt_holded_call *zhc;
10111                int holdacked=0;
10112                
10113 //             ast_log(LOG_NOTICE,"HOLD request from channel %s tei %d\n",p->owner->name, e->hold_req.tei);
10114                   if (ast_bridged_channel(p->owner)) {
10115                    zhc = malloc(sizeof(struct zt_holded_call));
10116                    if (!zhc) {
10117                   ast_log(LOG_ERROR, "unable to malloc zt_holded_call\n");
10118                   break;
10119                    }
10120                    memset(zhc, 0, sizeof(zhc));
10121                    strncpy(zhc->msn,  pri->pvts[chanpos]->cid_num, sizeof(zhc->msn));
10122                    strncpy(zhc->uniqueid,  ast_bridged_channel(p->owner)->uniqueid, sizeof(zhc->uniqueid));
10123                    zhc->tei = e->hold_req.tei;
10124                    zhc->cref = e->hold_req.cref;
10125                    zhc->call = e->hold_req.call;
10126                    zhc->channel = p->owner;
10127                    zhc->alreadyhungup = 0;
10128                    zhc->bridge = ast_bridged_channel(p->owner);
10129                    zhc->next = pri->holded_calls;
10130                    pri->holded_calls = zhc;
10131 
10132                    /* put channel on hold */
10133                    ast_masq_hold_call(ast_bridged_channel(p->owner), p->owner);
10134 
10135                    pri_hold_acknowledge(pri->pri, e->hold_req.call);
10136                    holdacked = 1;
10137                    p->call = NULL; // free the bchannel withouth destroying the call
10138                    p->tei = -1;
10139                } else {
10140                    // cant hold a non-bridge,...yet
10141                    
10142                    // make a fake channel
10143                    
10144                    // masquerade
10145                    
10146                    // put on hold
10147                    pri_hold_reject(pri->pri, e->hold_req.call);
10148                }
10149                 } else {
10150                    pri_hold_reject(pri->pri, e->hold_req.call);
10151                 }
10152                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10153             } else {
10154                pri_hold_reject(pri->pri, e->hold_req.call);
10155             }
10156             break; 
10157          case PRI_EVENT_RETRIEVE_REQ:
10158             if ((pri->nodetype != BRI_NETWORK_PTMP) && (pri->nodetype != BRI_NETWORK)) {
10159                 pri_retrieve_reject(pri->pri, e->retrieve_req.call);
10160                 break;
10161             }
10162             chanpos = pri_find_empty_chan(pri, 1);
10163             if (chanpos < 0) { 
10164                pri_retrieve_reject(pri->pri, e->retrieve_req.call);
10165                ast_log(LOG_WARNING, "Retrieve requested on odd channel number %d span %d\n", chanpos, pri->span);
10166                chanpos = -1;
10167                break;
10168             } else if (!pri->pvts[chanpos]) {
10169                ast_log(LOG_WARNING, "Retrieve requested on unconfigured channel number %d span %d\n", chanpos, pri->span);
10170                pri_retrieve_reject(pri->pri, e->retrieve_req.call);
10171                chanpos = -1;
10172                break;
10173             }
10174             if (chanpos > -1) {
10175                 struct zt_holded_call *onhold = NULL;
10176                 int retrieved = 0;
10177                 int res = -1;
10178                 struct app_tmp *tmp;
10179                 pthread_attr_t attr;
10180                 int law;
10181 
10182                 onhold = pri_get_callonhold(pri, e->retrieve_req.cref, e->retrieve_req.tei);
10183 
10184                 if (!onhold) {
10185                pri_retrieve_reject(pri->pri, e->retrieve_req.call);
10186                break;
10187                 }
10188                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10189                // found a parked call
10190                law = 1;
10191                if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1)
10192                    ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]), law);
10193                // uhh ohh...what shall we do without the bearer cap???
10194                law = ZT_LAW_ALAW;
10195                res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law);
10196                if (res < 0) 
10197                    ast_log(LOG_WARNING, "Unable to set law on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
10198                res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].zfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
10199                if (res < 0)
10200                    ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", PVT_TO_CHANNEL(pri->pvts[chanpos]));
10201                /* Start PBX */
10202                c = zt_new(pri->pvts[chanpos], AST_STATE_UP, 0, SUB_REAL, law, PRI_TRANS_CAP_SPEECH);
10203                if (c) {
10204                    pri->pvts[chanpos]->owner = c;
10205                    pri->pvts[chanpos]->outgoing = 1; /* for not sending proceedings... */
10206                    pri->pvts[chanpos]->call = e->retrieve_req.call;
10207                    pri->pvts[chanpos]->tei = e->retrieve_req.tei;
10208                       zt_enable_ec(pri->pvts[chanpos]);
10209                       zt_train_ec(pri->pvts[chanpos]);
10210                } else {
10211                    ast_log(LOG_ERROR, "unable to start pbx\n");
10212                }
10213 
10214                retrieved = 1;
10215             // ast_log(LOG_NOTICE, "sending RETRIEVE ACK on channel %d, span %d for tei %d cref %d\n",chanpos,pri->span, e->retrieve_req.tei,  e->retrieve_req.cref);
10216                pri_retrieve_acknowledge(pri->pri, e->retrieve_req.call, chanpos + 1);
10217 
10218                // the magic begins here: ....
10219                tmp = malloc(sizeof(struct app_tmp));
10220                if (tmp) {
10221                    memset(tmp, 0, sizeof(struct app_tmp));
10222                    strncpy(tmp->app, "holdedcall", sizeof(tmp->app) - 1);
10223                    strncpy(tmp->data, onhold->uniqueid, sizeof(tmp->data) - 1);
10224                    tmp->chan = c;
10225                }
10226                pri_destroy_callonhold(pri, onhold);
10227                onhold = NULL;
10228 
10229                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10230                pthread_attr_init(&attr);
10231                pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10232                if (ast_pthread_create(&tmp->t, &attr, ast_pbx_run_app, tmp)) {
10233                    ast_log(LOG_WARNING, "Unable to spawn execute thread on %s: %s\n", c->name, strerror(errno));
10234                    free(tmp);
10235                    ast_hangup(c);
10236                    retrieved = 0;
10237                }
10238 
10239                 if (!retrieved) {
10240                pri_retrieve_reject(pri->pri, e->retrieve_req.call);
10241                 }
10242             }
10243             break; 
10244          case PRI_EVENT_DISPLAY_RECEIVED:
10245             ast_log(LOG_NOTICE, "DISPLAY IE: [ %s ] received\n",e->display.text);
10246             chanpos = pri_find_principle(pri, e->display.channel);
10247             if (chanpos < 0) {
10248                 ast_log(LOG_WARNING, "odd channel number %d span %d\n", chanpos, pri->span);
10249                 chanpos = -1;
10250             } 
10251             if (chanpos > -1) {
10252                 if (pri->pvts[chanpos]->owner) {
10253          //    ast_sendtext(pri->pvt[chanpos]->owner, e->display.text);
10254                 }
10255             }           
10256             break;
10257          case PRI_EVENT_ANSWER:
10258             chanpos = pri_find_principle(pri, e->answer.channel);
10259             if (chanpos < 0) {
10260                ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", 
10261                   PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
10262             } else {
10263                chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
10264                if (chanpos < 0) {
10265                   ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", 
10266                      PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
10267                } else {
10268                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10269                   pri->pvts[chanpos]->tei = e->answer.tei;
10270                   /* Now we can do call progress detection */
10271 
10272                   /* We changed this so it turns on the DSP no matter what... progress or no progress.
10273                    * By this time, we need DTMF detection and other features that were previously disabled
10274                    * -- Matt F */
10275                   if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
10276                      ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
10277                      pri->pvts[chanpos]->dsp_features = 0;
10278                   }
10279                   if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
10280                      ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
10281                      x = ZT_START;
10282                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
10283                      if (res < 0) {
10284                         if (errno != EINPROGRESS) {
10285                            ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
10286                         }
10287                      }
10288                   } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
10289                      pri->pvts[chanpos]->dialing = 1;
10290                      /* Send any "w" waited stuff */
10291                      res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
10292                      if (res < 0) {
10293                         ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", pri->pvts[chanpos]->channel);
10294                         pri->pvts[chanpos]->dop.dialstr[0] = '\0';
10295                      } else 
10296                         ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
10297                      pri->pvts[chanpos]->dop.dialstr[0] = '\0';
10298                   } else if (pri->pvts[chanpos]->confirmanswer) {
10299                      ast_log(LOG_DEBUG, "Waiting for answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
10300                      enable_dtmf_detect(pri->pvts[chanpos]);
10301                   } else {
10302                      pri->pvts[chanpos]->dialing = 0;
10303                      pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
10304                      /* Enable echo cancellation if it's not on already */
10305                      zt_enable_ec(pri->pvts[chanpos]);
10306                      zt_train_ec(pri->pvts[chanpos]);
10307                      /* stop ignoring inband dtmf */
10308                      enable_dtmf_detect(pri->pvts[chanpos]);
10309                   }
10310 
10311 #ifdef SUPPORT_USERUSER
10312                   if (!ast_strlen_zero(e->answer.useruserinfo)) {
10313                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10314                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10315                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->answer.useruserinfo);
10316                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10317                   }
10318 #endif
10319 
10320                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10321                }
10322             }
10323             break;            
10324          case PRI_EVENT_HANGUP:
10325             chanpos = pri_find_principle(pri, e->hangup.channel);
10326             if (chanpos < 0) {
10327                ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", 
10328                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10329             } else {
10330                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10331                if (chanpos > -1) {
10332                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10333                   if (!pri->pvts[chanpos]->alreadyhungup) {
10334                      /* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
10335                      pri->pvts[chanpos]->alreadyhungup = 1;
10336                      if (pri->pvts[chanpos]->realcall) 
10337                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10338                      else if (pri->pvts[chanpos]->owner) {
10339                         /* Queue a BUSY instead of a hangup if our cause is appropriate */
10340                         pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10341                         if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10342                            pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10343                         else {
10344                            switch (e->hangup.cause) {
10345                               case PRI_CAUSE_USER_BUSY:
10346                                  pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10347                                  break;
10348                               case PRI_CAUSE_CALL_REJECTED:
10349                               case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10350                               case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10351                               case PRI_CAUSE_SWITCH_CONGESTION:
10352                               case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10353                               case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10354                                  pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10355                                  break;
10356                               default:
10357                                  pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10358                            }
10359                         }
10360                      }
10361                      if (option_verbose > 2) 
10362                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", 
10363                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
10364                   } else {
10365                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10366                      pri->pvts[chanpos]->call = NULL;
10367                      pri->pvts[chanpos]->tei = -1;
10368                   }
10369                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10370                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10371                          if (option_verbose > 2)
10372                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d on span %d since channel reported in use\n", 
10373                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10374                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10375                          pri->pvts[chanpos]->resetting = 1;
10376                      }
10377                   }
10378                   if (e->hangup.aoc_units > -1) {
10379                      if (pri->pvts[chanpos]->owner) {
10380                          char tmpstr[256];
10381                          snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10382                          pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10383                      }
10384                      if (option_verbose > 2)
10385                         ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10386                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10387                   }
10388 
10389 #ifdef SUPPORT_USERUSER
10390                   if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
10391                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10392                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10393                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
10394                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10395                   }
10396 #endif
10397 
10398                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10399                } else {
10400                   struct zt_holded_call *onhold = NULL;
10401                   /* check calls on hold */
10402                   onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
10403                   
10404                   if (onhold) {
10405                       // ast_log(LOG_NOTICE, "hangup, found cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
10406                       pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
10407                       pri_destroy_callonhold(pri, onhold);
10408                       onhold = NULL;
10409                   } else {
10410                       ast_log(LOG_NOTICE, "Hangup, did not find cref %d, tei %d\n",e->hangup.cref, e->hangup.tei);
10411                       ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", 
10412                      PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10413                   }
10414                }
10415             } 
10416             break;
10417 #ifndef PRI_EVENT_HANGUP_REQ
10418 #error please update libpri
10419 #endif
10420          case PRI_EVENT_HANGUP_REQ:
10421             chanpos = pri_find_principle(pri, e->hangup.channel);
10422             if (chanpos < 0) {
10423                if (pri->nodetype == BRI_NETWORK_PTMP) {
10424                    pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
10425                } else {
10426                    ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n", 
10427                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10428                }
10429             } else if ((pri->pvts[chanpos]->priindication_oob != 2) || (!e->hangup.inband_progress) || (!pri->pvts[chanpos]->outgoing)) {
10430                             /* dont hang up if we want to hear inband call progress */
10431                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10432                if (chanpos > -1) {
10433                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10434                   if (pri->pvts[chanpos]->realcall) 
10435                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10436                   else if (pri->pvts[chanpos]->owner) {
10437                      char tmpstr[256];
10438                      snprintf(tmpstr, sizeof(tmpstr), "%d", e->hangup.cause);
10439                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "PRI_CAUSE", tmpstr);
10440                      pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10441                      if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP)
10442                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10443                      else {
10444                         switch (e->hangup.cause) {
10445                            case PRI_CAUSE_USER_BUSY:
10446                               pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
10447                               break;
10448                            case PRI_CAUSE_CALL_REJECTED:
10449                            case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
10450                            case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
10451                            case PRI_CAUSE_SWITCH_CONGESTION:
10452                            case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
10453                            case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
10454                               pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
10455                               break;
10456                            default:
10457                               pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10458                         }
10459                      }
10460                      if (option_verbose > 2) 
10461                         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);
10462                      if (e->hangup.aoc_units > -1)
10463                         if (option_verbose > 2)
10464                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10465                               pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10466                      if (e->hangup.aoc_units > -1) {
10467                          if (pri->pvts[chanpos]->owner) {
10468                         char tmpstr[256];
10469                         snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10470                         pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10471                          }
10472                          if (option_verbose > 2)
10473                            ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10474                            pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10475                      }
10476                      if (pri->nodetype == BRI_NETWORK_PTMP) {
10477                          // check for bri transfers, not everybody uses ECT...
10478                          if (pri->pvts[chanpos]->owner) {
10479                         // find on hold call
10480                         struct zt_holded_call *onhold = NULL;
10481                         struct ast_channel *transferee = NULL;
10482                         int transfer_ok = 0;
10483  
10484                         onhold = pri_get_callonhold(pri, -1, e->hangup.tei);
10485  
10486                         if (onhold) {
10487                             if (pri->pvts[chanpos]->pritransfer == 2) {
10488                            if (((pri->pvts[chanpos]->owner->_state != AST_STATE_RING) && (pri->pvts[chanpos]->owner->_state != AST_STATE_RESERVED)) || ((!ast_strlen_zero(pri->pvts[chanpos]->exten)) && (strncasecmp(pri->pvts[chanpos]->exten, "s", sizeof(pri->pvts[chanpos]->exten))))) {
10489                                   transferee = ast_get_holded_call(onhold->uniqueid);
10490  
10491                                if (transferee) {
10492                               if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
10493                                      ast_indicate(transferee, AST_CONTROL_RINGING);
10494                               }
10495  
10496                               pri->pvts[chanpos]->owner->_softhangup &= ~AST_SOFTHANGUP_DEV;
10497   
10498                                    ast_mutex_unlock(&transferee->lock);
10499                               if (ast_channel_masquerade(pri->pvts[chanpos]->owner, transferee)) {
10500                                   ast_log(LOG_WARNING, "unable to masquerade\n");
10501                                    } else { 
10502                                      /* beware of zombies!!! */
10503                                   ast_set_flag(transferee, AST_FLAG_ZOMBIE);
10504                                   pri->pvts[chanpos]->owner = NULL;
10505                                   pri->pvts[chanpos]->tei = -1;
10506                                   transfer_ok = 1;
10507                               }
10508                                }
10509                            }  
10510                             } else if (pri->pvts[chanpos]->pritransfer == 0) {
10511                            ast_log(LOG_NOTICE, "killing channel %s \n", onhold->uniqueid);
10512                            ast_retrieve_call_to_death(onhold->uniqueid);
10513                            transfer_ok = 1;
10514                             } else if (pri->pvts[chanpos]->pritransfer == 1) {
10515                            /* we use ECT transfers, so just ignore this */
10516                            transfer_ok = 0;
10517                             }
10518                      
10519                             if (transfer_ok) {
10520                            onhold->alreadyhungup = 1; 
10521                            pri_hangup(pri->pri, onhold->call, e->hangup.cause, -1);
10522                            onhold = NULL;
10523                             }
10524                             ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10525                             break;
10526                                                          } else {
10527                                                                     pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10528                                                                         pri->pvts[chanpos]->call = NULL;
10529                                                                         pri->pvts[chanpos]->tei = -1;
10530                                                                 }
10531                          }
10532                      }
10533                   } else {
10534                      pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause, -1);
10535                      pri->pvts[chanpos]->call = NULL;
10536                      pri->pvts[chanpos]->tei = -1;
10537                   }
10538                   if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
10539                      if ((pri->nodetype != BRI_CPE_PTMP) && (pri->nodetype != BRI_NETWORK_PTMP)) {
10540                          if (option_verbose > 2)
10541                         ast_verbose(VERBOSE_PREFIX_3 "Forcing restart of channel %d/%d span %d since channel reported in use\n", 
10542                            PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10543                          pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
10544                          pri->pvts[chanpos]->resetting = 1;
10545                      }
10546                   }
10547 
10548 #ifdef SUPPORT_USERUSER
10549                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10550                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10551                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10552                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
10553                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10554                   }
10555 #endif
10556 
10557                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10558                } else {
10559                   if (pri->nodetype != BRI_NETWORK_PTMP) {
10560                       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);
10561                   } else {
10562                       // check holded_calls!!!
10563                       struct zt_holded_call *onhold = NULL;
10564  
10565                       onhold = pri_get_callonhold(pri, e->hangup.cref, e->hangup.tei);
10566  
10567                       if (onhold) {
10568                          pri_hangup(pri->pri, e->hangup.call, e->hangup.cause, -1);
10569                          ast_retrieve_call_to_death(onhold->uniqueid);
10570                          pri_destroy_callonhold(pri, onhold);
10571                          onhold = NULL;
10572                       } else {
10573                      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);
10574                       }
10575                   }
10576                }
10577             } 
10578             if ((chanpos > -1) && (pri->pvts[chanpos]->owner) && (pri->pvts[chanpos]->priindication_oob == 2) && (e->hangup.inband_progress) && (pri->pvts[chanpos]->outgoing)) {
10579                 ast_mutex_lock(&pri->pvts[chanpos]->lock);
10580                if (e->hangup.aoc_units > -1) {
10581                    char tmpstr[256];
10582                    snprintf(tmpstr, sizeof(tmpstr), "%d", (int)e->hangup.aoc_units);
10583                    pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "AOCEUNITS", tmpstr);
10584                    if (option_verbose > 2)
10585                   ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
10586                       pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
10587                }
10588                pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
10589                ast_channel_setwhentohangup(pri->pvts[chanpos]->owner, 5);
10590                 ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10591             }
10592             break;
10593          case PRI_EVENT_HANGUP_ACK:
10594             chanpos = pri_find_principle(pri, e->hangup.channel);
10595             if (chanpos < 0) {
10596                ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", 
10597                   PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
10598             } else {
10599                chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
10600                if (chanpos > -1) {
10601                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10602                   pri->pvts[chanpos]->call = NULL;
10603                   pri->pvts[chanpos]->tei = -1;
10604                   pri->pvts[chanpos]->resetting = 0;
10605                   if (pri->pvts[chanpos]->owner) {
10606                      if (option_verbose > 2) 
10607                         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);
10608                   }
10609 
10610 #ifdef SUPPORT_USERUSER
10611                   if (!ast_strlen_zero(e->hangup.useruserinfo)) {
10612                      struct ast_channel *owner = pri->pvts[chanpos]->owner;
10613                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10614                      pbx_builtin_setvar_helper(pri->pvts[chanpos]->owner, "USERUSERINFO", e->hangup.useruserinfo);
10615                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10616                   }
10617 #endif
10618 
10619                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10620                    }
10621                }
10622                 }
10623             }
10624             break;
10625          case PRI_EVENT_CONFIG_ERR:
10626             ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
10627             break;
10628          case PRI_EVENT_RESTART_ACK:
10629             chanpos = pri_find_principle(pri, e->restartack.channel);
10630             if (chanpos < 0) {
10631                /* Sometime switches (e.g. I421 / British Telecom) don't give us the
10632                   channel number, so we have to figure it out...  This must be why
10633                   everybody resets exactly a channel at a time. */
10634                for (x = 0; x < pri->numchans; x++) {
10635                   if (pri->pvts[x] && pri->pvts[x]->resetting) {
10636                      chanpos = x;
10637                      ast_mutex_lock(&pri->pvts[chanpos]->lock);
10638                      ast_log(LOG_DEBUG, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan, 
10639                            pri->pvts[chanpos]->prioffset, pri->span);
10640                      if (pri->pvts[chanpos]->realcall) 
10641                         pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10642                      else if (pri->pvts[chanpos]->owner) {
10643                         ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan, 
10644                            pri->pvts[chanpos]->prioffset, pri->span);
10645                         pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10646                      }
10647                      pri->pvts[chanpos]->resetting = 0;
10648                      if (option_verbose > 2)
10649                         ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10650                            pri->pvts[chanpos]->prioffset, pri->span);
10651                      ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10652                      if (pri->resetting)
10653                         pri_check_restart(pri);
10654                      break;
10655                   }
10656                }
10657                if (chanpos < 0) {
10658                   ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n", 
10659                      PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10660                }
10661             } else {
10662                if (pri->pvts[chanpos]) {
10663                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10664                   if (pri->pvts[chanpos]->realcall) 
10665                      pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
10666                   else if (pri->pvts[chanpos]->owner) {
10667                      ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
10668                         PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
10669                      pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
10670                   }
10671                   pri->pvts[chanpos]->resetting = 0;
10672                   if (option_verbose > 2)
10673                      ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan, 
10674                            pri->pvts[chanpos]->prioffset, pri->span);
10675                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10676                   if (pri->resetting)
10677                      pri_check_restart(pri);
10678                }
10679             }
10680             break;
10681          case PRI_EVENT_SETUP_ACK:
10682             chanpos = pri_find_principle(pri, e->setup_ack.channel);
10683             if (chanpos < 0) {
10684                ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n", 
10685                   PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
10686             } else {
10687                chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
10688                if (chanpos > -1) {
10689                   ast_mutex_lock(&pri->pvts[chanpos]->lock);
10690                   pri->pvts[chanpos]->setup_ack = 1;
10691                   /* Send any queued digits */
10692                   for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
10693                      ast_log(LOG_DEBUG, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
10694                      pri_information(pri->pri, pri->pvts[chanpos]->call, 
10695                         pri->pvts[chanpos]->dialdest[x]);
10696                   }
10697                   ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10698                } else
10699                   ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
10700             }
10701             break;
10702          case PRI_EVENT_NOTIFY:
10703             chanpos = pri_find_principle(pri, e->notify.channel);
10704             if (chanpos < 0) {
10705                ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
10706                   PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
10707             } else {
10708                struct ast_frame f = { AST_FRAME_CONTROL, };
10709                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10710                switch (e->notify.info) {
10711                case PRI_NOTIFY_REMOTE_HOLD:
10712                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10713                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on NETWORK channel. Starting MoH\n");
10714                       ast_moh_start(ast_bridged_channel(pri->pvts[chanpos]->owner), NULL, pri->pvts[chanpos]->mohinterpret);
10715                   } else {
10716                       ast_log(LOG_DEBUG, "Received REMOTE_HOLD notification on CPE channel. Not Starting MoH\n");
10717                   }
10718                   f.subclass = AST_CONTROL_HOLD;
10719                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10720                   break;
10721                case PRI_NOTIFY_REMOTE_RETRIEVAL:
10722                   if ((pri->nodetype == BRI_NETWORK_PTMP) || (pri->nodetype == BRI_NETWORK)) {
10723                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on NETWORK channel. Stopping MoH\n");
10724                       ast_moh_stop(ast_bridged_channel(pri->pvts[chanpos]->owner));
10725                   } else {
10726                       ast_log(LOG_DEBUG, "Received REMOTE_RETRIEVAL notification on CPE channel.\n");
10727                   }
10728                   f.subclass = AST_CONTROL_UNHOLD;
10729                   zap_queue_frame(pri->pvts[chanpos], &f, pri);
10730                   break;
10731                }
10732                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10733             }
10734             break;
10735          case PRI_EVENT_FACILITY:
10736                 if (e->facility.operation == 0x06) {
10737                struct ast_channel *chan = NULL;
10738                struct zt_holded_call *onhold = NULL;
10739                if (option_verbose > 2) {
10740                    ast_verbose(VERBOSE_PREFIX_3 "ECT requested by TEI %d for cref %d\n", e->facility.tei, e->facility.cref);
10741                }
10742                /* search for cref/tei in held calls */
10743                onhold = pri_get_callonhold(pri, e->facility.cref, e->facility.tei);
10744                if (onhold) {
10745                    chan = ast_get_holded_call(onhold->uniqueid);
10746                    onhold->alreadyhungup = 1;
10747                    onhold = NULL;
10748                    if (!chan) {
10749                   /* hang up */
10750                        pri_hangup(pri->pri, e->facility.call, 16, -1);
10751                   break;
10752                    }
10753                } else {
10754                    /* unknown cref/tei */
10755                    ast_log(LOG_WARNING, "did not find call on hold for cref %d tei %d\n", e->facility.tei, e->facility.cref);
10756                    /* hang up */
10757                    pri_hangup(pri->pri, e->facility.call, 16, -1);
10758                    break;
10759                }
10760  
10761                /* find an active call for the same tei */
10762                chanpos = pri_find_tei(pri, e->facility.call, e->facility.tei);
10763                if (chanpos < 0) {
10764                    /* did not find active call, hangup call on hold */
10765                    if (chan) {
10766                   ast_hangup(chan);
10767                   chan = NULL;
10768                    }
10769                } else {
10770                    ast_mutex_lock(&pri->pvts[chanpos]->lock);
10771                    /* transfer */
10772                    if (pri->pvts[chanpos]->owner) {
10773                   if (option_verbose > 3) {
10774                       ast_verbose(VERBOSE_PREFIX_3 "ECT: found %s on channel %d for tei %d\n", pri->pvts[chanpos]->owner->name ,chanpos, e->facility.tei);
10775                   }
10776                   /* pass callprogress if the channel is not up yet */
10777                   if (pri->pvts[chanpos]->owner->_state == AST_STATE_RINGING) {
10778                       ast_indicate(chan, AST_CONTROL_RINGING);
10779                   }
10780                   /* unlock the channel we removed from hold */
10781                   ast_mutex_unlock(&chan->lock);
10782                   if (ast_channel_masquerade(pri->pvts[chanpos]->owner, chan)) {
10783                          ast_log(LOG_WARNING, "unable to masquerade\n");
10784                   } else {
10785                       /* beware of zombies !!! */
10786                       ast_set_flag(chan, AST_FLAG_ZOMBIE);
10787                   //    chan->zombie = 1;
10788                   }
10789                    }
10790                    ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10791                }
10792                /* disconnect */
10793                pri_hangup(pri->pri, e->facility.call, 16, -1);
10794                 } else if (e->facility.operation == 0x0D) {
10795                ast_log(LOG_NOTICE, "call deflection to %s requested.\n", e->facility.forwardnum);
10796                ast_mutex_lock(&pri->pvts[chanpos]->lock);
10797                    /* transfer */
10798                    if (pri->pvts[chanpos]->owner) {
10799                   snprintf(pri->pvts[chanpos]->owner->call_forward, sizeof(pri->pvts[chanpos]->owner->call_forward), "Local/%s@%s", e->facility.forwardnum, pri->pvts[chanpos]->owner->context);
10800                    }
10801                ast_mutex_unlock(&pri->pvts[chanpos]->lock);
10802                 } else {
10803                ast_log(LOG_WARNING, "Unknown facility operation %#x requested.\n", e->facility.operation);
10804                 }
10805             break;
10806          default:
10807             ast_log(LOG_DEBUG, "Event: %d\n", e->e);
10808          }
10809       }  
10810       ast_mutex_unlock(&pri->lock);
10811    }
10812    /* Never reached */
10813    return NULL;
10814 }
10815 
10816 static int start_pri(struct zt_pri *pri)
10817 {
10818    int res, x;
10819    ZT_PARAMS p;
10820    ZT_BUFFERINFO bi;
10821    struct zt_spaninfo si;
10822    int i;
10823    
10824    for (i = 0; i < NUM_DCHANS; i++) {
10825       if (!pri->dchannels[i])
10826          break;
10827       pri->fds[i] = open("/dev/zap/channel", O_RDWR, 0600);
10828       x = pri->dchannels[i];
10829       if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],ZT_SPECIFY,&x) == -1)) {
10830          ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
10831          return -1;
10832       }
10833       res = ioctl(pri->fds[i], ZT_GET_PARAMS, &p);
10834       if (res) {
10835          zt_close(pri->fds[i]);
10836          pri->fds[i] = -1;
10837          ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
10838          return -1;
10839       }
10840       if ((p.sigtype != ZT_SIG_HDLCFCS) && (p.sigtype != ZT_SIG_HARDHDLC)) {
10841          zt_close(pri->fds[i]);
10842          pri->fds[i] = -1;
10843          ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.  See /etc/zaptel.conf\n", x);
10844          return -1;
10845       }
10846       memset(&si, 0, sizeof(si));
10847       res = ioctl(pri->fds[i], ZT_SPANSTAT, &si);
10848       if (res) {
10849          zt_close(pri->fds[i]);
10850          pri->fds[i] = -1;
10851          ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
10852       }
10853       if (!si.alarms)
10854          pri->dchanavail[i] |= DCHAN_NOTINALARM;
10855       else
10856          pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
10857       bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
10858       bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
10859       bi.numbufs = 32;
10860       bi.bufsize = 1024;
10861       if (ioctl(pri->fds[i], ZT_SET_BUFINFO, &bi)) {
10862          ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d\n", x);
10863          zt_close(pri->fds[i]);
10864          pri->fds[i] = -1;
10865          return -1;
10866       }
10867       pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype, pri->span);
10868       /* Force overlap dial if we're doing GR-303! */
10869       if (pri->switchtype == PRI_SWITCH_GR303_TMC)
10870          pri->overlapdial = 1;
10871       pri_set_overlapdial(pri->dchans[i],pri->overlapdial);
10872       /* Enslave to master if appropriate */
10873       if (i)
10874          pri_enslave(pri->dchans[0], pri->dchans[i]);
10875       if (!pri->dchans[i]) {
10876          zt_close(pri->fds[i]);
10877          pri->fds[i] = -1;
10878          ast_log(LOG_ERROR, "Unable to create PRI structure\n");
10879          return -1;
10880       }
10881       pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
10882       pri_set_nsf(pri->dchans[i], pri->nsf);
10883 #ifdef PRI_GETSET_TIMERS
10884       for (x = 0; x < PRI_MAX_TIMERS; x++) {
10885          if (pritimers[x] != 0)
10886             pri_set_timer(pri->dchans[i], x, pritimers[x]);
10887       }
10888 #endif
10889    }
10890    /* Assume primary is the one we use */
10891    pri->pri = pri->dchans[0];
10892    pri->resetpos = -1;
10893    if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
10894       for (i = 0; i < NUM_DCHANS; i++) {
10895          if (!pri->dchannels[i])
10896             break;
10897          zt_close(pri->fds[i]);
10898          pri->fds[i] = -1;
10899       }
10900       ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
10901       return -1;
10902    }
10903    return 0;
10904 }
10905 
10906 static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
10907 {
10908    int which, span;
10909    char *ret = NULL;
10910 
10911    if (pos != rpos)
10912       return ret;
10913 
10914    for (which = span = 0; span < NUM_SPANS; span++) {
10915       if (pris[span].pri && ++which > state) {
10916          asprintf(&ret, "%d", span + 1);  /* user indexes start from 1 */
10917          break;
10918       }
10919    }
10920    return ret;
10921 }
10922 
10923 static char *complete_span_4(const char *line, const char *word, int pos, int state)
10924 {
10925    return complete_span_helper(line,word,pos,state,3);
10926 }
10927 
10928 static char *complete_span_5(const char *line, const char *word, int pos, int state)
10929 {
10930    return complete_span_helper(line,word,pos,state,4);
10931 }
10932 
10933 static int handle_pri_set_debug_file(int fd, int argc, char **argv)
10934 {
10935    int myfd, x, d;
10936    int span;
10937  
10938    if (argc < 6) 
10939       return RESULT_SHOWUSAGE;
10940 
10941    if (!strncasecmp(argv[1], "set", 3)) {
10942       if (argc < 7) 
10943          return RESULT_SHOWUSAGE;
10944 
10945       if (!argv[4] || ast_strlen_zero(argv[4]))
10946          return RESULT_SHOWUSAGE;
10947 
10948       if (!argv[5])
10949          return RESULT_SHOWUSAGE;
10950  
10951       if (!argv[6] || ast_strlen_zero(argv[6]))
10952          return RESULT_SHOWUSAGE;
10953  
10954       span = atoi(argv[6]);
10955       if ((span < 1) && (span > NUM_SPANS)) {
10956          return RESULT_SUCCESS;
10957       }
10958       
10959 
10960       myfd = open(argv[4], O_CREAT|O_WRONLY, 0600);
10961       if (myfd < 0) {
10962          ast_cli(fd, "Unable to open '%s' for writing\n", argv[4]);
10963          return RESULT_SUCCESS;
10964       }
10965       for (x=0; x < NUM_SPANS; x++) {
10966              ast_mutex_lock(&pris[x].lock);
10967           
10968           if (pris[x].span == span) {
10969          if (pris[x].debugfd >= 0)
10970              close(pris[x].debugfd);
10971          pris[x].debugfd = myfd;
10972          for (d=0; d < NUM_DCHANS; d++) {
10973              if (pris[x].dchans[d])
10974             pri_set_debug_fd(pris[x].dchans[d], myfd);
10975          }
10976           }
10977              ast_mutex_unlock(&pris[x].lock);
10978       }
10979   
10980       ast_cli(fd, "PRI debug output for span %d will be sent to '%s'\n", span, argv[4]);
10981    } else {
10982       if (!argv[5] || ast_strlen_zero(argv[5]))
10983          return RESULT_SHOWUSAGE;
10984       /* Assume it is unset */
10985       span = atoi(argv[5]);
10986       if ((span < 1) && (span > NUM_SPANS)) {
10987          return RESULT_SUCCESS;
10988       }
10989  
10990       for (x=0; x < NUM_SPANS; x++) {
10991              ast_mutex_lock(&pris[x].lock);
10992           
10993           if (pris[x].span == span) {
10994          if (pris[x].debugfd >= 0)
10995              close(pris[x].debugfd);
10996          pris[x].debugfd = -1;
10997          for (d=0; d < NUM_DCHANS; d++) {
10998              if (pris[x].dchans[d])
10999             pri_set_debug_fd(pris[x].dchans[d], -1);
11000          }
11001           }
11002              ast_mutex_unlock(&pris[x].lock);
11003       }
11004  
11005       ast_cli(fd, "PRI debug output to file for span %d disabled\n", span);
11006    }
11007 
11008    return RESULT_SUCCESS;
11009 }
11010 
11011 static int handle_pri_debug(int fd, int argc, char *argv[])
11012 {
11013    int span;
11014    int x;
11015    if (argc < 4) {
11016       return RESULT_SHOWUSAGE;
11017    }
11018    span = atoi(argv[3]);
11019    if ((span < 1) || (span > NUM_SPANS)) {
11020       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
11021       return RESULT_SUCCESS;
11022    }
11023    if (!pris[span-1].pri) {
11024       ast_cli(fd, "No PRI running on span %d\n", span);
11025       return RESULT_SUCCESS;
11026    }
11027    for (x = 0; x < NUM_DCHANS; x++) {
11028       if (pris[span-1].dchans[x])
11029          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
11030                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
11031                                                PRI_DEBUG_Q921_STATE);
11032    }
11033    ast_cli(fd, "Enabled debugging on span %d\n", span);
11034    return RESULT_SUCCESS;
11035 }
11036 
11037 
11038 
11039 
11040 static int handle_pri_no_debug(int fd, int argc, char *argv[])
11041 {
11042    int span;
11043    int x;
11044    if (argc < 5)
11045       return RESULT_SHOWUSAGE;
11046    span = atoi(argv[4]);
11047    if ((span < 1) || (span > NUM_SPANS)) {
11048       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
11049       return RESULT_SUCCESS;
11050    }
11051    if (!pris[span-1].pri) {
11052       ast_cli(fd, "No PRI running on span %d\n", span);
11053       return RESULT_SUCCESS;
11054    }
11055    for (x = 0; x < NUM_DCHANS; x++) {
11056       if (pris[span-1].dchans[x])
11057          pri_set_debug(pris[span-1].dchans[x], 0);
11058    }
11059    ast_cli(fd, "Disabled debugging on span %d\n", span);
11060    return RESULT_SUCCESS;
11061 }
11062 
11063 static int handle_pri_really_debug(int fd, int argc, char *argv[])
11064 {
11065    int span;
11066    int x;
11067    if (argc < 5)
11068       return RESULT_SHOWUSAGE;
11069    span = atoi(argv[4]);
11070    if ((span < 1) || (span > NUM_SPANS)) {
11071       ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
11072       return RESULT_SUCCESS;
11073    }
11074    if (!pris[span-1].pri) {
11075       ast_cli(fd, "No PRI running on span %d\n", span);
11076       return RESULT_SUCCESS;
11077    }
11078    for (x = 0; x < NUM_DCHANS; x++) {
11079       if (pris[span-1].dchans[x])
11080          pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
11081                                                PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
11082                                                PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
11083    }
11084    ast_cli(fd, "Enabled EXTENSIVE debugging on span %d\n", span);
11085    return RESULT_SUCCESS;
11086 }
11087 
11088 static void build_status(char *s, size_t len, int status, int active)
11089 {
11090    if (!s || len < 1) {
11091       return;
11092    }
11093    s[0] = '\0';
11094    if (status & DCHAN_PROVISIONED)
11095       strncat(s, "Provisioned, ", len - strlen(s) - 1);
11096    if (!(status & DCHAN_NOTINALARM))
11097       strncat(s, "In Alarm, ", len - strlen(s) - 1);
11098    if (status & DCHAN_UP)
11099       strncat(s, "Up", len - strlen(s) - 1);
11100    else
11101       strncat(s, "Down", len - strlen(s) - 1);
11102    if (active)
11103       strncat(s, ", Active", len - strlen(s) - 1);
11104    else
11105       strncat(s, ", Standby", len - strlen(s) - 1);
11106    s[len - 1] = '\0';
11107 }
11108 
11109 static int handle_pri_show_spans(int fd, int argc, char *argv[])
11110 {
11111    int span;
11112    int x;
11113    char status[256];
11114    if (argc != 3)
11115       return RESULT_SHOWUSAGE;
11116 
11117    for (span = 0; span < NUM_SPANS; span++) {
11118       if (pris[span].pri) {
11119          for (x = 0; x < NUM_DCHANS; x++) {
11120             if (pris[span].dchannels[x]) {
11121                build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
11122                ast_cli(fd, "PRI span %d/%d: %s\n", span + 1, x, status);
11123             }
11124          }
11125       }
11126    }
11127    return RESULT_SUCCESS;
11128 }
11129 
11130 static int handle_pri_show_span(int fd, int argc, char *argv[])
11131 {
11132    int span;
11133    int x;
11134    char status[256];
11135    if (argc < 4)
11136       return RESULT_SHOWUSAGE;
11137    span = atoi(argv[3]);
11138    if ((span < 1) || (span > NUM_SPANS)) {
11139       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
11140       return RESULT_SUCCESS;
11141    }
11142    if (!pris[span-1].pri) {
11143       ast_cli(fd, "No PRI running on span %d\n", span);
11144       return RESULT_SUCCESS;
11145    }
11146    for (x = 0; x < NUM_DCHANS; x++) {
11147       if (pris[span-1].dchannels[x]) {
11148 #ifdef PRI_DUMP_INFO_STR
11149          char *info_str = NULL;
11150 #endif
11151          ast_cli(fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
11152          build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
11153          ast_cli(fd, "Status: %s\n", status);
11154 #ifdef PRI_DUMP_INFO_STR
11155          info_str = pri_dump_info_str(pris[span-1].pri);
11156          if (info_str) {
11157             ast_cli(fd, "%s", info_str);
11158             free(info_str);
11159          }
11160 #else
11161          pri_dump_info(pris[span-1].pri);
11162 #endif
11163          ast_cli(fd, "\n");
11164       }
11165    }
11166    return RESULT_SUCCESS;
11167 }
11168 
11169 static int handle_pri_show_debug(int fd, int argc, char *argv[])
11170 {
11171    int x;
11172    int span;
11173    int count=0;
11174    int debug=0;
11175 
11176    for (span = 0; span < NUM_SPANS; span++) {
11177            if (pris[span].pri) {
11178          for (x = 0; x < NUM_DCHANS; x++) {
11179             debug = 0;
11180                if (pris[span].dchans[x]) {
11181                   debug = pri_get_debug(pris[span].dchans[x]);
11182                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" );
11183                count++;
11184             }
11185          }
11186       }
11187 
11188    }
11189        
11190    if (!count) 
11191       ast_cli(fd, "No debug set or no PRI running\n");
11192    return RESULT_SUCCESS;
11193 }
11194 
11195 static const char pri_debug_help[] = 
11196    "Usage: pri debug span <span>\n"
11197    "       Enables debugging on a given PRI span\n";
11198    
11199 static const char pri_no_debug_help[] = 
11200    "Usage: pri no debug span <span>\n"
11201    "       Disables debugging on a given PRI span\n";
11202 
11203 static const char pri_really_debug_help[] = 
11204    "Usage: pri intensive debug span <span>\n"
11205    "       Enables debugging down to the Q.921 level\n";
11206 
11207 static const char pri_show_span_help[] = 
11208    "Usage: pri show span <span>\n"
11209    "       Displays PRI Information on a given PRI span\n";
11210 
11211 static const char pri_show_spans_help[] = 
11212    "Usage: pri show spans\n"
11213    "       Displays PRI Information\n";
11214 
11215 static char bri_debug_help[] = 
11216    "Usage: bri debug span <span>\n"
11217    "       Enables debugging on a given BRI span\n";
11218    
11219 static char bri_no_debug_help[] = 
11220    "Usage: bri no debug span <span>\n"
11221    "       Disables debugging on a given BRI span\n";
11222 
11223 static char bri_really_debug_help[] = 
11224    "Usage: bri intensive debug span <span>\n"
11225    "       Enables debugging down to the Q.921 level\n";
11226 
11227 static struct ast_cli_entry zap_pri_cli[] = {
11228    { { "pri", "debug", "span", NULL },
11229    handle_pri_debug, "Enables PRI debugging on a span",
11230    pri_debug_help, complete_span_4 },
11231 
11232    { { "pri", "no", "debug", "span", NULL },
11233    handle_pri_no_debug, "Disables PRI debugging on a span",
11234    pri_no_debug_help, complete_span_5 },
11235 
11236    { { "pri", "intense", "debug", "span", NULL },
11237    handle_pri_really_debug, "Enables REALLY INTENSE PRI debugging",
11238    pri_really_debug_help, complete_span_5 },
11239 
11240    { { "pri", "show", "spans", NULL },
11241    handle_pri_show_spans, "Displays PRI Information",
11242    pri_show_spans_help },
11243 
11244    { { "pri", "show", "span", NULL },
11245    handle_pri_show_span, "Displays PRI Information",
11246    pri_show_span_help, complete_span_4 },
11247 
11248    { { "pri", "show", "debug", NULL },
11249    handle_pri_show_debug, "Displays current PRI debug settings" },
11250 
11251    { { "bri", "debug", "span", NULL }, handle_pri_debug,
11252      "Enables BRI debugging on a span", bri_debug_help, complete_span_4 },
11253 
11254    { { "bri", "no", "debug", "span", NULL }, handle_pri_no_debug,
11255      "Disables BRI debugging on a span", bri_no_debug_help, complete_span_5 },
11256 
11257    { { "bri", "intense", "debug", "span", NULL }, handle_pri_really_debug,
11258      "Enables REALLY INTENSE BRI debugging", bri_really_debug_help, complete_span_5 },
11259 
11260    { { "pri", "set", "debug", "file", NULL },
11261    handle_pri_set_debug_file, "Sends PRI debug output to the specified file" },
11262 
11263    { { "pri", "unset", "debug", "file", NULL },
11264    handle_pri_set_debug_file, "Ends PRI debug output to file" },
11265 };
11266 
11267 static char *zapCD_tdesc = "Call Deflection";
11268 static char *zapCD_app = "zapCD";
11269 static char *zapCD_synopsis = "Call Deflection";
11270 
11271 static int app_zapCD(struct ast_channel *chan, void *data)
11272 {
11273  struct zt_pvt *p = chan->tech_pvt;
11274 
11275  if((!p->pri) || (!p->pri->pri)) {
11276    return -1;
11277  }
11278 
11279  if(!data) {
11280      ast_log(LOG_WARNING, "zapCD wants a number to deflect to\n");
11281    return -1;
11282  }
11283  return pri_deflect(p->pri->pri, p->call, data);
11284 }
11285 
11286 static char *zapInband_tdesc = "Inband Call Progress (pre-answer)";
11287 static char *zapInband_app = "zapInband";
11288 static char *zapInband_synopsis = "Inband Call Progress";
11289 
11290 static int app_zapInband(struct ast_channel *chan, void *data)
11291 {
11292  struct zt_pvt *p = chan->tech_pvt;
11293 
11294  return pri_acknowledge(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1);
11295 }
11296 
11297 #endif /* HAVE_PRI */
11298 
11299 #ifdef HAVE_GSMAT
11300 static int handle_zap_reset_span(int fd, int argc, char *argv[])
11301 {
11302    int span;
11303    int sleep = 5000;
11304    if (argc < 4)
11305       return RESULT_SHOWUSAGE;
11306    span = atoi(argv[3]);
11307    if ((span < 1) || (span > NUM_SPANS)) {
11308       ast_cli(fd, "Invalid span '%s'.  Should be a number from %d to %d\n", argv[3], 1, NUM_SPANS);
11309       return RESULT_SUCCESS;
11310    }
11311    if (zt_reset_span(span, sleep)) {
11312        return RESULT_FAILURE;
11313    }
11314    return RESULT_SUCCESS;
11315 }
11316 
11317 static int handle_gsm_debug_helper(int fd, int channel, int debug)
11318 {
11319 /* gsm debug channel <channel> */
11320    struct zt_pvt *pvt = NULL;
11321    if (channel < 1) {
11322       ast_cli(fd, "Invalid channel %d.  Should be a number.\n", channel);
11323       return RESULT_SUCCESS;
11324    }
11325    pvt = iflist;
11326    while (pvt) {
11327        if (pvt->channel == channel) {
11328       ast_mutex_lock(&pvt->lock);
11329       gsm_set_debug(pvt->gsm.modul, debug);
11330       ast_mutex_unlock(&pvt->lock);
11331       ast_cli(fd, "%s debugging on channel %d\n", debug ? "Enabled":"Disabled", channel);
11332       return RESULT_SUCCESS;
11333        }
11334        pvt = pvt->next;
11335    }
11336    
11337    ast_cli(fd, "No GSM running on channel %d\n", channel);
11338    return RESULT_SUCCESS;
11339 }
11340 
11341 
11342 
11343 static int handle_gsm_debug(int fd, int argc, char *argv[])
11344 {
11345 /* gsm debug channel <channel> */
11346  int channel;
11347  if (argc < 4) {
11348    return RESULT_SHOWUSAGE;
11349  }
11350  channel = atoi(argv[3]);
11351  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_AT);
11352 }
11353 
11354 static int handle_gsm_no_debug(int fd, int argc, char *argv[])
11355 {
11356 /* gsm no debug channel <channel> */
11357  int channel;
11358  if (argc < 5) {
11359    return RESULT_SHOWUSAGE;
11360  }
11361  channel = atoi(argv[4]);
11362  return handle_gsm_debug_helper(fd, channel, GSM_DEBUG_NONE);
11363 }
11364 
11365 static char zap_reset_help[] = 
11366    "Usage: zap reset span <span>\n"
11367    "       Reset/Restart a zaptel span\n";
11368 
11369 static char gsm_debug_help[] = 
11370    "Usage: gsm debug channel <channel>\n"
11371    "       Enables debugging on a given GSM channel\n";
11372    
11373 static char gsm_no_debug_help[] = 
11374    "Usage: gsm no debug channel <channel>\n"
11375    "       Disables debugging on a given GSM channel\n";
11376 
11377 static struct ast_cli_entry zap_gsm_cli[] = {
11378    { { "zap", "reset", "span", NULL }, handle_zap_reset_span,
11379      "Restart a zaptel span", zap_reset_help, complete_span_4 },
11380    { { "gsm", "debug", "channel", NULL }, handle_gsm_debug,
11381      "Enables GSM debugging on a channel", gsm_debug_help },
11382    { { "gsm", "no", "debug", "channel", NULL }, handle_gsm_no_debug,
11383      "Disables GSM debugging on a channel", gsm_no_debug_help},
11384 };
11385 
11386 
11387 
11388 static char gsm_send_pdu_help[] = 
11389    "Usage: gsm send pdu <channel> <pdu>\n"
11390    "       Sends a PDU on a GSM channel\n";
11391 
11392 
11393 
11394 static int handle_gsm_send_pdu(int fd, int argc, char *argv[])
11395 {
11396 /* gsm send sms <channel> <destination> <message> */
11397    int channel;
11398    struct zt_pvt *pvt = NULL;
11399    if (argc < 5) {
11400       return RESULT_SHOWUSAGE;
11401    }
11402    channel = atoi(argv[3]);
11403    if (channel < 1) {
11404       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11405       return RESULT_SUCCESS;
11406    }
11407    pvt = iflist;
11408    while (pvt) {
11409        if (pvt->channel == channel) {
11410       if (pvt->owner) {
11411           ast_cli(fd, "Channel in use.\n");
11412           return RESULT_FAILURE;
11413       } else {
11414           ast_mutex_lock(&pvt->lock);
11415           gsm_sms_send_pdu(pvt->gsm.modul, argv[4]);
11416           ast_mutex_unlock(&pvt->lock);
11417           return RESULT_SUCCESS;
11418       }
11419        }
11420        pvt = pvt->next;
11421    }
11422    
11423    return RESULT_SUCCESS;
11424 }
11425 
11426 static struct ast_cli_entry gsm_send_pdu = {
11427    { "gsm", "send", "pdu", NULL }, handle_gsm_send_pdu, "Sends a SM on a GSM channel", gsm_send_pdu_help, complete_span_4 };
11428 
11429 
11430 static char gsm_send_sms_help[] = 
11431    "Usage: gsm send sms <channel> <destination> <message>\n"
11432    "       Sends a SM on a GSM channel\n";
11433 
11434 
11435 static int handle_gsm_send_sms(int fd, int argc, char *argv[])
11436 {
11437 /* gsm send sms <channel> <destination> <message> */
11438    int channel;
11439    struct zt_pvt *pvt = NULL;
11440    if (argc < 6) {
11441       return RESULT_SHOWUSAGE;
11442    }
11443    channel = atoi(argv[3]);
11444    if (channel < 1) {
11445       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11446       return RESULT_SUCCESS;
11447    }
11448    pvt = iflist;
11449    while (pvt) {
11450        if (pvt->channel == channel) {
11451       if (pvt->owner) {
11452           ast_cli(fd, "Channel in use.\n");
11453           return RESULT_FAILURE;
11454       } else {
11455           ast_mutex_lock(&pvt->lock);
11456           gsm_sms_send_text(pvt->gsm.modul, argv[4], argv[5]);
11457           ast_mutex_unlock(&pvt->lock);
11458           return RESULT_SUCCESS;
11459       }
11460        }
11461        pvt = pvt->next;
11462    }
11463    
11464    return RESULT_SUCCESS;
11465 }
11466 
11467 static int zt_gsm_sendtext(struct ast_channel *chan, const char * dest, const char *text, int ispdu) {
11468      struct zt_pvt *pvt = NULL;
11469      char *c = NULL;
11470      pvt = chan->tech_pvt;
11471      
11472      if (!pvt) return -1;
11473      
11474      /* parse dialstring */
11475      c = strrchr(dest, '/');
11476      if (c)
11477    c++;
11478      else
11479    c = (char *)dest;
11480  
11481      ast_mutex_lock(&pvt->lock);
11482    if (ispdu) {
11483           gsm_sms_send_pdu(pvt->gsm.modul, (char *)text);
11484    } else {
11485           gsm_sms_send_text(pvt->gsm.modul, c, (char *)text);
11486    }
11487      ast_mutex_unlock(&pvt->lock);
11488      gsm_wait(pvt->gsm.modul);
11489      return 0;
11490 }
11491  
11492 static struct ast_cli_entry gsm_send_sms = {
11493    { "gsm", "send", "sms", NULL }, handle_gsm_send_sms, "Sends a SM on a GSM channel", gsm_send_sms_help, complete_span_4 };
11494 
11495 static char gsm_show_status_help[] = 
11496    "Usage: gsm show status <channel>>\n"
11497    "       Displays status information about the GSM channel.\n";
11498 
11499 
11500 static int handle_gsm_show_status(int fd, int argc, char *argv[])
11501 {
11502    int channel;
11503    struct zt_pvt *pvt = NULL;
11504    if (argc < 4) {
11505       return RESULT_SHOWUSAGE;
11506    }
11507    channel = atoi(argv[3]);
11508    if (channel < 1) {
11509       ast_cli(fd, "Invalid channel %s.  Should be a number.\n", argv[3]);
11510       return RESULT_SUCCESS;
11511    }
11512    pvt = iflist;
11513    while (pvt) {
11514        if (pvt->channel == channel) {
11515       if (pvt->owner) {
11516           ast_cli(fd, "Channel in use.\n");
11517           return RESULT_FAILURE;
11518       } else {
11519           ast_mutex_lock(&pvt->lock);
11520           gsm_request_status(pvt->gsm.modul);
11521           ast_mutex_unlock(&pvt->lock);
11522           return RESULT_SUCCESS;
11523       }
11524        }
11525        pvt = pvt->next;
11526    }
11527    
11528    return RESULT_SUCCESS;
11529 }
11530 
11531 static struct ast_cli_entry gsm_show_status = {
11532    { "gsm", "show", "status", NULL }, handle_gsm_show_status, "Displays status information about the GSM channel.", gsm_show_status_help, complete_span_4 };
11533 
11534 #endif /* HAVE_GSMAT */
11535 
11536 static int app_zapEC(struct ast_channel *chan, void *data)
11537 {
11538  int res=-1;
11539  struct zt_pvt *p = NULL;
11540 
11541  if (!data) {
11542    ast_log(LOG_WARNING, "zapEC requires one argument (on | off)\n");
11543  }
11544  if (chan && !strcasecmp("ZAP",chan->tech->type)) {
11545    p = chan->tech_pvt;
11546    if (!p) return res;
11547    if (!strcasecmp("on",(char *)data)) {
11548        zt_enable_ec(p);
11549        res = 0;
11550        if (option_verbose > 3) {
11551       ast_verbose(VERBOSE_PREFIX_3 "Enabled echo cancelation on channel %s.\n", chan->name);
11552        }
11553    } else if (!strcasecmp("off",(char *)data)) {
11554        zt_disable_ec(p);
11555        res = 0;
11556        if (option_verbose > 3) {
11557       ast_verbose(VERBOSE_PREFIX_3 "Disabled echo cancelation on channel %s.\n", chan->name);
11558        }
11559    } else {
11560        ast_log(LOG_WARNING, "Unknown argument %s to zapEC\n", (char *)data);
11561    }
11562  } else {
11563   ast_log(LOG_WARNING, "zapNoEC only works on ZAP channels, check your extensions.conf!\n");
11564   res = 0;
11565  }
11566 
11567  return res;
11568 }
11569 
11570 static char *zapEC_tdesc = "Enable/disable Echo cancelation";
11571 static char *zapEC_app = "zapEC";
11572 static char *zapEC_synopsis = "Enable/Disable Echo Cancelation on a Zap channel";
11573 
11574 static int zap_destroy_channel(int fd, int argc, char **argv)
11575 {
11576    int channel;
11577    
11578    if (argc != 4)
11579       return RESULT_SHOWUSAGE;
11580    
11581    channel = atoi(argv[3]);
11582 
11583    return zap_destroy_channel_bynum(channel);
11584 }
11585 
11586 static int setup_zap(int reload);
11587 static int zap_restart(void)
11588 {
11589    if (option_verbose > 0)
11590       ast_verbose(VERBOSE_PREFIX_1 "Destroying channels and reloading zaptel configuration.\n");
11591    while (iflist) {
11592       if (option_debug)
11593          ast_log(LOG_DEBUG, "Destroying zaptel channel no. %d\n", iflist->channel);
11594       /* Also updates iflist: */
11595       destroy_channel(NULL, iflist, 1);
11596    }
11597    if (option_debug)
11598       ast_log(LOG_DEBUG, "Channels destroyed. Now re-reading config.\n");
11599    if (setup_zap(0) != 0) {
11600       ast_log(LOG_WARNING, "Reload channels from zap config failed!\n");
11601       return 1;
11602    }
11603    return 0;
11604 }
11605 
11606 static int zap_restart_cmd(int fd, int argc, char **argv)
11607 {
11608    if (argc != 2) {
11609       return RESULT_SHOWUSAGE;
11610    }
11611 
11612    if (zap_restart() != 0)
11613       return RESULT_FAILURE;
11614    return RESULT_SUCCESS;
11615 }
11616 
11617 static int action_zaprestart(struct mansession *s, const struct message *m)
11618 {
11619    if (zap_restart() != 0) {
11620       astman_send_error(s, m, "Failed rereading zaptel configuration");
11621       return 1;
11622    }
11623    astman_send_ack(s, m, "ZapRestart: Success");
11624    return 0;
11625 }
11626 
11627 static int zap_show_channels(int fd, int argc, char **argv)
11628 {
11629 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11630 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
11631    struct zt_pvt *tmp = NULL;
11632    char tmps[20] = "";
11633    ast_mutex_t *lock;
11634    struct zt_pvt *start;
11635 #ifdef HAVE_PRI
11636    int trunkgroup;
11637    struct zt_pri *pri = NULL;
11638    int x;
11639 #endif
11640 
11641    lock = &iflock;
11642    start = iflist;
11643 
11644 #ifdef HAVE_PRI
11645    if (argc == 4) {
11646       if ((trunkgroup = atoi(argv[3])) < 1)
11647          return RESULT_SHOWUSAGE;
11648       for (x = 0; x < NUM_SPANS; x++) {
11649          if (pris[x].trunkgroup == trunkgroup) {
11650             pri = pris + x;
11651             break;
11652          }
11653       }
11654       if (pri) {
11655          start = pri->crvs;
11656          lock = &pri->lock;
11657       } else {
11658          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11659          return RESULT_FAILURE;
11660       }
11661    } else
11662 #endif
11663    if (argc != 3)
11664       return RESULT_SHOWUSAGE;
11665 
11666    ast_mutex_lock(lock);
11667 #ifdef HAVE_PRI
11668    ast_cli(fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
11669 #else
11670    ast_cli(fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret");
11671 #endif   
11672    
11673    tmp = start;
11674    while (tmp) {
11675       if (tmp->channel > 0) {
11676          snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
11677       } else
11678          ast_copy_string(tmps, "pseudo", sizeof(tmps));
11679       ast_cli(fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret);
11680       tmp = tmp->next;
11681    }
11682    ast_mutex_unlock(lock);
11683    return RESULT_SUCCESS;
11684 #undef FORMAT
11685 #undef FORMAT2
11686 }
11687 
11688 static int zap_show_channel(int fd, int argc, char **argv)
11689 {
11690    int channel;
11691    struct zt_pvt *tmp = NULL;
11692    ZT_CONFINFO ci;
11693    ZT_PARAMS ps;
11694    int x;
11695    ast_mutex_t *lock;
11696    struct zt_pvt *start;
11697 #ifdef HAVE_PRI
11698    char *c;
11699    int trunkgroup;
11700    struct zt_pri *pri=NULL;
11701 #endif
11702 
11703    lock = &iflock;
11704    start = iflist;
11705 
11706    if (argc != 4)
11707       return RESULT_SHOWUSAGE;
11708 #ifdef HAVE_PRI
11709    if ((c = strchr(argv[3], ':'))) {
11710       if (sscanf(argv[3], "%d:%d", &trunkgroup, &channel) != 2)
11711          return RESULT_SHOWUSAGE;
11712       if ((trunkgroup < 1) || (channel < 1))
11713          return RESULT_SHOWUSAGE;
11714       for (x = 0; x < NUM_SPANS; x++) {
11715          if (pris[x].trunkgroup == trunkgroup) {
11716             pri = pris + x;
11717             break;
11718          }
11719       }
11720       if (pri) {
11721          start = pri->crvs;
11722          lock = &pri->lock;
11723       } else {
11724          ast_cli(fd, "No such trunk group %d\n", trunkgroup);
11725          return RESULT_FAILURE;
11726       }
11727    } else
11728 #endif
11729       channel = atoi(argv[3]);
11730 
11731    ast_mutex_lock(lock);
11732    tmp = start;
11733    while (tmp) {
11734       if (tmp->channel == channel) {
11735 #ifdef HAVE_PRI
11736          if (pri) 
11737             ast_cli(fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
11738          else
11739 #endif         
11740          ast_cli(fd, "Channel: %d\n", tmp->channel);
11741          ast_cli(fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].zfd);
11742          ast_cli(fd, "Span: %d\n", tmp->span);
11743          ast_cli(fd, "Extension: %s\n", tmp->exten);
11744          ast_cli(fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
11745          ast_cli(fd, "Context: %s\n", tmp->context);
11746          ast_cli(fd, "Caller ID: %s\n", tmp->cid_num);
11747          ast_cli(fd, "Calling TON: %d\n", tmp->cid_ton);
11748          ast_cli(fd, "Caller ID name: %s\n", tmp->cid_name);
11749          ast_cli(fd, "Destroy: %d\n", tmp->destroy);
11750          ast_cli(fd, "InAlarm: %d\n", tmp->inalarm);
11751          ast_cli(fd, "Signalling Type: %s\n", sig2str(tmp->sig));
11752          ast_cli(fd, "Radio: %d\n", tmp->radio);
11753          ast_cli(fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
11754          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)" : "");
11755          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)" : "");
11756          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)" : "");
11757          ast_cli(fd, "Confno: %d\n", tmp->confno);
11758          ast_cli(fd, "Propagated Conference: %d\n", tmp->propconfno);
11759          ast_cli(fd, "Real in conference: %d\n", tmp->inconference);
11760          ast_cli(fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
11761          ast_cli(fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
11762          ast_cli(fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
11763          ast_cli(fd, "Default law: %s\n", tmp->law == ZT_LAW_MULAW ? "ulaw" : tmp->law == ZT_LAW_ALAW ? "alaw" : "unknown");
11764          ast_cli(fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
11765          ast_cli(fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
11766          ast_cli(fd, "Echo Cancellation: %d taps%s, currently %s\n", tmp->echocancel, tmp->echocanbridged ? "" : " unless TDM bridged", tmp->echocanon ? "ON" : "OFF");
11767          if (tmp->master)
11768             ast_cli(fd, "Master Channel: %d\n", tmp->master->channel);
11769          for (x = 0; x < MAX_SLAVES; x++) {
11770             if (tmp->slaves[x])
11771                ast_cli(fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
11772          }
11773 #ifdef HAVE_PRI
11774          if (tmp->pri) {
11775             ast_cli(fd, "PRI Flags: ");
11776             if (tmp->resetting)
11777                ast_cli(fd, "Resetting ");
11778             if (tmp->call)
11779                ast_cli(fd, "Call ");
11780             if (tmp->bearer)
11781                ast_cli(fd, "Bearer ");
11782             ast_cli(fd, "\n");
11783             if (tmp->logicalspan) 
11784                ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
11785             else
11786                ast_cli(fd, "PRI Logical Span: Implicit\n");
11787          }
11788             
11789 #endif
11790          memset(&ci, 0, sizeof(ci));
11791          ps.channo = tmp->channel;
11792          if (tmp->subs[SUB_REAL].zfd > -1) {
11793             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONF, &ci)) {
11794                ast_cli(fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
11795             }
11796 #ifdef ZT_GETCONFMUTE
11797             if (!ioctl(tmp->subs[SUB_REAL].zfd, ZT_GETCONFMUTE, &x)) {
11798                ast_cli(fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
11799             }
11800 #endif
11801             if (ioctl(tmp->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps) < 0) {
11802                ast_log(LOG_WARNING, "Failed to get parameters on channel %d\n", tmp->channel);
11803             } else {
11804                ast_cli(fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
11805             }
11806          }
11807          ast_mutex_unlock(lock);
11808          return RESULT_SUCCESS;
11809       }
11810       tmp = tmp->next;
11811    }
11812    
11813    ast_cli(fd, "Unable to find given channel %d\n", channel);
11814    ast_mutex_unlock(lock);
11815    return RESULT_FAILURE;
11816 }
11817 
11818 static char zap_show_cadences_help[] =
11819 "Usage: zap show cadences\n"
11820 "       Shows all cadences currently defined\n";
11821 
11822 static int handle_zap_show_cadences(int fd, int argc, char *argv[])
11823 {
11824    int i, j;
11825    for (i = 0; i < num_cadence; i++) {
11826       char output[1024];
11827       char tmp[16], tmp2[64];
11828       snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
11829       term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
11830 
11831       for (j = 0; j < 16; j++) {
11832          if (cadences[i].ringcadence[j] == 0)
11833             break;
11834          snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
11835          if (cidrings[i] * 2 - 1 == j)
11836             term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
11837          else
11838             term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
11839          if (j != 0)
11840             strncat(output, ",", sizeof(output) - strlen(output) - 1);
11841          strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
11842       }
11843       ast_cli(fd,"%s\n",output);
11844    }
11845    return 0;
11846 }
11847 
11848 /* Based on irqmiss.c */
11849 static int zap_show_status(int fd, int argc, char *argv[]) {
11850    #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
11851    #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
11852 
11853    int span;
11854    int res;
11855    char alarms[50];
11856 
11857    int ctl;
11858    ZT_SPANINFO s;
11859 
11860    ctl = open("/dev/zap/ctl", O_RDWR);
11861    if (ctl < 0) {
11862       ast_log(LOG_WARNING, "Unable to open /dev/zap/ctl: %s\n", strerror(errno));
11863       ast_cli(fd, "No Zaptel interface found.\n");
11864       return RESULT_FAILURE;
11865    }
11866    ast_cli(fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
11867 
11868    for (span = 1; span < ZT_MAX_SPANS; ++span) {
11869       s.spanno = span;
11870       res = ioctl(ctl, ZT_SPANSTAT, &s);
11871       if (res) {
11872          continue;
11873       }
11874       alarms[0] = '\0';
11875       if (s.alarms > 0) {
11876          if (s.alarms & ZT_ALARM_BLUE)
11877             strcat(alarms, "BLU/");
11878          if (s.alarms & ZT_ALARM_YELLOW)
11879             strcat(alarms, "YEL/");
11880          if (s.alarms & ZT_ALARM_RED)
11881             strcat(alarms, "RED/");
11882          if (s.alarms & ZT_ALARM_LOOPBACK)
11883             strcat(alarms, "LB/");
11884          if (s.alarms & ZT_ALARM_RECOVER)
11885             strcat(alarms, "REC/");
11886          if (s.alarms & ZT_ALARM_NOTOPEN)
11887             strcat(alarms, "NOP/");
11888          if (!strlen(alarms))
11889             strcat(alarms, "UUU/");
11890          if (strlen(alarms)) {
11891             /* Strip trailing / */
11892             alarms[strlen(alarms) - 1] = '\0';
11893          }
11894       } else {
11895          if (s.numchans)
11896             strcpy(alarms, "OK");
11897          else
11898             strcpy(alarms, "UNCONFIGURED");
11899       }
11900 
11901       ast_cli(fd, FORMAT, s.desc, alarms, s.irqmisses, s.bpvcount, s.crc4count);
11902    }
11903    close(ctl);
11904 
11905    return RESULT_SUCCESS;
11906 #undef FORMAT
11907 #undef FORMAT2
11908 }
11909 
11910 static char show_channels_usage[] =
11911    "Usage: zap show channels\n"
11912    "  Shows a list of available channels\n";
11913 
11914 static char show_channel_usage[] =
11915    "Usage: zap show channel <chan num>\n"
11916    "  Detailed information about a given channel\n";
11917 
11918 static char zap_show_status_usage[] =
11919    "Usage: zap show status\n"
11920    "       Shows a list of Zaptel cards with status\n";
11921 
11922 static char destroy_channel_usage[] =
11923    "Usage: zap destroy channel <chan num>\n"
11924    "  DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.  Immediately removes a given channel, whether it is in use or not\n";
11925 
11926 static char zap_restart_usage[] =
11927    "Usage: zap restart\n"
11928    "  Restarts the zaptel channels: destroys them all and then\n"
11929    "  re-reads them from zapata.conf.\n"
11930    "  Note that this will STOP any running CALL on zaptel channels.\n"
11931    "";
11932 
11933 static struct ast_cli_entry zap_cli[] = {
11934    { { "zap", "show", "cadences", NULL },
11935    handle_zap_show_cadences, "List cadences",
11936    zap_show_cadences_help },
11937 
11938    { { "zap", "show", "channels", NULL},
11939    zap_show_channels, "Show active zapata channels",
11940    show_channels_usage },
11941 
11942    { { "zap", "show", "channel", NULL},
11943    zap_show_channel, "Show information on a channel",
11944    show_channel_usage },
11945 
11946    { { "zap", "destroy", "channel", NULL},
11947    zap_destroy_channel, "Destroy a channel",
11948    destroy_channel_usage },
11949 
11950    { { "zap", "restart", NULL},
11951    zap_restart_cmd, "Fully restart zaptel channels",
11952    zap_restart_usage },
11953 
11954    { { "zap", "show", "status", NULL},
11955    zap_show_status, "Show all Zaptel cards status",
11956    zap_show_status_usage },
11957 };
11958 
11959 #define TRANSFER  0
11960 #define HANGUP    1
11961 
11962 static int zap_fake_event(struct zt_pvt *p, int mode)
11963 {
11964    if (p) {
11965       switch (mode) {
11966          case TRANSFER:
11967             p->fake_event = ZT_EVENT_WINKFLASH;
11968             break;
11969          case HANGUP:
11970             p->fake_event = ZT_EVENT_ONHOOK;
11971             break;
11972          default:
11973             ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);   
11974       }
11975    }
11976    return 0;
11977 }
11978 static struct zt_pvt *find_channel(int channel)
11979 {
11980    struct zt_pvt *p = iflist;
11981    while (p) {
11982       if (p->channel == channel) {
11983          break;
11984       }
11985       p = p->next;
11986    }
11987    return p;
11988 }
11989 
11990 static int action_zapdndon(struct mansession *s, const struct message *m)
11991 {
11992    struct zt_pvt *p = NULL;
11993    const char *channel = astman_get_header(m, "ZapChannel");
11994 
11995    if (ast_strlen_zero(channel)) {
11996       astman_send_error(s, m, "No channel specified");
11997       return 0;
11998    }
11999    p = find_channel(atoi(channel));
12000    if (!p) {
12001       astman_send_error(s, m, "No such channel");
12002       return 0;
12003    }
12004    p->dnd = 1;
12005    astman_send_ack(s, m, "DND Enabled");
12006    return 0;
12007 }
12008 
12009 static int action_zapdndoff(struct mansession *s, const struct message *m)
12010 {
12011    struct zt_pvt *p = NULL;
12012    const char *channel = astman_get_header(m, "ZapChannel");
12013 
12014    if (ast_strlen_zero(channel)) {
12015       astman_send_error(s, m, "No channel specified");
12016       return 0;
12017    }
12018    p = find_channel(atoi(channel));
12019    if (!p) {
12020       astman_send_error(s, m, "No such channel");
12021       return 0;
12022    }
12023    p->dnd = 0;
12024    astman_send_ack(s, m, "DND Disabled");
12025    return 0;
12026 }
12027 
12028 static int action_transfer(struct mansession *s, const struct message *m)
12029 {
12030    struct zt_pvt *p = NULL;
12031    const char *channel = astman_get_header(m, "ZapChannel");
12032 
12033    if (ast_strlen_zero(channel)) {
12034       astman_send_error(s, m, "No channel specified");
12035       return 0;
12036    }
12037    p = find_channel(atoi(channel));
12038    if (!p) {
12039       astman_send_error(s, m, "No such channel");
12040       return 0;
12041    }
12042    zap_fake_event(p,TRANSFER);
12043    astman_send_ack(s, m, "ZapTransfer");
12044    return 0;
12045 }
12046 
12047 static int action_transferhangup(struct mansession *s, const struct message *m)
12048 {
12049    struct zt_pvt *p = NULL;
12050    const char *channel = astman_get_header(m, "ZapChannel");
12051 
12052    if (ast_strlen_zero(channel)) {
12053       astman_send_error(s, m, "No channel specified");
12054       return 0;
12055    }
12056    p = find_channel(atoi(channel));
12057    if (!p) {
12058       astman_send_error(s, m, "No such channel");
12059       return 0;
12060    }
12061    zap_fake_event(p,HANGUP);
12062    astman_send_ack(s, m, "ZapHangup");
12063    return 0;
12064 }
12065 
12066 static int action_zapdialoffhook(struct mansession *s, const struct message *m)
12067 {
12068    struct zt_pvt *p = NULL;
12069    const char *channel = astman_get_header(m, "ZapChannel");
12070    const char *number = astman_get_header(m, "Number");
12071    int i;
12072 
12073    if (ast_strlen_zero(channel)) {
12074       astman_send_error(s, m, "No channel specified");
12075       return 0;
12076    }
12077    if (ast_strlen_zero(number)) {
12078       astman_send_error(s, m, "No number specified");
12079       return 0;
12080    }
12081    p = find_channel(atoi(channel));
12082    if (!p) {
12083       astman_send_error(s, m, "No such channel");
12084       return 0;
12085    }
12086    if (!p->owner) {
12087       astman_send_error(s, m, "Channel does not have it's owner");
12088       return 0;
12089    }
12090    for (i = 0; i < strlen(number); i++) {
12091       struct ast_frame f = { AST_FRAME_DTMF, number[i] };
12092       zap_queue_frame(p, &f, NULL); 
12093    }
12094    astman_send_ack(s, m, "ZapDialOffhook");
12095    return 0;
12096 }
12097 
12098 static int action_zapshowchannels(struct mansession *s, const struct message *m)
12099 {
12100    struct zt_pvt *tmp = NULL;
12101    const char *id = astman_get_header(m, "ActionID");
12102    char idText[256] = "";
12103 
12104    astman_send_ack(s, m, "Zapata channel status will follow");
12105    if (!ast_strlen_zero(id))
12106       snprintf(idText, sizeof(idText) - 1, "ActionID: %s\r\n", id);
12107 
12108    ast_mutex_lock(&iflock);
12109    
12110    tmp = iflist;
12111    while (tmp) {
12112       if (tmp->channel > 0) {
12113          int alarm = get_alarms(tmp);
12114          astman_append(s,
12115             "Event: ZapShowChannels\r\n"
12116             "Channel: %d\r\n"
12117             "Signalling: %s\r\n"
12118             "Context: %s\r\n"
12119             "DND: %s\r\n"
12120             "Alarm: %s\r\n"
12121             "%s"
12122             "\r\n",
12123             tmp->channel, sig2str(tmp->sig), tmp->context, 
12124             tmp->dnd ? "Enabled" : "Disabled",
12125             alarm2str(alarm), idText);
12126       } 
12127 
12128       tmp = tmp->next;
12129    }
12130 
12131    ast_mutex_unlock(&iflock);
12132    
12133    astman_append(s, 
12134       "Event: ZapShowChannelsComplete\r\n"
12135       "%s"
12136       "\r\n", 
12137       idText);
12138    return 0;
12139 }
12140 
12141 static int __unload_module(void)
12142 {
12143    int x;
12144    struct zt_pvt *p, *pl;
12145 
12146 #ifdef HAVE_PRI
12147    int i;
12148    for (i = 0; i < NUM_SPANS; i++) {
12149       if (pris[i].master != AST_PTHREADT_NULL) 
12150          pthread_cancel(pris[i].master);
12151    }
12152    ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
12153    ast_unregister_application(zap_send_keypad_facility_app);
12154    ast_unregister_application(zapCD_app);
12155    ast_unregister_application(zapInband_app);
12156 #endif
12157 #ifdef HAVE_GSMAT
12158    ast_cli_unregister_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
12159    ast_cli_unregister(&gsm_send_sms);
12160    ast_cli_unregister(&gsm_send_pdu);
12161    ast_cli_unregister(&gsm_show_status);
12162 #endif
12163    ast_cli_unregister_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
12164    ast_unregister_application(zapEC_app);
12165    ast_manager_unregister( "ZapDialOffhook" );
12166    ast_manager_unregister( "ZapHangup" );
12167    ast_manager_unregister( "ZapTransfer" );
12168    ast_manager_unregister( "ZapDNDoff" );
12169    ast_manager_unregister( "ZapDNDon" );
12170    ast_manager_unregister("ZapShowChannels");
12171    ast_manager_unregister("ZapRestart");
12172    ast_channel_unregister(&zap_tech);
12173    ast_mutex_lock(&iflock);
12174    /* Hangup all interfaces if they have an owner */
12175    p = iflist;
12176    while (p) {
12177       if (p->owner)
12178          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
12179       p = p->next;
12180    }
12181    ast_mutex_unlock(&iflock);
12182    ast_mutex_lock(&monlock);
12183    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
12184       pthread_cancel(monitor_thread);
12185       pthread_kill(monitor_thread, SIGURG);
12186       pthread_join(monitor_thread, NULL);
12187    }
12188    monitor_thread = AST_PTHREADT_STOP;
12189    ast_mutex_unlock(&monlock);
12190 
12191    ast_mutex_lock(&iflock);
12192    /* Destroy all the interfaces and free their memory */
12193    p = iflist;
12194    while (p) {
12195       /* Free any callerid */
12196       if (p->cidspill)
12197          free(p->cidspill);
12198       /* Close the zapata thingy */
12199       if (p->subs[SUB_REAL].zfd > -1)
12200          zt_close(p->subs[SUB_REAL].zfd);
12201       pl = p;
12202       p = p->next;
12203       x = pl->channel;
12204       /* Free associated memory */
12205       if (pl)
12206          destroy_zt_pvt(&pl);
12207       ast_verbose(VERBOSE_PREFIX_3 "Unregistered channel %d\n", x);
12208    }
12209    iflist = NULL;
12210    ifcount = 0;
12211    ast_mutex_unlock(&iflock);
12212 #ifdef HAVE_PRI      
12213    for (i = 0; i < NUM_SPANS; i++) {
12214       if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
12215          pthread_join(pris[i].master, NULL);
12216       zt_close(pris[i].fds[i]);
12217    }
12218 #endif
12219    return 0;
12220 }
12221 
12222 static int unload_module(void)
12223 {
12224 #ifdef HAVE_PRI      
12225    int y;
12226    for (y = 0; y < NUM_SPANS; y++)
12227       ast_mutex_destroy(&pris[y].lock);
12228 #endif
12229    return __unload_module();
12230 }
12231 
12232 static int build_channels(struct zt_chan_conf conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
12233 {
12234    char *c, *chan;
12235    int x, start, finish;
12236    struct zt_pvt *tmp;
12237 #ifdef HAVE_PRI
12238    struct zt_pri *pri;
12239    int trunkgroup, y;
12240 #endif
12241    
12242    if ((reload == 0) && (conf.chan.sig < 0)) {
12243       ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
12244       return -1;
12245    }
12246 
12247    c = ast_strdupa(value);
12248 
12249 #ifdef HAVE_PRI
12250    pri = NULL;
12251    if (iscrv) {
12252       if (sscanf(c, "%d:%n", &trunkgroup, &y) != 1) {
12253          ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno);
12254          return -1;
12255       }
12256       if (trunkgroup < 1) {
12257          ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d\n", lineno);
12258          return -1;
12259       }
12260       c += y;
12261       for (y = 0; y < NUM_SPANS; y++) {
12262          if (pris[y].trunkgroup == trunkgroup) {
12263             pri = pris + y;
12264             break;
12265          }
12266       }
12267       if (!pri) {
12268          ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup, lineno);
12269          return -1;
12270       }
12271    }
12272 #endif         
12273 
12274    while ((chan = strsep(&c, ","))) {
12275       if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
12276          /* Range */
12277       } else if (sscanf(chan, "%d", &start)) {
12278          /* Just one */
12279          finish = start;
12280       } else if (!strcasecmp(chan, "pseudo")) {
12281          finish = start = CHAN_PSEUDO;
12282          if (found_pseudo)
12283             *found_pseudo = 1;
12284       } else {
12285          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
12286          return -1;
12287       }
12288       if (finish < start) {
12289          ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
12290          x = finish;
12291          finish = start;
12292          start = x;
12293       }
12294 
12295       for (x = start; x <= finish; x++) {
12296 #ifdef HAVE_PRI
12297          tmp = mkintf(x, conf, pri, reload);
12298 #else       
12299          tmp = mkintf(x, conf, NULL, reload);
12300 #endif         
12301 
12302          if (tmp) {
12303             if (option_verbose > 2) {
12304 #ifdef HAVE_PRI
12305                if (pri)
12306                   ast_verbose(VERBOSE_PREFIX_3 "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
12307                else
12308 #endif
12309                   ast_verbose(VERBOSE_PREFIX_3 "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
12310             }
12311          } else {
12312             ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
12313                (reload == 1) ? "reconfigure" : "register", value);
12314             return -1;
12315          }
12316       }
12317    }
12318 
12319    return 0;
12320 }
12321 
12322 /** The length of the parameters list of 'zapchan'. 
12323  * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
12324 #define MAX_CHANLIST_LEN 80
12325 static int process_zap(struct zt_chan_conf *confp, struct ast_variable *v, int reload, int skipchannels)
12326 {
12327    struct zt_pvt *tmp;
12328    char *ringc; /* temporary string for parsing the dring number. */
12329    int y;
12330    int found_pseudo = 0;
12331         char zapchan[MAX_CHANLIST_LEN] = {};
12332 
12333    for (; v; v = v->next) {
12334       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
12335          continue;
12336 
12337       /* Create the interface list */
12338       if (!strcasecmp(v->name, "channel")
12339 #ifdef HAVE_PRI
12340           || !strcasecmp(v->name, "crv")
12341 #endif         
12342          ) {
12343          int iscrv;
12344          if (skipchannels)
12345             continue;
12346          iscrv = !strcasecmp(v->name, "crv");
12347          if (build_channels(*confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
12348                return -1;
12349       } else if (!strcasecmp(v->name, "zapchan")) {
12350          ast_copy_string(zapchan, v->value, sizeof(zapchan));
12351       } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
12352          if (ast_true(v->value))
12353             confp->chan.usedistinctiveringdetection = 1;
12354       } else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
12355          if (ast_true(v->value))
12356             distinctiveringaftercid = 1;
12357       } else if (!strcasecmp(v->name, "dring1context")) {
12358          ast_copy_string(drings.ringContext[0].contextData, v->value, sizeof(drings.ringContext[0].contextData));
12359       } else if (!strcasecmp(v->name, "dring2context")) {
12360          ast_copy_string(drings.ringContext[1].contextData, v->value, sizeof(drings.ringContext[1].contextData));
12361       } else if (!strcasecmp(v->name, "dring3context")) {
12362          ast_copy_string(drings.ringContext[2].contextData, v->value, sizeof(drings.ringContext[2].contextData));
12363       } else if (!strcasecmp(v->name, "dring1")) {
12364          ringc = v->value;
12365          sscanf(ringc, "%d,%d,%d", &drings.ringnum[0].ring[0], &drings.ringnum[0].ring[1], &drings.ringnum[0].ring[2]);
12366       } else if (!strcasecmp(v->name, "dring2")) {
12367          ringc = v->value;
12368          sscanf(ringc, "%d,%d,%d", &drings.ringnum[1].ring[0], &drings.ringnum[1].ring[1], &drings.ringnum[1].ring[2]);
12369       } else if (!strcasecmp(v->name, "dring3")) {
12370          ringc = v->value;
12371          sscanf(ringc, "%d,%d,%d", &drings.ringnum[2].ring[0], &drings.ringnum[2].ring[1], &drings.ringnum[2].ring[2]);
12372       } else if (!strcasecmp(v->name, "usecallerid")) {
12373          confp->chan.use_callerid = ast_true(v->value);
12374       } else if (!strcasecmp(v->name, "cidsignalling")) {
12375          if (!strcasecmp(v->value, "bell"))
12376             confp->chan.cid_signalling = CID_SIG_BELL;
12377          else if (!strcasecmp(v->value, "v23"))
12378             confp->chan.cid_signalling = CID_SIG_V23;
12379          else if (!strcasecmp(v->value, "dtmf"))
12380             confp->chan.cid_signalling = CID_SIG_DTMF;
12381          else if (!strcasecmp(v->value, "smdi"))
12382             confp->chan.cid_signalling = CID_SIG_SMDI;
12383          else if (!strcasecmp(v->value, "v23_jp"))
12384             confp->chan.cid_signalling = CID_SIG_V23_JP;
12385          else if (ast_true(v->value))
12386             confp->chan.cid_signalling = CID_SIG_BELL;
12387       } else if (!strcasecmp(v->name, "cidstart")) {
12388          if (!strcasecmp(v->value, "ring"))
12389             confp->chan.cid_start = CID_START_RING;
12390          else if (!strcasecmp(v->value, "polarity"))
12391             confp->chan.cid_start = CID_START_POLARITY;
12392          else if (ast_true(v->value))
12393             confp->chan.cid_start = CID_START_RING;
12394       } else if (!strcasecmp(v->name, "threewaycalling")) {
12395          confp->chan.threewaycalling = ast_true(v->value);
12396       } else if (!strcasecmp(v->name, "cancallforward")) {
12397          confp->chan.cancallforward = ast_true(v->value);
12398       } else if (!strcasecmp(v->name, "relaxdtmf")) {
12399          if (ast_true(v->value)) 
12400             confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
12401          else
12402             confp->chan.dtmfrelax = 0;
12403       } else if (!strcasecmp(v->name, "mailbox")) {
12404          ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
12405       } else if (!strcasecmp(v->name, "adsi")) {
12406          confp->chan.adsi = ast_true(v->value);
12407       } else if (!strcasecmp(v->name, "usesmdi")) {
12408          confp->chan.use_smdi = ast_true(v->value);
12409       } else if (!strcasecmp(v->name, "smdiport")) {
12410          ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
12411       } else if (!strcasecmp(v->name, "transfer")) {
12412          confp->chan.transfer = ast_true(v->value);
12413       } else if (!strcasecmp(v->name, "canpark")) {
12414          confp->chan.canpark = ast_true(v->value);
12415       } else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
12416          confp->chan.echocanbridged = ast_true(v->value);
12417       } else if (!strcasecmp(v->name, "busydetect")) {
12418          confp->chan.busydetect = ast_true(v->value);
12419       } else if (!strcasecmp(v->name, "busycount")) {
12420          confp->chan.busycount = atoi(v->value);
12421       } else if (!strcasecmp(v->name, "busypattern")) {
12422          if (sscanf(v->value, "%d,%d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
12423             ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength\n");
12424          }
12425       } else if (!strcasecmp(v->name, "callprogress")) {
12426          if (ast_true(v->value))
12427             confp->chan.callprogress |= 1;
12428          else
12429             confp->chan.callprogress &= ~1;
12430       } else if (!strcasecmp(v->name, "faxdetect")) {
12431          if (!strcasecmp(v->value, "incoming")) {
12432             confp->chan.callprogress |= 4;
12433             confp->chan.callprogress &= ~2;
12434          } else if (!strcasecmp(v->value, "outgoing")) {
12435             confp->chan.callprogress &= ~4;
12436             confp->chan.callprogress |= 2;
12437          } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
12438             confp->chan.callprogress |= 6;
12439          else
12440             confp->chan.callprogress &= ~6;
12441       } else if (!strcasecmp(v->name, "echocancel")) {
12442          if (!ast_strlen_zero(v->value)) {
12443             y = atoi(v->value);
12444          } else
12445             y = 0;
12446          if ((y == 32) || (y == 64) || (y == 128) || (y == 256) || (y == 512) || (y == 1024))
12447             confp->chan.echocancel = y;
12448          else {
12449             confp->chan.echocancel = ast_true(v->value);
12450             if (confp->chan.echocancel)
12451                confp->chan.echocancel=128;
12452          }
12453       } else if (!strcasecmp(v->name, "echotraining")) {
12454          if (sscanf(v->value, "%d", &y) == 1) {
12455             if ((y < 10) || (y > 4000)) {
12456                ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v->lineno);              
12457             } else {
12458                confp->chan.echotraining = y;
12459             }
12460          } else if (ast_true(v->value)) {
12461             confp->chan.echotraining = 400;
12462          } else
12463             confp->chan.echotraining = 0;
12464       } else if (!strcasecmp(v->name, "hidecallerid")) {
12465          confp->chan.hidecallerid = ast_true(v->value);
12466       } else if (!strcasecmp(v->name, "hidecalleridname")) {
12467          confp->chan.hidecalleridname = ast_true(v->value);
12468       } else if (!strcasecmp(v->name, "pulsedial")) {
12469          confp->chan.pulse = ast_true(v->value);
12470       } else if (!strcasecmp(v->name, "callreturn")) {
12471          confp->chan.callreturn = ast_true(v->value);
12472       } else if (!strcasecmp(v->name, "callwaiting")) {
12473          confp->chan.callwaiting = ast_true(v->value);
12474       } else if (!strcasecmp(v->name, "callwaitingcallerid")) {
12475          confp->chan.callwaitingcallerid = ast_true(v->value);
12476       } else if (!strcasecmp(v->name, "context")) {
12477          ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
12478       } else if (!strcasecmp(v->name, "language")) {
12479          ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
12480       } else if (!strcasecmp(v->name, "progzone")) {
12481          ast_copy_string(progzone, v->value, sizeof(progzone));
12482       } else if (!strcasecmp(v->name, "mohinterpret") 
12483          ||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
12484          ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
12485       } else if (!strcasecmp(v->name, "mohsuggest")) {
12486          ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
12487       } else if (!strcasecmp(v->name, "stripmsd")) {
12488          confp->chan.stripmsd = atoi(v->value);
12489       } else if (!strcasecmp(v->name, "jitterbuffers")) {
12490          numbufs = atoi(v->value);
12491       } else if (!strcasecmp(v->name, "group")) {
12492          confp->chan.group = ast_get_group(v->value);
12493       } else if (!strcasecmp(v->name, "callgroup")) {
12494          confp->chan.callgroup = ast_get_group(v->value);
12495       } else if (!strcasecmp(v->name, "pickupgroup")) {
12496          confp->chan.pickupgroup = ast_get_group(v->value);
12497       } else if (!strcasecmp(v->name, "immediate")) {
12498          confp->chan.immediate = ast_true(v->value);
12499       } else if (!strcasecmp(v->name, "transfertobusy")) {
12500          confp->chan.transfertobusy = ast_true(v->value);
12501       } else if (!strcasecmp(v->name, "rxgain")) {
12502          if (sscanf(v->value, "%f", &confp->chan.rxgain) != 1) {
12503             ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
12504          }
12505       } else if (!strcasecmp(v->name, "txgain")) {
12506          if (sscanf(v->value, "%f", &confp->chan.txgain) != 1) {
12507             ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
12508          }
12509       } else if (!strcasecmp(v->name, "tonezone")) {
12510          if (sscanf(v->value, "%d", &confp->chan.tonezone) != 1) {
12511             ast_log(LOG_WARNING, "Invalid tonezone: %s\n", v->value);
12512          }
12513       } else if (!strcasecmp(v->name, "callerid")) {
12514          if (!strcasecmp(v->value, "asreceived")) {
12515             confp->chan.cid_num[0] = '\0';
12516             confp->chan.cid_name[0] = '\0';
12517          } else {
12518             ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
12519          } 
12520       } else if (!strcasecmp(v->name, "fullname")) {
12521          ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
12522       } else if (!strcasecmp(v->name, "cid_number")) {
12523          ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
12524       } else if (!strcasecmp(v->name, "useincomingcalleridonzaptransfer")) {
12525          confp->chan.zaptrcallerid = ast_true(v->value);
12526       } else if (!strcasecmp(v->name, "restrictcid")) {
12527          confp->chan.restrictcid = ast_true(v->value);
12528       } else if (!strcasecmp(v->name, "usecallingpres")) {
12529          confp->chan.use_callingpres = ast_true(v->value);
12530       } else if (!strcasecmp(v->name, "accountcode")) {
12531          ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
12532       } else if (!strcasecmp(v->name, "amaflags")) {
12533          y = ast_cdr_amaflags2int(v->value);
12534          if (y < 0) 
12535             ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno);
12536          else
12537             confp->chan.amaflags = y;
12538       } else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
12539          confp->chan.polarityonanswerdelay = atoi(v->value);
12540       } else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
12541          confp->chan.answeronpolarityswitch = ast_true(v->value);
12542       } else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
12543          confp->chan.hanguponpolarityswitch = ast_true(v->value);
12544       } else if (!strcasecmp(v->name, "sendcalleridafter")) {
12545          confp->chan.sendcalleridafter = atoi(v->value);
12546       } else if (!reload){ 
12547           if (!strcasecmp(v->name, "signalling")) {
12548             confp->chan.outsigmod = -1;
12549             if (!strcasecmp(v->value, "em")) {
12550                confp->chan.sig = SIG_EM;
12551             } else if (!strcasecmp(v->value, "em_e1")) {
12552                confp->chan.sig = SIG_EM_E1;
12553             } else if (!strcasecmp(v->value, "em_w")) {
12554                confp->chan.sig = SIG_EMWINK;
12555                confp->chan.radio = 0;
12556             } else if (!strcasecmp(v->value, "fxs_ls")) {
12557                confp->chan.sig = SIG_FXSLS;
12558                confp->chan.radio = 0;
12559             } else if (!strcasecmp(v->value, "fxs_gs")) {
12560                confp->chan.sig = SIG_FXSGS;
12561                confp->chan.radio = 0;
12562             } else if (!strcasecmp(v->value, "fxs_ks")) {
12563                confp->chan.sig = SIG_FXSKS;
12564                confp->chan.radio = 0;
12565             } else if (!strcasecmp(v->value, "fxo_ls")) {
12566                confp->chan.sig = SIG_FXOLS;
12567                confp->chan.radio = 0;
12568             } else if (!strcasecmp(v->value, "fxo_gs")) {
12569                confp->chan.sig = SIG_FXOGS;
12570                confp->chan.radio = 0;
12571             } else if (!strcasecmp(v->value, "fxo_ks")) {
12572                confp->chan.sig = SIG_FXOKS;
12573                confp->chan.radio = 0;
12574             } else if (!strcasecmp(v->value, "fxs_rx")) {
12575                confp->chan.sig = SIG_FXSKS;
12576                confp->chan.radio = 1;
12577             } else if (!strcasecmp(v->value, "fxo_rx")) {
12578                confp->chan.sig = SIG_FXOLS;
12579                confp->chan.radio = 1;
12580             } else if (!strcasecmp(v->value, "fxs_tx")) {
12581                confp->chan.sig = SIG_FXSLS;
12582                confp->chan.radio = 1;
12583             } else if (!strcasecmp(v->value, "fxo_tx")) {
12584                confp->chan.sig = SIG_FXOGS;
12585                confp->chan.radio = 1;
12586             } else if (!strcasecmp(v->value, "em_rx")) {
12587                confp->chan.sig = SIG_EM;
12588                confp->chan.radio = 1;
12589             } else if (!strcasecmp(v->value, "em_tx")) {
12590                confp->chan.sig = SIG_EM;
12591                confp->chan.radio = 1;
12592             } else if (!strcasecmp(v->value, "em_rxtx")) {
12593                confp->chan.sig = SIG_EM;
12594                confp->chan.radio = 2;
12595             } else if (!strcasecmp(v->value, "em_txrx")) {
12596                confp->chan.sig = SIG_EM;
12597                confp->chan.radio = 2;
12598             } else if (!strcasecmp(v->value, "sf")) {
12599                confp->chan.sig = SIG_SF;
12600                confp->chan.radio = 0;
12601             } else if (!strcasecmp(v->value, "sf_w")) {
12602                confp->chan.sig = SIG_SFWINK;
12603                confp->chan.radio = 0;
12604             } else if (!strcasecmp(v->value, "sf_featd")) {
12605                confp->chan.sig = SIG_FEATD;
12606                confp->chan.radio = 0;
12607             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12608                confp->chan.sig = SIG_FEATDMF;
12609                confp->chan.radio = 0;
12610             } else if (!strcasecmp(v->value, "sf_featb")) {
12611                confp->chan.sig = SIG_SF_FEATB;
12612                confp->chan.radio = 0;
12613             } else if (!strcasecmp(v->value, "sf")) {
12614                confp->chan.sig = SIG_SF;
12615                confp->chan.radio = 0;
12616             } else if (!strcasecmp(v->value, "sf_rx")) {
12617                confp->chan.sig = SIG_SF;
12618                confp->chan.radio = 1;
12619             } else if (!strcasecmp(v->value, "sf_tx")) {
12620                confp->chan.sig = SIG_SF;
12621                confp->chan.radio = 1;
12622             } else if (!strcasecmp(v->value, "sf_rxtx")) {
12623                confp->chan.sig = SIG_SF;
12624                confp->chan.radio = 2;
12625             } else if (!strcasecmp(v->value, "sf_txrx")) {
12626                confp->chan.sig = SIG_SF;
12627                confp->chan.radio = 2;
12628             } else if (!strcasecmp(v->value, "featd")) {
12629                confp->chan.sig = SIG_FEATD;
12630                confp->chan.radio = 0;
12631             } else if (!strcasecmp(v->value, "featdmf")) {
12632                confp->chan.sig = SIG_FEATDMF;
12633                confp->chan.radio = 0;
12634             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12635                confp->chan.sig = SIG_FEATDMF_TA;
12636                confp->chan.radio = 0;
12637             } else if (!strcasecmp(v->value, "e911")) {
12638                confp->chan.sig = SIG_E911;
12639                confp->chan.radio = 0;
12640             } else if (!strcasecmp(v->value, "fgccama")) {
12641                confp->chan.sig = SIG_FGC_CAMA;
12642                confp->chan.radio = 0;
12643             } else if (!strcasecmp(v->value, "fgccamamf")) {
12644                confp->chan.sig = SIG_FGC_CAMAMF;
12645                confp->chan.radio = 0;
12646             } else if (!strcasecmp(v->value, "featb")) {
12647                confp->chan.sig = SIG_FEATB;
12648                confp->chan.radio = 0;
12649 #ifdef HAVE_PRI
12650             } else if (!strcasecmp(v->value, "pri_net")) {
12651                confp->chan.radio = 0;
12652                confp->chan.sig = SIG_PRI;
12653                confp->pri.nodetype = PRI_NETWORK;
12654             } else if (!strcasecmp(v->value, "pri_cpe")) {
12655                confp->chan.sig = SIG_PRI;
12656                confp->chan.radio = 0;
12657                confp->pri.nodetype = PRI_CPE;
12658             } else if (!strcasecmp(v->value, "gr303fxoks_net")) {
12659                confp->chan.sig = SIG_GR303FXOKS;
12660                confp->chan.radio = 0;
12661                confp->pri.nodetype = PRI_NETWORK;
12662             } else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
12663                confp->chan.sig = SIG_GR303FXSKS;
12664                confp->chan.radio = 0;
12665                confp->pri.nodetype = PRI_CPE;
12666             } else if (!strcasecmp(v->value, "bri_net_ptmp")) {
12667                confp->chan.radio = 0;
12668                confp->chan.sig = SIG_PRI;
12669                confp->pri.nodetype = BRI_NETWORK_PTMP;
12670             } else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
12671                confp->chan.sig = SIG_PRI;
12672                confp->chan.radio = 0;
12673                confp->pri.nodetype = BRI_CPE_PTMP;
12674             } else if (!strcasecmp(v->value, "bri_net")) {
12675                confp->chan.radio = 0;
12676                confp->chan.sig = SIG_PRI;
12677                confp->pri.nodetype = BRI_NETWORK;
12678             } else if (!strcasecmp(v->value, "bri_cpe")) {
12679                confp->chan.sig = SIG_PRI;
12680                confp->chan.radio = 0;
12681                confp->pri.nodetype = BRI_CPE;
12682 #endif
12683 #ifdef HAVE_GSMAT
12684             } else if (!strcasecmp(v->value, "gsm")) {
12685                confp->chan.sig = SIG_GSM;
12686                confp->chan.radio = 0;
12687 #endif            
12688             } else {
12689                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12690             }
12691           } else if (!strcasecmp(v->name, "outsignalling")) {
12692             if (!strcasecmp(v->value, "em")) {
12693                confp->chan.outsigmod = SIG_EM;
12694             } else if (!strcasecmp(v->value, "em_e1")) {
12695                confp->chan.outsigmod = SIG_EM_E1;
12696             } else if (!strcasecmp(v->value, "em_w")) {
12697                confp->chan.outsigmod = SIG_EMWINK;
12698             } else if (!strcasecmp(v->value, "sf")) {
12699                confp->chan.outsigmod = SIG_SF;
12700             } else if (!strcasecmp(v->value, "sf_w")) {
12701                confp->chan.outsigmod = SIG_SFWINK;
12702             } else if (!strcasecmp(v->value, "sf_featd")) {
12703                confp->chan.outsigmod = SIG_FEATD;
12704             } else if (!strcasecmp(v->value, "sf_featdmf")) {
12705                confp->chan.outsigmod = SIG_FEATDMF;
12706             } else if (!strcasecmp(v->value, "sf_featb")) {
12707                confp->chan.outsigmod = SIG_SF_FEATB;
12708             } else if (!strcasecmp(v->value, "sf")) {
12709                confp->chan.outsigmod = SIG_SF;
12710             } else if (!strcasecmp(v->value, "featd")) {
12711                confp->chan.outsigmod = SIG_FEATD;
12712             } else if (!strcasecmp(v->value, "featdmf")) {
12713                confp->chan.outsigmod = SIG_FEATDMF;
12714             } else if (!strcasecmp(v->value, "featdmf_ta")) {
12715                confp->chan.outsigmod = SIG_FEATDMF_TA;
12716             } else if (!strcasecmp(v->value, "e911")) {
12717                confp->chan.outsigmod = SIG_E911;
12718             } else if (!strcasecmp(v->value, "fgccama")) {
12719                confp->chan.outsigmod = SIG_FGC_CAMA;
12720             } else if (!strcasecmp(v->value, "fgccamamf")) {
12721                confp->chan.outsigmod = SIG_FGC_CAMAMF;
12722             } else if (!strcasecmp(v->value, "featb")) {
12723                confp->chan.outsigmod = SIG_FEATB;
12724             } else {
12725                ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
12726             }
12727 #ifdef HAVE_PRI
12728          } else if (!strcasecmp(v->name, "pridialplan")) {
12729             if (!strcasecmp(v->value, "national")) {
12730                confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
12731             } else if (!strcasecmp(v->value, "unknown")) {
12732                confp->pri.dialplan = PRI_UNKNOWN + 1;
12733             } else if (!strcasecmp(v->value, "private")) {
12734                confp->pri.dialplan = PRI_PRIVATE + 1;
12735             } else if (!strcasecmp(v->value, "international")) {
12736                confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
12737             } else if (!strcasecmp(v->value, "local")) {
12738                confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
12739             } else if (!strcasecmp(v->value, "dynamic")) {
12740                confp->pri.dialplan = -1;
12741             } else {
12742                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12743             }
12744          } else if (!strcasecmp(v->name, "prilocaldialplan")) {
12745             if (!strcasecmp(v->value, "national")) {
12746                confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
12747             } else if (!strcasecmp(v->value, "unknown")) {
12748                confp->pri.localdialplan = PRI_UNKNOWN + 1;
12749             } else if (!strcasecmp(v->value, "private")) {
12750                confp->pri.localdialplan = PRI_PRIVATE + 1;
12751             } else if (!strcasecmp(v->value, "international")) {
12752                confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
12753             } else if (!strcasecmp(v->value, "local")) {
12754                confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
12755             } else if (!strcasecmp(v->value, "dynamic")) {
12756                confp->pri.localdialplan = -1;
12757             } else {
12758                ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
12759             }
12760          } else if (!strcasecmp(v->name, "switchtype")) {
12761             if (!strcasecmp(v->value, "national")) 
12762                confp->pri.switchtype = PRI_SWITCH_NI2;
12763             else if (!strcasecmp(v->value, "ni1"))
12764                confp->pri.switchtype = PRI_SWITCH_NI1;
12765             else if (!strcasecmp(v->value, "dms100"))
12766                confp->pri.switchtype = PRI_SWITCH_DMS100;
12767             else if (!strcasecmp(v->value, "4ess"))
12768                confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
12769             else if (!strcasecmp(v->value, "5ess"))
12770                confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
12771             else if (!strcasecmp(v->value, "euroisdn"))
12772                confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
12773             else if (!strcasecmp(v->value, "qsig"))
12774                confp->pri.switchtype = PRI_SWITCH_QSIG;
12775             else {
12776                ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
12777                return -1;
12778             }
12779          } else if (!strcasecmp(v->name, "nsf")) {
12780             if (!strcasecmp(v->value, "sdn"))
12781                confp->pri.nsf = PRI_NSF_SDN;
12782             else if (!strcasecmp(v->value, "megacom"))
12783                confp->pri.nsf = PRI_NSF_MEGACOM;
12784             else if (!strcasecmp(v->value, "tollfreemegacom"))
12785                confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;           
12786             else if (!strcasecmp(v->value, "accunet"))
12787                confp->pri.nsf = PRI_NSF_ACCUNET;
12788             else if (!strcasecmp(v->value, "none"))
12789                confp->pri.nsf = PRI_NSF_NONE;
12790             else {
12791                ast_log(LOG_WARNING, "Unknown network-specific facility '%s'\n", v->value);
12792                confp->pri.nsf = PRI_NSF_NONE;
12793             }
12794          } else if (!strcasecmp(v->name, "priindication")) {
12795             if (!strcasecmp(v->value, "outofband"))
12796                confp->chan.priindication_oob = 1;
12797             else if (!strcasecmp(v->value, "inband"))
12798                confp->chan.priindication_oob = 0;
12799             else if (!strcasecmp(v->value, "passthrough"))
12800                confp->chan.priindication_oob = 2;
12801             else
12802                ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband', 'outofband' or 'passthrough' at line %d\n",
12803                   v->value, v->lineno);
12804          } else if (!strcasecmp(v->name, "pritransfer")) {
12805             if (!strcasecmp(v->value, "no"))
12806                confp->chan.pritransfer = 0;
12807             else if (!strcasecmp(v->value, "ect"))
12808                confp->chan.pritransfer = 1;
12809             else if (!strcasecmp(v->value, "hangup"))
12810                confp->chan.pritransfer = 2;
12811             else
12812                ast_log(LOG_WARNING, "'%s' is not a valid pri transfer value, should be 'no' , 'ect' or 'hangup' at line %d\n",
12813                   v->value, v->lineno);
12814          } else if (!strcasecmp(v->name, "priexclusive")) {
12815             confp->chan.priexclusive = ast_true(v->value);
12816          } else if (!strcasecmp(v->name, "internationalprefix")) {
12817             ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
12818          } else if (!strcasecmp(v->name, "nationalprefix")) {
12819             ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
12820          } else if (!strcasecmp(v->name, "localprefix")) {
12821             ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
12822          } else if (!strcasecmp(v->name, "privateprefix")) {
12823             ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
12824          } else if (!strcasecmp(v->name, "unknownprefix")) {
12825             ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
12826          } else if (!strcasecmp(v->name, "nocid")) {
12827             ast_copy_string(confp->pri.nocid, v->value, sizeof(confp->pri.nocid));
12828          } else if (!strcasecmp(v->name, "withheldcid")) {
12829             ast_copy_string(confp->pri.withheldcid, v->value, sizeof(confp->pri.withheldcid));
12830          } else if (!strcasecmp(v->name, "pin")) {
12831             ast_copy_string(gsm_modem_pin, v->value, sizeof(gsm_modem_pin) - 1);
12832          } else if (!strcasecmp(v->name, "exten")) {
12833             ast_copy_string(gsm_modem_exten, v->value, sizeof(gsm_modem_exten) - 1);
12834          } else if (!strcasecmp(v->name, "resetinterval")) {
12835             if (!strcasecmp(v->value, "never"))
12836                confp->pri.resetinterval = -1;
12837             else if (atoi(v->value) >= 60)
12838                confp->pri.resetinterval = atoi(v->value);
12839             else
12840                ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
12841                   v->value, v->lineno);
12842          } else if (!strcasecmp(v->name, "minunused")) {
12843             confp->pri.minunused = atoi(v->value);
12844          } else if (!strcasecmp(v->name, "minidle")) {
12845             confp->pri.minidle = atoi(v->value); 
12846          } else if (!strcasecmp(v->name, "idleext")) {
12847             ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
12848          } else if (!strcasecmp(v->name, "idledial")) {
12849             ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
12850          } else if (!strcasecmp(v->name, "pritrustusercid")) {
12851             confp->pri.usercid = ast_true(v->value);
12852          } else if (!strcasecmp(v->name, "overlapdial")) {
12853             confp->pri.overlapdial = ast_true(v->value);
12854          } else if (!strcasecmp(v->name, "pritimer")) {
12855 #ifdef PRI_GETSET_TIMERS
12856             char *timerc, *c;
12857             int timer, timeridx;
12858             c = v->value;
12859             timerc = strsep(&c, ",");
12860             if (timerc) {
12861                timer = atoi(c);
12862                if (!timer)
12863                   ast_log(LOG_WARNING, "'%s' is not a valid value for an ISDN timer\n", timerc);
12864                else {
12865                   if ((timeridx = pri_timer2idx(timerc)) >= 0)
12866                      pritimers[timeridx] = timer;
12867                   else
12868                      ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer\n", timerc);
12869                }
12870             } else
12871                ast_log(LOG_WARNING, "'%s' is not a valid ISDN timer configuration string\n", v->value);
12872 
12873          } else if (!strcasecmp(v->name, "facilityenable")) {
12874             confp->pri.facilityenable = ast_true(v->value);
12875 #endif /* PRI_GETSET_TIMERS */
12876 #endif /* HAVE_PRI */
12877          } else if (!strcasecmp(v->name, "cadence")) {
12878             /* setup to scan our argument */
12879             int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
12880             int i;
12881             struct zt_ring_cadence new_cadence;
12882             int cid_location = -1;
12883             int firstcadencepos = 0;
12884             char original_args[80];
12885             int cadence_is_ok = 1;
12886 
12887             ast_copy_string(original_args, v->value, sizeof(original_args));
12888             /* 16 cadences allowed (8 pairs) */
12889             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]);
12890    
12891             /* Cadence must be even (on/off) */
12892             if (element_count % 2 == 1) {
12893                ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s\n",original_args);
12894                cadence_is_ok = 0;
12895             }
12896    
12897             /* Ring cadences cannot be negative */
12898             for (i = 0; i < element_count; i++) {
12899                if (c[i] == 0) {
12900                   ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s\n", original_args);
12901                   cadence_is_ok = 0;
12902                   break;
12903                } else if (c[i] < 0) {
12904                   if (i % 2 == 1) {
12905                      /* Silence duration, negative possibly okay */
12906                      if (cid_location == -1) {
12907                         cid_location = i;
12908                         c[i] *= -1;
12909                      } else {
12910                         ast_log(LOG_ERROR, "CID location specified twice: %s\n",original_args);
12911                         cadence_is_ok = 0;
12912                         break;
12913                      }
12914                   } else {
12915                      if (firstcadencepos == 0) {
12916                         firstcadencepos = i; /* only recorded to avoid duplicate specification */
12917                                  /* duration will be passed negative to the zaptel driver */
12918                      } else {
12919                          ast_log(LOG_ERROR, "First cadence position specified twice: %s\n",original_args);
12920                         cadence_is_ok = 0;
12921                         break;
12922                      }
12923                   }
12924                }
12925             }
12926    
12927             /* Substitute our scanned cadence */
12928             for (i = 0; i < 16; i++) {
12929                new_cadence.ringcadence[i] = c[i];
12930             }
12931    
12932             if (cadence_is_ok) {
12933                /* ---we scanned it without getting annoyed; now some sanity checks--- */
12934                if (element_count < 2) {
12935                   ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s\n", original_args);
12936                } else {
12937                   if (cid_location == -1) {
12938                      /* user didn't say; default to first pause */
12939                      cid_location = 1;
12940                   } else {
12941                      /* convert element_index to cidrings value */
12942                      cid_location = (cid_location + 1) / 2;
12943                   }
12944                   /* ---we like their cadence; try to install it--- */
12945                   if (!user_has_defined_cadences++)
12946                      /* this is the first user-defined cadence; clear the default user cadences */
12947                      num_cadence = 0;
12948                   if ((num_cadence+1) >= NUM_CADENCE_MAX)
12949                      ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX, original_args);
12950                   else {
12951                      cadences[num_cadence] = new_cadence;
12952                      cidrings[num_cadence++] = cid_location;
12953                      if (option_verbose > 2)
12954                         ast_verbose(VERBOSE_PREFIX_3 "cadence 'r%d' added: %s\n",num_cadence,original_args);
12955                   }
12956                }
12957             }
12958          } else if (!strcasecmp(v->name, "ringtimeout")) {
12959             ringt_base = (atoi(v->value) * 8) / READ_SIZE;
12960          } else if (!strcasecmp(v->name, "prewink")) {
12961             confp->timing.prewinktime = atoi(v->value);
12962          } else if (!strcasecmp(v->name, "preflash")) {
12963             confp->timing.preflashtime = atoi(v->value);
12964          } else if (!strcasecmp(v->name, "wink")) {
12965             confp->timing.winktime = atoi(v->value);
12966          } else if (!strcasecmp(v->name, "flash")) {
12967             confp->timing.flashtime = atoi(v->value);
12968          } else if (!strcasecmp(v->name, "start")) {
12969             confp->timing.starttime = atoi(v->value);
12970          } else if (!strcasecmp(v->name, "rxwink")) {
12971             confp->timing.rxwinktime = atoi(v->value);
12972          } else if (!strcasecmp(v->name, "rxflash")) {
12973             confp->timing.rxflashtime = atoi(v->value);
12974          } else if (!strcasecmp(v->name, "debounce")) {
12975             confp->timing.debouncetime = atoi(v->value);
12976          } else if (!strcasecmp(v->name, "toneduration")) {
12977             int toneduration;
12978             int ctlfd;
12979             int res;
12980             struct zt_dialparams dps;
12981 
12982             ctlfd = open("/dev/zap/ctl", O_RDWR);
12983             if (ctlfd == -1) {
12984                ast_log(LOG_ERROR, "Unable to open /dev/zap/ctl to set toneduration\n");
12985                return -1;
12986             }
12987 
12988             toneduration = atoi(v->value);
12989             if (toneduration > -1) {
12990                dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
12991                res = ioctl(ctlfd, ZT_SET_DIALPARAMS, &dps);
12992                if (res < 0) {
12993                   ast_log(LOG_ERROR, "Invalid tone duration: %d ms\n", toneduration);
12994                   return -1;
12995                }
12996             }
12997             close(ctlfd);
12998          } else if (!strcasecmp(v->name, "defaultcic")) {
12999             ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
13000          } else if (!strcasecmp(v->name, "defaultozz")) {
13001             ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
13002          } 
13003       } else if (!skipchannels)
13004          ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
13005    }
13006    if (zapchan[0]) { 
13007       /* The user has set 'zapchan' */
13008       /*< \todo pass proper line number instead of 0 */
13009       if (build_channels(*confp, 0, zapchan, reload, 0, &found_pseudo)) {
13010          return -1;
13011       }
13012    }
13013    /*< \todo why check for the pseudo in the per-channel section.
13014     * Any actual use for manual setup of the pseudo channel? */
13015    if (!found_pseudo && reload == 0) {
13016       /* Make sure pseudo isn't a member of any groups if
13017          we're automatically making it. */   
13018       
13019       confp->chan.group = 0;
13020       confp->chan.callgroup = 0;
13021       confp->chan.pickupgroup = 0;
13022 
13023       tmp = mkintf(CHAN_PSEUDO, *confp, NULL, reload);
13024 
13025       if (tmp) {
13026          if (option_verbose > 2)
13027             ast_verbose(VERBOSE_PREFIX_3 "Automatically generated pseudo channel\n");
13028       } else {
13029          ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
13030       }
13031    }
13032    return 0;
13033 }
13034       
13035 static int setup_zap(int reload)
13036 {
13037    struct ast_config *cfg;
13038    struct ast_variable *v;
13039    struct zt_chan_conf conf = zt_chan_conf_default();
13040    int res;
13041 
13042 #ifdef HAVE_PRI
13043    char *c;
13044    int spanno;
13045    int i, x;
13046    int logicalspan;
13047    int trunkgroup;
13048    int dchannels[NUM_DCHANS];
13049 #endif
13050 
13051    cfg = ast_config_load(config);
13052 
13053    /* Error if we have no config file */
13054    if (!cfg) {
13055       ast_log(LOG_ERROR, "Unable to load config %s\n", config);
13056       return 0;
13057    }
13058 
13059    /* It's a little silly to lock it, but we mind as well just to be sure */
13060    ast_mutex_lock(&iflock);
13061 #ifdef HAVE_PRI
13062    if (!reload) {
13063       /* Process trunkgroups first */
13064       v = ast_variable_browse(cfg, "trunkgroups");
13065       while (v) {
13066          if (!strcasecmp(v->name, "trunkgroup")) {
13067             trunkgroup = atoi(v->value);
13068             if (trunkgroup > 0) {
13069                if ((c = strchr(v->value, ','))) {
13070                   i = 0;
13071                   memset(dchannels, 0, sizeof(dchannels));
13072                   while (c && (i < NUM_DCHANS)) {
13073                      dchannels[i] = atoi(c + 1);
13074                      if (dchannels[i] < 0) {
13075                         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);
13076                      } else
13077                         i++;
13078                      c = strchr(c + 1, ',');
13079                   }
13080                   if (i) {
13081                      if (pri_create_trunkgroup(trunkgroup, dchannels)) {
13082                         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);
13083                      } else if (option_verbose > 1)
13084                         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");
13085                   } else
13086                      ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of zapata.conf\n", trunkgroup, v->lineno);
13087                } else
13088                   ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of zapata.conf\n", trunkgroup, v->lineno);
13089             } else
13090                ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of zapata.conf\n", v->lineno);
13091          } else if (!strcasecmp(v->name, "spanmap")) {
13092             spanno = atoi(v->value);
13093             if (spanno > 0) {
13094                if ((c = strchr(v->value, ','))) {
13095                   trunkgroup = atoi(c + 1);
13096                   if (trunkgroup > 0) {
13097                      if ((c = strchr(c + 1, ','))) 
13098                         logicalspan = atoi(c + 1);
13099                      else
13100                         logicalspan = 0;
13101                      if (logicalspan >= 0) {
13102                         if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
13103                            ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
13104                         } else if (option_verbose > 1) 
13105                            ast_verbose(VERBOSE_PREFIX_2 "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
13106                      } else
13107                         ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of zapata.conf\n", v->lineno);
13108                   } else
13109                      ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of zapata.conf\n", v->lineno);
13110                } else
13111                   ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of zapata.conf\n", v->lineno);
13112             } else
13113                ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of zapata.conf\n", v->lineno);
13114          } else {
13115             ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
13116          }
13117          v = v->next;
13118       }
13119    }
13120 #endif
13121    
13122    /* Copy the default jb config over global_jbconf */
13123    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
13124 
13125    v = ast_variable_browse(cfg, "channels");
13126    res = process_zap(&conf, v, reload, 0);
13127    ast_mutex_unlock(&iflock);
13128    ast_config_destroy(cfg);
13129    if (res)
13130       return res;
13131    cfg = ast_config_load("users.conf");
13132    if (cfg) {
13133       char *cat;
13134       const char *chans;
13135       process_zap(&conf, ast_variable_browse(cfg, "general"), 1, 1);
13136       for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
13137          if (!strcasecmp(cat, "general"))
13138             continue;
13139          chans = ast_variable_retrieve(cfg, cat, "zapchan");
13140          if (!ast_strlen_zero(chans)) {
13141             /** \todo At this point we should probably 
13142              * duplicate conf, and pass a copy, to prevent 
13143              * one section from affecting another
13144              */
13145             process_zap(&conf, ast_variable_browse(cfg, cat), reload, 0);
13146          }
13147       }
13148       ast_config_destroy(cfg);
13149    }
13150 #ifdef HAVE_PRI
13151    if (!reload) {
13152       for (x = 0; x < NUM_SPANS; x++) {
13153          pris[x].debugfd = -1;
13154          if (pris[x].pvts[0]) {
13155             if (start_pri(pris + x)) {
13156                ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
13157                return -1;
13158             } else if (option_verbose > 1)
13159                ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
13160          }
13161       }
13162    }
13163 #endif
13164    /* And start the monitor for the first time */
13165    restart_monitor();
13166    return 0;
13167 }
13168 
13169 static int load_module(void)
13170 {
13171    int res;
13172 
13173 #ifdef HAVE_PRI
13174    int y,i;
13175    memset(pris, 0, sizeof(pris));
13176    for (y = 0; y < NUM_SPANS; y++) {
13177       ast_mutex_init(&pris[y].lock);
13178       pris[y].offset = -1;
13179       pris[y].master = AST_PTHREADT_NULL;
13180       for (i = 0; i < NUM_DCHANS; i++)
13181          pris[y].fds[i] = -1;
13182    }
13183    pri_set_error(zt_pri_error);
13184    pri_set_message(zt_pri_message);
13185    ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
13186          zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
13187 #endif
13188 #ifdef HAVE_GSMAT
13189    gsm_set_error(zt_gsm_error);
13190    gsm_set_message(zt_gsm_message);
13191 #endif
13192    res = setup_zap(0);
13193    /* Make sure we can register our Zap channel type */
13194    if (res)
13195       return AST_MODULE_LOAD_DECLINE;
13196    if (ast_channel_register(&zap_tech)) {
13197       ast_log(LOG_ERROR, "Unable to register channel class 'Zap'\n");
13198       __unload_module();
13199       return -1;
13200    }
13201 #ifdef HAVE_PRI
13202    ast_string_field_init(&inuse, 16);
13203    ast_string_field_set(&inuse, name, "GR-303InUse");
13204    ast_cli_register_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(struct ast_cli_entry));
13205    ast_register_application(zapCD_app, app_zapCD, zapCD_synopsis, zapCD_tdesc);
13206         ast_register_application(zapInband_app, app_zapInband, zapInband_synopsis, zapInband_tdesc);
13207 #endif   
13208    ast_register_application(zapEC_app, app_zapEC, zapEC_synopsis, zapEC_tdesc);
13209    ast_cli_register_multiple(zap_cli, sizeof(zap_cli) / sizeof(struct ast_cli_entry));
13210 #ifdef HAVE_GSMAT
13211    ast_cli_register(&gsm_send_sms);
13212    ast_cli_register(&gsm_send_pdu);
13213    ast_cli_register(&gsm_show_status);
13214    ast_cli_register_multiple(zap_gsm_cli, sizeof(zap_gsm_cli) / sizeof(zap_gsm_cli[0]));
13215 #endif
13216    
13217    memset(round_robin, 0, sizeof(round_robin));
13218    ast_manager_register( "ZapTransfer", 0, action_transfer, "Transfer Zap Channel" );
13219    ast_manager_register( "ZapHangup", 0, action_transferhangup, "Hangup Zap Channel" );
13220    ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
13221    ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
13222    ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
13223    ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
13224    ast_manager_register("ZapRestart", 0, action_zaprestart, "Fully Restart zaptel channels (terminates calls)");
13225 
13226    return res;
13227 }
13228 
13229 #ifdef HAVE_PRI
13230 static int zt_tdd_sendtext(struct ast_channel *c, const char *text);
13231 
13232 static int zt_pri_sendtext(struct ast_channel *c, const char *text) {
13233  struct zt_pvt *p = c->tech_pvt;
13234  if (!p) return -1;
13235  if (!p->pri) return -1;
13236        if (strlen(text)) {
13237       if (p->pri) {     
13238           if (!pri_grab(p, p->pri)) {
13239       // ast_log(LOG_NOTICE, "Sending Display IE  '%s'\n", text);
13240          pri_information_display(p->pri->pri,p->call,(char *)text);
13241          pri_rel(p->pri);
13242              } else ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
13243       }
13244        }
13245  return 0;
13246 }
13247 #endif
13248 
13249 static int zt_sendtext(struct ast_channel *c, const char *dest, const char *text, int ispdu) {
13250  struct zt_pvt *p = c->tech_pvt;
13251  if (!p) return -1;
13252  if (p->sig == SIG_PRI) {
13253 #ifdef HAVE_PRI
13254    if (ispdu) {
13255        ast_log(LOG_WARNING, "Dont know how to send PDU on ZAP ISDN channel\n");
13256        return -1;
13257    }
13258    return zt_pri_sendtext(c, text);
13259 #endif
13260  } else if (p->sig == SIG_GSM) {
13261 #ifdef HAVE_GSMAT
13262      return zt_gsm_sendtext(c, dest, text, ispdu);
13263 #endif
13264  } else {
13265    return zt_tdd_sendtext(c, text);
13266  }
13267  return -1;
13268 }
13269 
13270 static int zt_tdd_sendtext(struct ast_channel *c, const char *text)
13271 {
13272 #define  END_SILENCE_LEN 400
13273 #define  HEADER_MS 50
13274 #define  TRAILER_MS 5
13275 #define  HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
13276 #define  ASCII_BYTES_PER_CHAR 80
13277 
13278    unsigned char *buf,*mybuf;
13279    struct zt_pvt *p = c->tech_pvt;
13280    struct pollfd fds[1];
13281    int size,res,fd,len,x;
13282    int bytes=0;
13283    /* Initial carrier (imaginary) */
13284    float cr = 1.0;
13285    float ci = 0.0;
13286    float scont = 0.0;
13287    int index;
13288 
13289 
13290    index = zt_get_index(c, p, 0);
13291    if (index < 0) {
13292       ast_log(LOG_WARNING, "Huh?  I don't exist?\n");
13293       return -1;
13294    }
13295    if (!text[0]) return(0); /* if nothing to send, dont */
13296    if ((!p->tdd) && (!p->mate)) return(0);  /* if not in TDD mode, just return */
13297    if (p->mate) 
13298       buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
13299    else
13300       buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
13301    if (!buf)
13302       return -1;
13303    mybuf = buf;
13304    if (p->mate) {
13305       int codec = AST_LAW(p);
13306       for (x = 0; x < HEADER_MS; x++) {   /* 50 ms of Mark */
13307          PUT_CLID_MARKMS;
13308       }
13309       /* Put actual message */
13310       for (x = 0; text[x]; x++) {
13311          PUT_CLID(text[x]);
13312       }
13313       for (x = 0; x < TRAILER_MS; x++) {  /* 5 ms of Mark */
13314          PUT_CLID_MARKMS;
13315       }
13316       len = bytes;
13317       buf = mybuf;
13318    } else {
13319       len = tdd_generate(p->tdd, buf, text);
13320       if (len < 1) {
13321          ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
13322          free(mybuf);
13323          return -1;
13324       }
13325    }
13326    memset(buf + len, 0x7f, END_SILENCE_LEN);
13327    len += END_SILENCE_LEN;
13328    fd = p->subs[index].zfd;
13329    while (len) {
13330       if (ast_check_hangup(c)) {
13331          free(mybuf);
13332          return -1;
13333       }
13334       size = len;
13335       if (size > READ_SIZE)
13336          size = READ_SIZE;
13337       fds[0].fd = fd;
13338       fds[0].events = POLLOUT | POLLPRI;
13339       fds[0].revents = 0;
13340       res = poll(fds, 1, -1);
13341       if (!res) {
13342          ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
13343          continue;
13344       }
13345         /* if got exception */
13346       if (fds[0].revents & POLLPRI) {
13347          ast_free(mybuf);
13348          return -1;
13349       }
13350       if (!(fds[0].revents & POLLOUT)) {
13351          ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
13352          continue;
13353       }
13354       res = write(fd, buf, size);
13355       if (res != size) {
13356          if (res == -1) {
13357             free(mybuf);
13358             return -1;
13359          }
13360          if (option_debug)
13361             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
13362          break;
13363       }
13364       len -= size;
13365       buf += size;
13366    }
13367    free(mybuf);
13368    return(0);
13369 }
13370 
13371 
13372 static int reload(void)
13373 {
13374    int res = 0;
13375 
13376    res = setup_zap(1);
13377    if (res) {
13378       ast_log(LOG_WARNING, "Reload of chan_zap.so is unsuccessful!\n");
13379       return -1;
13380    }
13381    return 0;
13382 }
13383 
13384 /* This is a workaround so that menuselect displays a proper description
13385  * AST_MODULE_INFO(, , "Zapata Telephony"
13386  */
13387 
13388 #ifdef ZAPATA_PRI
13389 #define tdesc "Zapata Telephony w/PRI"
13390 #else
13391 #define tdesc "Zapata Telephony"
13392 #endif
13393 
13394 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
13395       .load = load_module,
13396       .unload = unload_module,
13397       .reload = reload,
13398           );
13399 
13400 

Generated on Sat Apr 12 07:12:23 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5