Thu Oct 11 06:42:01 2012

Asterisk developer's documentation


chan_dahdi.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief DAHDI Pseudo TDM interface 
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * Connects to the DAHDI telephony library as well as 
00026  * libpri. Libpri is optional and needed only if you are
00027  * going to use ISDN connections.
00028  *
00029  * You need to install libraries before you attempt to compile
00030  * and install the DAHDI channel.
00031  *
00032  * \par See also
00033  * \arg \ref Config_dahdi
00034  *
00035  * \ingroup channel_drivers
00036  *
00037  * \todo Deprecate the "musiconhold" configuration option post 1.4
00038  */
00039 
00040 /*** MODULEINFO
00041    <depend>res_smdi</depend>
00042    <depend>dahdi</depend>
00043    <depend>tonezone</depend>
00044    <depend>res_features</depend>
00045    <use>pri</use>
00046  ***/
00047 
00048 #include "asterisk.h"
00049 
00050 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 313188 $")
00051 
00052 #include <stdio.h>
00053 #include <string.h>
00054 #if defined(__NetBSD__) || defined(__FreeBSD__)
00055 #include <pthread.h>
00056 #include <signal.h>
00057 #else
00058 #include <sys/signal.h>
00059 #endif
00060 #include <errno.h>
00061 #include <stdlib.h>
00062 #if !defined(SOLARIS) && !defined(__FreeBSD__)
00063 #include <stdint.h>
00064 #endif
00065 #include <unistd.h>
00066 #include <sys/ioctl.h>
00067 #include <math.h>
00068 #include <ctype.h>
00069 
00070 #ifdef HAVE_PRI
00071 #include <libpri.h>
00072 #endif
00073 
00074 #include "asterisk/lock.h"
00075 #include "asterisk/channel.h"
00076 #include "asterisk/config.h"
00077 #include "asterisk/logger.h"
00078 #include "asterisk/module.h"
00079 #include "asterisk/pbx.h"
00080 #include "asterisk/options.h"
00081 #include "asterisk/file.h"
00082 #include "asterisk/ulaw.h"
00083 #include "asterisk/alaw.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/adsi.h"
00086 #include "asterisk/cli.h"
00087 #include "asterisk/cdr.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/musiconhold.h"
00090 #include "asterisk/say.h"
00091 #include "asterisk/tdd.h"
00092 #include "asterisk/app.h"
00093 #include "asterisk/dsp.h"
00094 #include "asterisk/astdb.h"
00095 #include "asterisk/manager.h"
00096 #include "asterisk/causes.h"
00097 #include "asterisk/term.h"
00098 #include "asterisk/utils.h"
00099 #include "asterisk/transcap.h"
00100 #include "asterisk/stringfields.h"
00101 #include "asterisk/abstract_jb.h"
00102 #include "asterisk/smdi.h"
00103 #include "asterisk/astobj.h"
00104 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00105 
00106 #include "asterisk/dahdi_compat.h"
00107 #include "asterisk/tonezone_compat.h"
00108 
00109 /*! Global jitterbuffer configuration - by default, jb is disabled */
00110 static struct ast_jb_conf default_jbconf =
00111 {
00112    .flags = 0,
00113    .max_size = -1,
00114    .resync_threshold = -1,
00115    .impl = ""
00116 };
00117 static struct ast_jb_conf global_jbconf;
00118 
00119 #ifndef DAHDI_TONEDETECT
00120 /* Work around older code with no tone detect */
00121 #define DAHDI_EVENT_DTMFDOWN 0
00122 #define DAHDI_EVENT_DTMFUP 0
00123 #endif
00124 
00125 /* define this to send PRI user-user information elements */
00126 #undef SUPPORT_USERUSER
00127 
00128 /*! 
00129  * Define to make always pick a channel if allowed.  Useful for
00130  * testing channel shifting.
00131  */
00132 //#define ALWAYS_PICK_CHANNEL 1
00133 
00134 /*!
00135  * Define to force a RESTART on a channel that returns a cause
00136  * code of PRI_CAUSE_REQUESTED_CHAN_UNAVAIL(44).  If the cause
00137  * is because of a stuck channel on the peer and the channel is
00138  * always the next channel we pick for an outgoing call then
00139  * this can help.
00140  */
00141 #define FORCE_RESTART_UNAVAIL_CHANS    1
00142 
00143 /*!
00144  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
00145  * the user hangs up to reset the state machine so ring works properly.
00146  * This is used to be able to support kewlstart by putting the zhone in
00147  * groundstart mode since their forward disconnect supervision is entirely
00148  * broken even though their documentation says it isn't and their support
00149  * is entirely unwilling to provide any assistance with their channel banks
00150  * even though their web site says they support their products for life.
00151  */
00152 /* #define ZHONE_HACK */
00153 
00154 /*! \note
00155  * Define if you want to check the hook state for an FXO (FXS signalled) interface
00156  * before dialing on it.  Certain FXO interfaces always think they're out of
00157  * service with this method however.
00158  */
00159 /* #define DAHDI_CHECK_HOOKSTATE */
00160 
00161 /*! \brief Typically, how many rings before we should send Caller*ID */
00162 #define DEFAULT_CIDRINGS 1
00163 
00164 #define AST_LAW(p) (((p)->law == DAHDI_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[] = "DAHDI Telephony Driver"
00170 #ifdef HAVE_PRI
00171                " w/PRI"
00172 #endif
00173 ;
00174 
00175 #define SIG_EM    DAHDI_SIG_EM
00176 #define SIG_EMWINK   (0x0100000 | DAHDI_SIG_EM)
00177 #define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
00178 #define  SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
00179 #define  SIG_FEATB   (0x0800000 | DAHDI_SIG_EM)
00180 #define  SIG_E911 (0x1000000 | DAHDI_SIG_EM)
00181 #define  SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
00182 #define  SIG_FGC_CAMA   (0x4000000 | DAHDI_SIG_EM)
00183 #define  SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
00184 #define SIG_FXSLS DAHDI_SIG_FXSLS
00185 #define SIG_FXSGS DAHDI_SIG_FXSGS
00186 #define SIG_FXSKS DAHDI_SIG_FXSKS
00187 #define SIG_FXOLS DAHDI_SIG_FXOLS
00188 #define SIG_FXOGS DAHDI_SIG_FXOGS
00189 #define SIG_FXOKS DAHDI_SIG_FXOKS
00190 #define SIG_PRI      DAHDI_SIG_CLEAR
00191 #define  SIG_SF      DAHDI_SIG_SF
00192 #define SIG_SFWINK   (0x0100000 | DAHDI_SIG_SF)
00193 #define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
00194 #define  SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
00195 #define  SIG_SF_FEATB   (0x0800000 | DAHDI_SIG_SF)
00196 #define SIG_EM_E1 DAHDI_SIG_EM_E1
00197 #define SIG_GR303FXOKS  (0x0100000 | DAHDI_SIG_FXOKS)
00198 #define SIG_GR303FXSKS  (0x0100000 | DAHDI_SIG_FXSKS)
00199 
00200 #define NUM_SPANS       32
00201 #define NUM_DCHANS      4  /*!< No more than 4 d-channels */
00202 #define MAX_CHANNELS 672      /*!< No more than a DS3 per trunk group */
00203 
00204 #define CHAN_PSEUDO  -2
00205 
00206 #define DCHAN_PROVISIONED (1 << 0)
00207 #define DCHAN_NOTINALARM  (1 << 1)
00208 #define DCHAN_UP          (1 << 2)
00209 
00210 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
00211 
00212 /* Overlap dialing option types */
00213 #define DAHDI_OVERLAPDIAL_NONE 0
00214 #define DAHDI_OVERLAPDIAL_OUTGOING 1
00215 #define DAHDI_OVERLAPDIAL_INCOMING 2
00216 #define DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
00217 
00218 static char defaultcic[64] = "";
00219 static char defaultozz[64] = "";
00220 
00221 static char progzone[10] = "";
00222 
00223 static int distinctiveringaftercid = 0;
00224 
00225 static int numbufs = 4;
00226 
00227 #ifdef HAVE_PRI
00228 static struct ast_channel inuse;
00229 #ifdef PRI_GETSET_TIMERS
00230 static int pritimers[PRI_MAX_TIMERS];
00231 #endif
00232 static int pridebugfd = -1;
00233 static char pridebugfilename[1024] = "";
00234 #endif
00235 
00236 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
00237 static int firstdigittimeout = 16000;
00238 
00239 /*! \brief How long to wait for following digits (FXO logic) */
00240 static int gendigittimeout = 8000;
00241 
00242 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
00243 static int matchdigittimeout = 3000;
00244 
00245 /*! \brief Protect the interface list (of dahdi_pvt's) */
00246 AST_MUTEX_DEFINE_STATIC(iflock);
00247 
00248 
00249 static int ifcount = 0;
00250 
00251 #ifdef HAVE_PRI
00252 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
00253 #endif
00254 
00255 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
00256    when it's doing something critical. */
00257 AST_MUTEX_DEFINE_STATIC(monlock);
00258 
00259 /*! \brief This is the thread for the monitor which checks for input on the channels
00260    which are not currently in use. */
00261 static pthread_t monitor_thread = AST_PTHREADT_NULL;
00262 static ast_cond_t ss_thread_complete;
00263 AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
00264 AST_MUTEX_DEFINE_STATIC(restart_lock);
00265 static int ss_thread_count = 0;
00266 static int num_restart_pending = 0;
00267 
00268 static int restart_monitor(void);
00269 
00270 static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
00271 
00272 static int dahdi_sendtext(struct ast_channel *c, const char *text);
00273 
00274 #define SIG_PRI_LIB_HANDLE_CASES \
00275    SIG_PRI
00276 
00277 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
00278 static inline int dahdi_get_event(int fd)
00279 {
00280    int j;
00281    if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
00282       return -1;
00283    return j;
00284 }
00285 
00286 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
00287 static inline int dahdi_wait_event(int fd)
00288 {
00289    int i, j = 0;
00290    i = DAHDI_IOMUX_SIGEVENT;
00291    if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
00292       return -1;
00293    if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
00294       return -1;
00295    return j;
00296 }
00297 
00298 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
00299 #define READ_SIZE 160
00300 
00301 #define MASK_AVAIL      (1 << 0) /*!< Channel available for PRI use */
00302 #define MASK_INUSE      (1 << 1) /*!< Channel currently in use */
00303 
00304 #define CALLWAITING_SILENT_SAMPLES     ((300 * 8) / READ_SIZE) /*!< 300 ms */
00305 #define CALLWAITING_REPEAT_SAMPLES     ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
00306 #define CALLWAITING_SUPPRESS_SAMPLES   ((100 * 8) / READ_SIZE) /*!< 100 ms */
00307 #define CIDCW_EXPIRE_SAMPLES        ((500 * 8) / READ_SIZE) /*!< 500 ms */
00308 #define MIN_MS_SINCE_FLASH          ((2000) )   /*!< 2000 ms */
00309 #define DEFAULT_RINGT               ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
00310 
00311 struct dahdi_pvt;
00312 
00313 /*!
00314  * \brief Configured ring timeout base.
00315  * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
00316  */
00317 static int ringt_base = DEFAULT_RINGT;
00318 
00319 #ifdef HAVE_PRI
00320 
00321 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
00322 #define PRI_CHANNEL(p) ((p) & 0xff)
00323 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00324 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
00325 
00326 /*! Call establishment life cycle level for simple comparisons. */
00327 enum dahdi_call_level {
00328    /*! Call does not exist. */
00329    DAHDI_CALL_LEVEL_IDLE,
00330    /*! Call is present but has no response yet. (SETUP) */
00331    DAHDI_CALL_LEVEL_SETUP,
00332    /*! Call is collecting digits for overlap dialing. (SETUP ACKNOWLEDGE) */
00333    DAHDI_CALL_LEVEL_OVERLAP,
00334    /*! Call routing is happening. (PROCEEDING) */
00335    DAHDI_CALL_LEVEL_PROCEEDING,
00336    /*! Called party is being alerted of the call. (ALERTING) */
00337    DAHDI_CALL_LEVEL_ALERTING,
00338    /*! Call is connected/answered. (CONNECT) */
00339    DAHDI_CALL_LEVEL_CONNECT,
00340 };
00341 
00342 struct dahdi_pri {
00343    pthread_t master;                /*!< Thread of master */
00344    ast_mutex_t lock;                /*!< Mutex */
00345    char idleext[AST_MAX_EXTENSION];          /*!< Where to idle extra calls */
00346    char idlecontext[AST_MAX_CONTEXT];           /*!< What context to use for idle */
00347    char idledial[AST_MAX_EXTENSION];            /*!< What to dial before dumping */
00348    int minunused;                   /*!< Min # of channels to keep empty */
00349    int minidle;                     /*!< Min # of "idling" calls to keep active */
00350    int nodetype;                    /*!< Node type */
00351    int switchtype;                     /*!< Type of switch to emulate */
00352    int nsf;                   /*!< Network-Specific Facilities */
00353    int dialplan;                    /*!< Dialing plan */
00354    int localdialplan;                  /*!< Local dialing plan */
00355    char internationalprefix[10];             /*!< country access code ('00' for european dialplans) */
00356    char nationalprefix[10];               /*!< area access code ('0' for european dialplans) */
00357    char localprefix[20];                  /*!< area access code + area code ('0'+area code for european dialplans) */
00358    char privateprefix[20];                /*!< for private dialplans */
00359    char unknownprefix[20];                /*!< for unknown dialplans */
00360    int dchannels[NUM_DCHANS];             /*!< What channel are the dchannels on */
00361    int trunkgroup;                     /*!< What our trunkgroup is */
00362    int mastertrunkgroup;                  /*!< What trunk group is our master */
00363    int prilogicalspan;                 /*!< Logical span number within trunk group */
00364    int numchans;                    /*!< Num of channels we represent */
00365    int overlapdial;                 /*!< In overlap dialing mode */
00366    int facilityenable;                 /*!< Enable facility IEs */
00367    struct pri *dchans[NUM_DCHANS];              /*!< Actual d-channels */
00368    int dchanavail[NUM_DCHANS];               /*!< Whether each channel is available */
00369    struct pri *pri;                 /*!< Currently active D-channel */
00370    /*! \brief TRUE if to dump PRI event info (Tested but never set) */
00371    int debug;
00372    int fds[NUM_DCHANS];                /*!< FD's for d-channels */
00373    /*! \brief Value set but not used */
00374    int offset;
00375    /*! \brief Span number put into user output messages */
00376    int span;
00377    /*! \brief TRUE if span is being reset/restarted */
00378    int resetting;
00379    /*! \brief Current position during a reset (-1 if not started) */
00380    int resetpos;
00381 #ifdef HAVE_PRI_INBANDDISCONNECT
00382    unsigned int inbanddisconnect:1;          /*!< Should we support inband audio after receiving DISCONNECT? */
00383 #endif
00384    /*! TRUE if we have already whined about no D channels available. */
00385    unsigned int no_d_channels:1;
00386    time_t lastreset;                /*!< time when unused channels were last reset */
00387    long resetinterval;                 /*!< Interval (in seconds) for resetting unused channels */
00388    struct dahdi_pvt *pvts[MAX_CHANNELS];           /*!< Member channel pvt structs */
00389    struct dahdi_pvt *crvs;                /*!< Member CRV structs */
00390    struct dahdi_pvt *crvend;                 /*!< Pointer to end of CRV structs */
00391 };
00392 
00393 
00394 static struct dahdi_pri pris[NUM_SPANS];
00395 
00396 #if 0
00397 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
00398 #else
00399 #define DEFAULT_PRI_DEBUG 0
00400 #endif
00401 
00402 static inline void pri_rel(struct dahdi_pri *pri)
00403 {
00404    ast_mutex_unlock(&pri->lock);
00405 }
00406 
00407 #else
00408 /*! Shut up the compiler */
00409 struct dahdi_pri;
00410 #endif
00411 
00412 #define SUB_REAL  0        /*!< Active call */
00413 #define SUB_CALLWAIT 1        /*!< Call-Waiting call on hold */
00414 #define SUB_THREEWAY 2        /*!< Three-way call */
00415 
00416 /* Polarity states */
00417 #define POLARITY_IDLE   0
00418 #define POLARITY_REV    1
00419 
00420 
00421 static struct dahdi_distRings drings;
00422 
00423 struct distRingData {
00424    int ring[3];
00425 };
00426 struct ringContextData {
00427    char contextData[AST_MAX_CONTEXT];
00428 };
00429 struct dahdi_distRings {
00430    struct distRingData ringnum[3];
00431    struct ringContextData ringContext[3];
00432 };
00433 
00434 static char *subnames[] = {
00435    "Real",
00436    "Callwait",
00437    "Threeway"
00438 };
00439 
00440 struct dahdi_subchannel {
00441    int dfd;
00442    struct ast_channel *owner;
00443    int chan;
00444    short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
00445    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00446    unsigned int needringing:1;
00447    unsigned int needbusy:1;
00448    unsigned int needcongestion:1;
00449    unsigned int needcallerid:1;
00450    unsigned int needanswer:1;
00451    unsigned int needflash:1;
00452    unsigned int needhold:1;
00453    unsigned int needunhold:1;
00454    unsigned int linear:1;
00455    unsigned int inthreeway:1;
00456    struct dahdi_confinfo curconf;
00457 };
00458 
00459 #define CONF_USER_REAL     (1 << 0)
00460 #define CONF_USER_THIRDCALL   (1 << 1)
00461 
00462 #define MAX_SLAVES   4
00463 
00464 static struct dahdi_pvt {
00465    ast_mutex_t lock;             /*!< Channel private lock. */
00466    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00467                      /*!< Up to three channels can be associated with this call */
00468       
00469    struct dahdi_subchannel sub_unused;    /*!< Just a safety precaution */
00470    struct dahdi_subchannel subs[3];       /*!< Sub-channels */
00471    struct dahdi_confinfo saveconf;        /*!< Saved conference info */
00472 
00473    struct dahdi_pvt *slaves[MAX_SLAVES];     /*!< Slave to us (follows our conferencing) */
00474    struct dahdi_pvt *master;           /*!< Master to us (we follow their conferencing) */
00475    int inconference;          /*!< If our real should be in the conference */
00476    
00477    int bufsize;                /*!< Size of the buffers */
00478    int buf_no;             /*!< Number of buffers */
00479    int buf_policy;            /*!< Buffer policy */
00480    int sig;             /*!< Signalling style */
00481    /*!
00482     * \brief Nonzero if the signaling type is sent over a radio.
00483     * \note Set to a couple of nonzero values but it is only tested like a boolean.
00484     */
00485    int radio;
00486    int outsigmod;             /*!< Outbound Signalling style (modifier) */
00487    int oprmode;               /*!< "Operator Services" mode */
00488    struct dahdi_pvt *oprpeer;          /*!< "Operator Services" peer tech_pvt ptr */
00489    /*! \brief Rx gain set by chan_dahdi.conf */
00490    float rxgain;
00491    /*! \brief Tx gain set by chan_dahdi.conf */
00492    float txgain;
00493    int tonezone;              /*!< tone zone for this chan, or -1 for default */
00494    struct dahdi_pvt *next;          /*!< Next channel in list */
00495    struct dahdi_pvt *prev;          /*!< Prev channel in list */
00496 
00497    /* flags */
00498 
00499    /*!
00500     * \brief TRUE if ADSI (Analog Display Services Interface) available
00501     * \note Set from the "adsi" value read in from chan_dahdi.conf
00502     */
00503    unsigned int adsi:1;
00504    /*!
00505     * \brief TRUE if we can use a polarity reversal to mark when an outgoing
00506     * call is answered by the remote party.
00507     * \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
00508     */
00509    unsigned int answeronpolarityswitch:1;
00510    /*!
00511     * \brief TRUE if busy detection is enabled.
00512     * (Listens for the beep-beep busy pattern.)
00513     * \note Set from the "busydetect" value read in from chan_dahdi.conf
00514     */
00515    unsigned int busydetect:1;
00516    /*!
00517     * \brief TRUE if call return is enabled.
00518     * (*69, if your dialplan doesn't catch this first)
00519     * \note Set from the "callreturn" value read in from chan_dahdi.conf
00520     */
00521    unsigned int callreturn:1;
00522    /*!
00523     * \brief TRUE if busy extensions will hear the call-waiting tone
00524     * and can use hook-flash to switch between callers.
00525     * \note Can be disabled by dialing *70.
00526     * \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
00527     */
00528    unsigned int callwaiting:1;
00529    /*!
00530     * \brief TRUE if send caller ID for Call Waiting
00531     * \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
00532     */
00533    unsigned int callwaitingcallerid:1;
00534    /*!
00535     * \brief TRUE if support for call forwarding enabled.
00536     * Dial *72 to enable call forwarding.
00537     * Dial *73 to disable call forwarding.
00538     * \note Set from the "cancallforward" value read in from chan_dahdi.conf
00539     */
00540    unsigned int cancallforward:1;
00541    /*!
00542     * \brief TRUE if support for call parking is enabled.
00543     * \note Set from the "canpark" value read in from chan_dahdi.conf
00544     */
00545    unsigned int canpark:1;
00546    /*! \brief TRUE if to wait for a DTMF digit to confirm answer */
00547    unsigned int confirmanswer:1;
00548    /*!
00549     * \brief TRUE if the channel is to be destroyed on hangup.
00550     * (Used by pseudo channels.)
00551     */
00552    unsigned int destroy:1;
00553    unsigned int didtdd:1;           /*!< flag to say its done it once */
00554    /*! \brief TRUE if analog type line dialed no digits in Dial() */
00555    unsigned int dialednone:1;
00556    /*! \brief TRUE if in the process of dialing digits or sending something. */
00557    unsigned int dialing:1;
00558    /*! \brief TRUE if the transfer capability of the call is digital. */
00559    unsigned int digital:1;
00560    /*! \brief TRUE if Do-Not-Disturb is enabled. */
00561    unsigned int dnd:1;
00562    /*! \brief XXX BOOLEAN Purpose??? */
00563    unsigned int echobreak:1;
00564    /*!
00565     * \brief TRUE if echo cancellation enabled when bridged.
00566     * \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
00567     * \note Disabled if the echo canceller is not setup.
00568     */
00569    unsigned int echocanbridged:1;
00570    /*! \brief TRUE if echo cancellation is turned on. */
00571    unsigned int echocanon:1;
00572    /*! \brief TRUE if a fax tone has already been handled. */
00573    unsigned int faxhandled:1;
00574    /*!< TRUE while buffer configuration override is in use. */
00575    unsigned int bufferoverrideinuse:1;
00576    /*! \brief TRUE if over a radio and dahdi_read() has been called. */
00577    unsigned int firstradio:1;
00578    /*!
00579     * \brief TRUE if the call will be considered "hung up" on a polarity reversal.
00580     * \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
00581     */
00582    unsigned int hanguponpolarityswitch:1;
00583    /*! \brief TRUE if DTMF detection needs to be done by hardware. */
00584    unsigned int hardwaredtmf:1;
00585    /*!
00586     * \brief TRUE if the outgoing caller ID is blocked/hidden.
00587     * \note Caller ID can be disabled by dialing *67.
00588     * \note Caller ID can be enabled by dialing *82.
00589     * \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
00590     */
00591    unsigned int hidecallerid:1;
00592    /*!
00593     * \brief TRUE if hide just the name not the number for legacy PBX use.
00594     * \note Only applies to PRI channels.
00595     * \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
00596     */
00597    unsigned int hidecalleridname:1;
00598    /*! \brief TRUE if DTMF detection is disabled. */
00599    unsigned int ignoredtmf:1;
00600    /*!
00601     * \brief TRUE if the channel should be answered immediately
00602     * without attempting to gather any digits.
00603     * \note Set from the "immediate" value read in from chan_dahdi.conf
00604     */
00605    unsigned int immediate:1;
00606    /*! \brief TRUE if in an alarm condition. */
00607    unsigned int inalarm:1;
00608    unsigned int unknown_alarm:1;
00609    /*! \brief TRUE if TDD in MATE mode */
00610    unsigned int mate:1;
00611 #if defined(HAVE_PRI)
00612    /*!
00613     * \brief TRUE when this channel is allocated.
00614     *
00615     * \details
00616     * Needed to hold an outgoing channel allocation before the
00617     * owner pointer is created.
00618     *
00619     * \note This is one of several items to check to see if a
00620     * channel is available for use.
00621     */
00622    unsigned int allocated:1;
00623 #endif   /* defined(HAVE_PRI) */
00624    /*! \brief TRUE if we originated the call leg. */
00625    unsigned int outgoing:1;
00626    /* unsigned int overlapdial:1;         unused and potentially confusing */
00627    /*!
00628     * \brief TRUE if busy extensions will hear the call-waiting tone
00629     * and can use hook-flash to switch between callers.
00630     * \note Set from the "callwaiting" value read in from chan_dahdi.conf
00631     */
00632    unsigned int permcallwaiting:1;
00633    /*!
00634     * \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
00635     * \note Set from the "hidecallerid" value read in from chan_dahdi.conf
00636     */
00637    unsigned int permhidecallerid:1;
00638    /*!
00639     * \brief TRUE if PRI congestion/busy indications are sent out-of-band.
00640     * \note Set from the "priindication" value read in from chan_dahdi.conf
00641     */
00642    unsigned int priindication_oob:1;
00643    /*!
00644     * \brief TRUE if PRI B channels are always exclusively selected.
00645     * \note Set from the "priexclusive" value read in from chan_dahdi.conf
00646     */
00647    unsigned int priexclusive:1;
00648    /*!
00649     * \brief TRUE if we will pulse dial.
00650     * \note Set from the "pulsedial" value read in from chan_dahdi.conf
00651     */
00652    unsigned int pulse:1;
00653    /*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
00654    unsigned int pulsedial:1;
00655    unsigned int restartpending:1;      /*!< flag to ensure counted only once for restart */
00656    /*!
00657     * \brief TRUE if caller ID is restricted.
00658     * \note Set but not used.  Should be deleted.  Redundant with permhidecallerid.
00659     * \note Set from the "restrictcid" value read in from chan_dahdi.conf
00660     */
00661    unsigned int restrictcid:1;
00662    /*!
00663     * \brief TRUE if three way calling is enabled
00664     * \note Set from the "threewaycalling" value read in from chan_dahdi.conf
00665     */
00666    unsigned int threewaycalling:1;
00667    /*!
00668     * \brief TRUE if call transfer is enabled
00669     * \note For FXS ports (either direct analog or over T1/E1):
00670     *   Support flash-hook call transfer
00671     * \note For digital ports using ISDN PRI protocols:
00672     *   Support switch-side transfer (called 2BCT, RLT or other names)
00673     * \note Set from the "transfer" value read in from chan_dahdi.conf
00674     */
00675    unsigned int transfer:1;
00676    /*!
00677     * \brief TRUE if caller ID is used on this channel.
00678     * \note PRI spans will save caller ID from the networking peer.
00679     * \note FXS ports will generate the caller ID spill.
00680     * \note FXO ports will listen for the caller ID spill.
00681     * \note Set from the "usecallerid" value read in from chan_dahdi.conf
00682     */
00683    unsigned int use_callerid:1;
00684    /*!
00685     * \brief TRUE if we will use the calling presentation setting
00686     * from the Asterisk channel for outgoing calls.
00687     * \note Only applies to PRI channels.
00688     * \note Set from the "usecallingpres" value read in from chan_dahdi.conf
00689     */
00690    unsigned int use_callingpres:1;
00691    /*!
00692     * \brief TRUE if distinctive rings are to be detected.
00693     * \note For FXO lines
00694     * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
00695     */
00696    unsigned int usedistinctiveringdetection:1;
00697    /*!
00698     * \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
00699     * \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
00700     */
00701    unsigned int dahditrcallerid:1;
00702    /*!
00703     * \brief TRUE if allowed to flash-transfer to busy channels.
00704     * \note Set from the "transfertobusy" value read in from chan_dahdi.conf
00705     */
00706    unsigned int transfertobusy:1;
00707    /*!
00708     * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
00709     * \note Set from the "usesmdi" value read in from chan_dahdi.conf
00710     */
00711    unsigned int use_smdi:1;
00712 #if defined(HAVE_PRI)
00713    /*! \brief TRUE if the call has already gone/hungup */
00714    unsigned int alreadyhungup:1;
00715    /*!
00716     * \brief TRUE if this is an idle call
00717     * \note Applies to PRI channels.
00718     */
00719    unsigned int isidlecall:1;
00720    /*! \brief TRUE if the call has seen inband-information progress through the network. */
00721    unsigned int progress:1;
00722    /*!
00723     * \brief TRUE if this channel is being reset/restarted
00724     * \note Applies to PRI channels.
00725     */
00726    unsigned int resetting:1;
00727 
00728    /*! Call establishment life cycle level for simple comparisons. */
00729    enum dahdi_call_level call_level;
00730 #endif
00731    /*! \brief The serial port to listen for SMDI data on */
00732    struct ast_smdi_interface *smdi_iface;
00733 
00734    /*! \brief Distinctive Ring data */
00735    struct dahdi_distRings drings;
00736 
00737    /*!
00738     * \brief The configured context for incoming calls.
00739     * \note The "context" string read in from chan_dahdi.conf
00740     */
00741    char context[AST_MAX_CONTEXT];
00742    /*!
00743     * \brief Saved context string.
00744     */
00745    char defcontext[AST_MAX_CONTEXT];
00746    /*! \brief Extension to use in the dialplan. */
00747    char exten[AST_MAX_EXTENSION];
00748    /*!
00749     * \brief Language configured for calls.
00750     * \note The "language" string read in from chan_dahdi.conf
00751     */
00752    char language[MAX_LANGUAGE];
00753    /*!
00754     * \brief The configured music-on-hold class to use for calls.
00755     * \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
00756     */
00757    char mohinterpret[MAX_MUSICCLASS];
00758    /*!
00759     * \brief Sugggested music-on-hold class for peer channel to use for calls.
00760     * \note The "mohsuggest" string read in from chan_dahdi.conf
00761     */
00762    char mohsuggest[MAX_MUSICCLASS];
00763 #ifdef PRI_ANI
00764    /*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
00765    char cid_ani[AST_MAX_EXTENSION];
00766 #endif
00767    /*! \brief Caller ID number from an incoming call. */
00768    char cid_num[AST_MAX_EXTENSION];
00769    /*! \brief Caller ID Q.931 TON/NPI field values.  Set by PRI. Zero otherwise. */
00770    int cid_ton;
00771    /*! \brief Caller ID name from an incoming call. */
00772    char cid_name[AST_MAX_EXTENSION];
00773    /*! \brief Last Caller ID number from an incoming call. */
00774    char lastcid_num[AST_MAX_EXTENSION];
00775    /*! \brief Last Caller ID name from an incoming call. */
00776    char lastcid_name[AST_MAX_EXTENSION];
00777    char *origcid_num;            /*!< malloced original callerid */
00778    char *origcid_name;           /*!< malloced original callerid */
00779    /*! \brief Call waiting number. */
00780    char callwait_num[AST_MAX_EXTENSION];
00781    /*! \brief Call waiting name. */
00782    char callwait_name[AST_MAX_EXTENSION];
00783    /*! \brief Redirecting Directory Number Information Service (RDNIS) number */
00784    char rdnis[AST_MAX_EXTENSION];
00785    /*! \brief Dialed Number Identifier */
00786    char dnid[AST_MAX_EXTENSION];
00787    /*!
00788     * \brief Bitmapped groups this belongs to.
00789     * \note The "group" bitmapped group string read in from chan_dahdi.conf
00790     */
00791    ast_group_t group;
00792    /*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
00793    int law;
00794    int confno;             /*!< Our conference */
00795    int confusers;             /*!< Who is using our conference */
00796    int propconfno;               /*!< Propagated conference number */
00797    /*!
00798     * \brief Bitmapped call groups this belongs to.
00799     * \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
00800     */
00801    ast_group_t callgroup;
00802    /*!
00803     * \brief Bitmapped pickup groups this belongs to.
00804     * \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
00805     */
00806    ast_group_t pickupgroup;
00807    int channel;               /*!< Channel Number or CRV */
00808    int span;               /*!< Span number */
00809    time_t guardtime;          /*!< Must wait this much time before using for new call */
00810    int cid_signalling;           /*!< CID signalling type bell202 or v23 */
00811    int cid_start;             /*!< CID start indicator, polarity or ring */
00812    int callingpres;           /*!< The value of callling presentation that we're going to use when placing a PRI call */
00813    int callwaitingrepeat;           /*!< How many samples to wait before repeating call waiting */
00814    int cidcwexpire;           /*!< When to stop waiting for CID/CW CAS response (In samples) */
00815    int cid_suppress_expire;      /*!< How many samples to suppress after a CID spill. */
00816    /*! \brief Analog caller ID waveform sample buffer */
00817    unsigned char *cidspill;
00818    /*! \brief Position in the cidspill buffer to send out next. */
00819    int cidpos;
00820    /*! \brief Length of the cidspill buffer containing samples. */
00821    int cidlen;
00822    /*! \brief Ring timeout timer?? */
00823    int ringt;
00824    /*!
00825     * \brief Ring timeout base.
00826     * \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
00827     */
00828    int ringt_base;
00829    /*!
00830     * \brief Number of most significant digits/characters to strip from the dialed number.
00831     * \note Feature is deprecated.  Use dialplan logic.
00832     * \note The characters are stripped before the PRI TON/NPI prefix
00833     * characters are processed.
00834     */
00835    int stripmsd;
00836    /*!
00837     * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
00838     * \note
00839     * After CAS is sent, the call waiting caller id will be sent if the phone
00840     * gives a positive reply.
00841     */
00842    int callwaitcas;
00843    /*! \brief Number of call waiting rings. */
00844    int callwaitrings;
00845    /*! \brief Number of echo cancel taps.  0 if echo canceller not requested. */
00846    int echocancel;
00847    /*!
00848     * \brief Echo training time. 0 = disabled
00849     * \note Set from the "echotraining" value read in from chan_dahdi.conf
00850     */
00851    int echotraining;
00852    /*! \brief Filled with 'w'.  XXX Purpose?? */
00853    char echorest[20];
00854    /*!
00855     * \brief Number of times to see "busy" tone before hanging up.
00856     * \note Set from the "busycount" value read in from chan_dahdi.conf
00857     */
00858    int busycount;
00859    /*!
00860     * \brief Length of "busy" tone on time.
00861     * \note Set from the "busypattern" value read in from chan_dahdi.conf
00862     */
00863    int busy_tonelength;
00864    /*!
00865     * \brief Length of "busy" tone off time.
00866     * \note Set from the "busypattern" value read in from chan_dahdi.conf
00867     */
00868    int busy_quietlength;
00869    /*!
00870     * \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
00871     * \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
00872     */
00873    int callprogress;
00874    struct timeval flashtime;        /*!< Last flash-hook time */
00875    /*! \brief Opaque DSP configuration structure. */
00876    struct ast_dsp *dsp;
00877    //int cref;             /*!< Call reference number (Not used) */
00878    /*! \brief DAHDI dial operation command struct for ioctl() call. */
00879    struct dahdi_dialoperation dop;
00880    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00881    /*! \brief Second part of SIG_FEATDMF_TA wink operation. */
00882    char finaldial[64];
00883    char accountcode[AST_MAX_ACCOUNT_CODE];      /*!< Account code */
00884    int amaflags;              /*!< AMA Flags */
00885    struct tdd_state *tdd;           /*!< TDD flag */
00886    /*! \brief Accumulated call forwarding number. */
00887    char call_forward[AST_MAX_EXTENSION];
00888    /*!
00889     * \brief Voice mailbox location.
00890     * \note Set from the "mailbox" string read in from chan_dahdi.conf
00891     */
00892    char mailbox[AST_MAX_EXTENSION];
00893    /*! \brief Delayed dialing for E911.  Overlap digits for ISDN. */
00894    char dialdest[256];
00895    /*! \brief Time the interface went on-hook. */
00896    int onhooktime;
00897    /*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
00898    int msgstate;
00899    int distinctivering;          /*!< Which distinctivering to use */
00900    int cidrings;              /*!< Which ring to deliver CID on */
00901    int dtmfrelax;             /*!< whether to run in relaxed DTMF mode */
00902    /*! \brief Holding place for event injected from outside normal operation. */
00903    int fake_event;
00904    /*!
00905     * \brief Minimal time period (ms) between the answer polarity
00906     * switch and hangup polarity switch.
00907     */
00908    int polarityonanswerdelay;
00909    /*! \brief Start delay time if polarityonanswerdelay is nonzero. */
00910    struct timeval polaritydelaytv;
00911    /*!
00912     * \brief Send caller ID after this many rings.
00913     * \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
00914     */
00915    int sendcalleridafter;
00916 #ifdef HAVE_PRI
00917    /*! \brief DAHDI PRI control parameters */
00918    struct dahdi_pri *pri;
00919    /*! \brief XXX Purpose??? */
00920    struct dahdi_pvt *bearer;
00921    /*! \brief XXX Purpose??? */
00922    struct dahdi_pvt *realcall;
00923    /*! \brief Opaque libpri call control structure */
00924    q931_call *call;
00925    /*! \brief Channel number in span. */
00926    int prioffset;
00927    /*! \brief Logical span number within trunk group */
00928    int logicalspan;
00929 #endif   
00930    /*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
00931    int polarity;
00932    /*! \brief DSP feature flags: DSP_FEATURE_xxx */
00933    int dsp_features;
00934    /*! \brief DTMF digit in progress.  0 when no digit in progress. */
00935    char begindigit;
00936 } *iflist = NULL, *ifend = NULL;
00937 
00938 /*! \brief Channel configuration from chan_dahdi.conf .
00939  * This struct is used for parsing the [channels] section of chan_dahdi.conf.
00940  * Generally there is a field here for every possible configuration item.
00941  *
00942  * The state of fields is saved along the parsing and whenever a 'channel'
00943  * statement is reached, the current dahdi_chan_conf is used to configure the 
00944  * channel (struct dahdi_pvt)
00945  *
00946  * @seealso dahdi_chan_init for the default values.
00947  */
00948 struct dahdi_chan_conf {
00949    struct dahdi_pvt chan;
00950 #ifdef HAVE_PRI
00951    struct dahdi_pri pri;
00952 #endif
00953    struct dahdi_params timing;
00954 
00955    /*!
00956     * \brief The serial port to listen for SMDI data on
00957     * \note Set from the "smdiport" string read in from chan_dahdi.conf
00958     */
00959    char smdi_port[SMDI_MAX_FILENAME_LEN];
00960 };
00961 
00962 /** returns a new dahdi_chan_conf with default values (by-value) */
00963 static struct dahdi_chan_conf dahdi_chan_conf_default(void) {
00964    /* recall that if a field is not included here it is initialized
00965     * to 0 or equivalent
00966     */
00967    struct dahdi_chan_conf conf = {
00968 #ifdef HAVE_PRI
00969       .pri = {
00970          .nsf = PRI_NSF_NONE,
00971          .switchtype = PRI_SWITCH_NI2,
00972          .dialplan = PRI_NATIONAL_ISDN + 1,
00973          .localdialplan = PRI_NATIONAL_ISDN + 1,
00974          .nodetype = PRI_CPE,
00975 
00976          .minunused = 2,
00977          .idleext = "",
00978          .idledial = "",
00979          .internationalprefix = "",
00980          .nationalprefix = "",
00981          .localprefix = "",
00982          .privateprefix = "",
00983          .unknownprefix = "",
00984 
00985          .resetinterval = 3600
00986       },
00987 #endif
00988       .chan = {
00989          .context = "default",
00990          .cid_num = "",
00991          .cid_name = "",
00992          .mohinterpret = "default",
00993          .mohsuggest = "",
00994          .transfertobusy = 1,
00995 
00996          .cid_signalling = CID_SIG_BELL,
00997          .cid_start = CID_START_RING,
00998          .dahditrcallerid = 0,
00999          .use_callerid = 1,
01000          .sig = -1,
01001          .outsigmod = -1,
01002 
01003          .tonezone = -1,
01004 
01005          .echocancel = 1,
01006 
01007          .busycount = 3,
01008 
01009          .accountcode = "",
01010 
01011          .mailbox = "",
01012 
01013 
01014          .polarityonanswerdelay = 600,
01015 
01016          .sendcalleridafter = DEFAULT_CIDRINGS,
01017 
01018          .buf_policy = DAHDI_POLICY_IMMEDIATE,
01019          .buf_no = numbufs,
01020       },
01021       .timing = {
01022          .prewinktime = -1,
01023          .preflashtime = -1,
01024          .winktime = -1,
01025          .flashtime = -1,
01026          .starttime = -1,
01027          .rxwinktime = -1,
01028          .rxflashtime = -1,
01029          .debouncetime = -1
01030       },
01031       .smdi_port = "/dev/ttyS0",
01032    };
01033 
01034    return conf;
01035 }
01036 
01037 
01038 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
01039 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
01040 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
01041 static int dahdi_sendtext(struct ast_channel *c, const char *text);
01042 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
01043 static int dahdi_hangup(struct ast_channel *ast);
01044 static int dahdi_answer(struct ast_channel *ast);
01045 static struct ast_frame *dahdi_read(struct ast_channel *ast);
01046 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
01047 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
01048 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
01049 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
01050 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
01051 static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len); 
01052 static int dahdi_func_write(struct ast_channel *chan, char *function, char *data, const char *value);
01053 
01054 static const struct ast_channel_tech dahdi_tech = {
01055    .type = "DAHDI",
01056    .description = tdesc,
01057    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
01058    .requester = dahdi_request,
01059    .send_digit_begin = dahdi_digit_begin,
01060    .send_digit_end = dahdi_digit_end,
01061    .send_text = dahdi_sendtext,
01062    .call = dahdi_call,
01063    .hangup = dahdi_hangup,
01064    .answer = dahdi_answer,
01065    .read = dahdi_read,
01066    .write = dahdi_write,
01067    .bridge = dahdi_bridge,
01068    .exception = dahdi_exception,
01069    .indicate = dahdi_indicate,
01070    .fixup = dahdi_fixup,
01071    .setoption = dahdi_setoption,
01072    .func_channel_read = dahdi_func_read,
01073    .func_channel_write = dahdi_func_write,
01074 };
01075 
01076 static const struct ast_channel_tech zap_tech = {
01077    .type = "Zap",
01078    .description = tdesc,
01079    .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
01080    .requester = dahdi_request,
01081    .send_digit_begin = dahdi_digit_begin,
01082    .send_digit_end = dahdi_digit_end,
01083    .send_text = dahdi_sendtext,
01084    .call = dahdi_call,
01085    .hangup = dahdi_hangup,
01086    .answer = dahdi_answer,
01087    .read = dahdi_read,
01088    .write = dahdi_write,
01089    .bridge = dahdi_bridge,
01090    .exception = dahdi_exception,
01091    .indicate = dahdi_indicate,
01092    .fixup = dahdi_fixup,
01093    .setoption = dahdi_setoption,
01094    .func_channel_read = dahdi_func_read,
01095    .func_channel_write = dahdi_func_write,
01096 };
01097 
01098 static const struct ast_channel_tech *chan_tech;
01099 
01100 #ifdef HAVE_PRI
01101 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
01102 #else
01103 #define GET_CHANNEL(p) ((p)->channel)
01104 #endif
01105 
01106 struct dahdi_pvt *round_robin[32];
01107 
01108 #ifdef HAVE_PRI
01109 static inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri)
01110 {
01111    int res;
01112    /* Grab the lock first */
01113    do {
01114       res = ast_mutex_trylock(&pri->lock);
01115       if (res) {
01116          DEADLOCK_AVOIDANCE(&pvt->lock);
01117       }
01118    } while (res);
01119    /* Then break the poll */
01120    if (pri->master != AST_PTHREADT_NULL)
01121       pthread_kill(pri->master, SIGURG);
01122    return 0;
01123 }
01124 #endif
01125 
01126 #define NUM_CADENCE_MAX 25
01127 static int num_cadence = 4;
01128 static int user_has_defined_cadences = 0;
01129 
01130 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
01131    { { 125, 125, 2000, 4000 } },       /*!< Quick chirp followed by normal ring */
01132    { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
01133    { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
01134    { { 1000, 500, 2500, 5000 } },   /*!< Long ring */
01135 };
01136 
01137 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
01138  * is 1, the second pause is 2 and so on.
01139  */
01140 
01141 static int cidrings[NUM_CADENCE_MAX] = {
01142    2,                            /*!< Right after first long ring */
01143    4,                            /*!< Right after long part */
01144    3,                            /*!< After third chirp */
01145    2,                            /*!< Second spell */
01146 };
01147 
01148 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
01149          (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
01150 
01151 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
01152 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
01153 
01154 #define dahdi_get_index(ast, p, nullok)   _dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
01155 static int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
01156 {
01157    int res;
01158    if (p->subs[SUB_REAL].owner == ast)
01159       res = 0;
01160    else if (p->subs[SUB_CALLWAIT].owner == ast)
01161       res = 1;
01162    else if (p->subs[SUB_THREEWAY].owner == ast)
01163       res = 2;
01164    else {
01165       res = -1;
01166       if (!nullok)
01167          ast_log(LOG_WARNING,
01168             "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
01169             ast ? ast->name : "", p->channel, fname, line);
01170    }
01171    return res;
01172 }
01173 
01174 /*!
01175  * \internal
01176  * \brief Obtain the specified subchannel owner lock if the owner exists.
01177  *
01178  * \param pvt Channel private struct.
01179  * \param sub_idx Subchannel owner to lock.
01180  *
01181  * \note Assumes the pvt->lock is already obtained.
01182  *
01183  * \note
01184  * Because deadlock avoidance may have been necessary, you need to confirm
01185  * the state of things before continuing.
01186  *
01187  * \return Nothing
01188  */
01189 static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
01190 {
01191    for (;;) {
01192       if (!pvt->subs[sub_idx].owner) {
01193          /* No subchannel owner pointer */
01194          break;
01195       }
01196       if (!ast_mutex_trylock(&pvt->subs[sub_idx].owner->lock)) {
01197          /* Got subchannel owner lock */
01198          break;
01199       }
01200       /* We must unlock the private to avoid the possibility of a deadlock */
01201       DEADLOCK_AVOIDANCE(&pvt->lock);
01202    }
01203 }
01204 
01205 static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri)
01206 {
01207 #ifdef HAVE_PRI
01208    if (pri)
01209       ast_mutex_unlock(&pri->lock);
01210 #endif         
01211    dahdi_lock_sub_owner(p, a);
01212    if (p->subs[a].owner) {
01213       ast_queue_frame(p->subs[a].owner, &ast_null_frame);
01214       ast_mutex_unlock(&p->subs[a].owner->lock);
01215    }
01216 #ifdef HAVE_PRI
01217    if (pri)
01218       ast_mutex_lock(&pri->lock);
01219 #endif         
01220 }
01221 
01222 #ifdef HAVE_PRI
01223 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, struct dahdi_pri *pri)
01224 #else
01225 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *pri)
01226 #endif
01227 {
01228    /* We must unlock the PRI to avoid the possibility of a deadlock */
01229 #ifdef HAVE_PRI
01230    if (pri)
01231       ast_mutex_unlock(&pri->lock);
01232 #endif      
01233    for (;;) {
01234       if (p->owner) {
01235          if (ast_mutex_trylock(&p->owner->lock)) {
01236             DEADLOCK_AVOIDANCE(&p->lock);
01237          } else {
01238             ast_queue_frame(p->owner, f);
01239             ast_mutex_unlock(&p->owner->lock);
01240             break;
01241          }
01242       } else
01243          break;
01244    }
01245 #ifdef HAVE_PRI
01246    if (pri)
01247       ast_mutex_lock(&pri->lock);
01248 #endif      
01249 }
01250 
01251 static int restore_gains(struct dahdi_pvt *p);
01252 
01253 static void swap_subs(struct dahdi_pvt *p, int a, int b)
01254 {
01255    int tchan;
01256    int tinthreeway;
01257    struct ast_channel *towner;
01258 
01259    ast_log(LOG_DEBUG, "Swapping %d and %d\n", a, b);
01260 
01261    tchan = p->subs[a].chan;
01262    towner = p->subs[a].owner;
01263    tinthreeway = p->subs[a].inthreeway;
01264 
01265    p->subs[a].chan = p->subs[b].chan;
01266    p->subs[a].owner = p->subs[b].owner;
01267    p->subs[a].inthreeway = p->subs[b].inthreeway;
01268 
01269    p->subs[b].chan = tchan;
01270    p->subs[b].owner = towner;
01271    p->subs[b].inthreeway = tinthreeway;
01272 
01273    if (p->subs[a].owner) 
01274       p->subs[a].owner->fds[0] = p->subs[a].dfd;
01275    if (p->subs[b].owner) 
01276       p->subs[b].owner->fds[0] = p->subs[b].dfd;
01277    wakeup_sub(p, a, NULL);
01278    wakeup_sub(p, b, NULL);
01279 }
01280 
01281 static int dahdi_open(char *fn)
01282 {
01283    int fd;
01284    int isnum;
01285    int chan = 0;
01286    int bs;
01287    int x;
01288    isnum = 1;
01289    for (x = 0; x < strlen(fn); x++) {
01290       if (!isdigit(fn[x])) {
01291          isnum = 0;
01292          break;
01293       }
01294    }
01295    if (isnum) {
01296       chan = atoi(fn);
01297       if (chan < 1) {
01298          ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
01299          return -1;
01300       }
01301       fn = DAHDI_FILE_CHANNEL;
01302    }
01303    fd = open(fn, O_RDWR | O_NONBLOCK);
01304    if (fd < 0) {
01305       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
01306       return -1;
01307    }
01308    if (chan) {
01309       if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
01310          x = errno;
01311          close(fd);
01312          errno = x;
01313          ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
01314          return -1;
01315       }
01316    }
01317    bs = READ_SIZE;
01318    if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
01319       ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
01320       x = errno;
01321       close(fd);
01322       errno = x;
01323       return -1;
01324    }
01325    return fd;
01326 }
01327 
01328 static void dahdi_close(int fd)
01329 {
01330    if (fd > 0)
01331       close(fd);
01332 }
01333 
01334 static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
01335 {
01336    dahdi_close(chan_pvt->subs[sub_num].dfd);
01337    chan_pvt->subs[sub_num].dfd = -1;
01338 }
01339  
01340 #ifdef HAVE_PRI
01341 static void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num)
01342 {
01343    dahdi_close(pri->fds[fd_num]);
01344    pri->fds[fd_num] = -1;
01345 }
01346 #endif
01347 
01348 static int dahdi_setlinear(int dfd, int linear)
01349 {
01350    int res;
01351    res = ioctl(dfd, DAHDI_SETLINEAR, &linear);
01352    if (res)
01353       return res;
01354    return 0;
01355 }
01356 
01357 
01358 static int alloc_sub(struct dahdi_pvt *p, int x)
01359 {
01360    struct dahdi_bufferinfo bi;
01361    int res;
01362    if (p->subs[x].dfd < 0) {
01363       p->subs[x].dfd = dahdi_open(DAHDI_FILE_PSEUDO);
01364       if (p->subs[x].dfd > -1) {
01365          res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
01366          if (!res) {
01367             bi.txbufpolicy = p->buf_policy;
01368             bi.rxbufpolicy = p->buf_policy;
01369             bi.numbufs = p->buf_no;
01370             res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
01371             if (res < 0) {
01372                ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
01373             }
01374          } else 
01375             ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
01376          if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
01377             ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
01378             dahdi_close_sub(p, x);
01379             return -1;
01380          }
01381          if (option_debug)
01382             ast_log(LOG_DEBUG, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
01383          return 0;
01384       } else
01385          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
01386       return -1;
01387    }
01388    ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
01389    return -1;
01390 }
01391 
01392 static int unalloc_sub(struct dahdi_pvt *p, int x)
01393 {
01394    if (!x) {
01395       ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
01396       return -1;
01397    }
01398    ast_log(LOG_DEBUG, "Released sub %d of channel %d\n", x, p->channel);
01399    dahdi_close_sub(p, x);
01400    p->subs[x].linear = 0;
01401    p->subs[x].chan = 0;
01402    p->subs[x].owner = NULL;
01403    p->subs[x].inthreeway = 0;
01404    p->polarity = POLARITY_IDLE;
01405    memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
01406    return 0;
01407 }
01408 
01409 static int digit_to_dtmfindex(char digit)
01410 {
01411    if (isdigit(digit))
01412       return DAHDI_TONE_DTMF_BASE + (digit - '0');
01413    else if (digit >= 'A' && digit <= 'D')
01414       return DAHDI_TONE_DTMF_A + (digit - 'A');
01415    else if (digit >= 'a' && digit <= 'd')
01416       return DAHDI_TONE_DTMF_A + (digit - 'a');
01417    else if (digit == '*')
01418       return DAHDI_TONE_DTMF_s;
01419    else if (digit == '#')
01420       return DAHDI_TONE_DTMF_p;
01421    else
01422       return -1;
01423 }
01424 
01425 static int dahdi_digit_begin(struct ast_channel *chan, char digit)
01426 {
01427    struct dahdi_pvt *pvt;
01428    int index;
01429    int dtmf = -1;
01430    
01431    pvt = chan->tech_pvt;
01432 
01433    ast_mutex_lock(&pvt->lock);
01434 
01435    index = dahdi_get_index(chan, pvt, 0);
01436 
01437    if ((index != SUB_REAL) || !pvt->owner)
01438       goto out;
01439 
01440 #ifdef HAVE_PRI
01441    if (pvt->sig == SIG_PRI
01442       && chan->_state == AST_STATE_DIALING) {
01443       if (pvt->call_level < DAHDI_CALL_LEVEL_OVERLAP) {
01444          unsigned int len;
01445 
01446          len = strlen(pvt->dialdest);
01447          if (len < sizeof(pvt->dialdest) - 1) {
01448             ast_log(LOG_DEBUG,
01449                "Queueing digit '%c' since setup_ack not yet received\n", digit);
01450             pvt->dialdest[len++] = digit;
01451             pvt->dialdest[len] = '\0';
01452          } else {
01453             ast_log(LOG_WARNING,
01454                "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
01455                pvt->span, digit);
01456          }
01457          goto out;
01458       }
01459       if (pvt->call_level < DAHDI_CALL_LEVEL_PROCEEDING) {
01460          if (!pri_grab(pvt, pvt->pri)) {
01461             pri_information(pvt->pri->pri, pvt->call, digit);
01462             pri_rel(pvt->pri);
01463          } else {
01464             ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
01465          }
01466          goto out;
01467       }
01468       if (pvt->call_level < DAHDI_CALL_LEVEL_CONNECT) {
01469          ast_log(LOG_WARNING,
01470             "Span %d: Digit '%c' may be ignored by peer. (Call level:%d)\n",
01471             pvt->span, digit, pvt->call_level);
01472       }
01473    }
01474 #endif
01475    if ((dtmf = digit_to_dtmfindex(digit)) == -1)
01476       goto out;
01477 
01478    if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
01479       int res;
01480       struct dahdi_dialoperation zo = {
01481          .op = DAHDI_DIAL_OP_APPEND,
01482          .dialstr[0] = 'T',
01483          .dialstr[1] = digit,
01484          .dialstr[2] = 0,
01485       };
01486       if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo)))
01487          ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno));
01488       else
01489          pvt->dialing = 1;
01490    } else {
01491       ast_log(LOG_DEBUG, "Started VLDTMF digit '%c'\n", digit);
01492       pvt->dialing = 1;
01493       pvt->begindigit = digit;
01494    }
01495 
01496 out:
01497    ast_mutex_unlock(&pvt->lock);
01498 
01499    return 0;
01500 }
01501 
01502 static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
01503 {
01504    struct dahdi_pvt *pvt;
01505    int res = 0;
01506    int index;
01507    int x;
01508    
01509    pvt = chan->tech_pvt;
01510 
01511    ast_mutex_lock(&pvt->lock);
01512    
01513    index = dahdi_get_index(chan, pvt, 0);
01514 
01515    if ((index != SUB_REAL) || !pvt->owner || pvt->pulse)
01516       goto out;
01517 
01518 #ifdef HAVE_PRI
01519    /* This means that the digit was already sent via PRI signalling */
01520    if (pvt->sig == SIG_PRI && !pvt->begindigit)
01521       goto out;
01522 #endif
01523 
01524    if (pvt->begindigit) {
01525       x = -1;
01526       ast_log(LOG_DEBUG, "Ending VLDTMF digit '%c'\n", digit);
01527       res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
01528       pvt->dialing = 0;
01529       pvt->begindigit = 0;
01530    }
01531 
01532 out:
01533    ast_mutex_unlock(&pvt->lock);
01534 
01535    return res;
01536 }
01537 
01538 static char *events[] = {
01539    "No event",
01540    "On hook",
01541    "Ring/Answered",
01542    "Wink/Flash",
01543    "Alarm",
01544    "No more alarm",
01545    "HDLC Abort",
01546    "HDLC Overrun",
01547    "HDLC Bad FCS",
01548    "Dial Complete",
01549    "Ringer On",
01550    "Ringer Off",
01551    "Hook Transition Complete",
01552    "Bits Changed",
01553    "Pulse Start",
01554    "Timer Expired",
01555    "Timer Ping",
01556    "Polarity Reversal",
01557    "Ring Begin",
01558 };
01559 
01560 static struct {
01561    int alarm;
01562    char *name;
01563 } alarms[] = {
01564    { DAHDI_ALARM_RED, "Red Alarm" },
01565    { DAHDI_ALARM_YELLOW, "Yellow Alarm" },
01566    { DAHDI_ALARM_BLUE, "Blue Alarm" },
01567    { DAHDI_ALARM_RECOVER, "Recovering" },
01568    { DAHDI_ALARM_LOOPBACK, "Loopback" },
01569    { DAHDI_ALARM_NOTOPEN, "Not Open" },
01570    { DAHDI_ALARM_NONE, "None" },
01571 };
01572 
01573 static char *alarm2str(int alarm)
01574 {
01575    int x;
01576    for (x = 0; x < sizeof(alarms) / sizeof(alarms[0]); x++) {
01577       if (alarms[x].alarm & alarm)
01578          return alarms[x].name;
01579    }
01580    return alarm ? "Unknown Alarm" : "No Alarm";
01581 }
01582 
01583 static char *event2str(int event)
01584 {
01585    static char buf[256];
01586    if ((event < (sizeof(events) / sizeof(events[0]))) && (event > -1))
01587       return events[event];
01588    sprintf(buf, "Event %d", event); /* safe */
01589    return buf;
01590 }
01591 
01592 #ifdef HAVE_PRI
01593 static char *dialplan2str(int dialplan)
01594 {
01595    if (dialplan == -1) {
01596       return("Dynamically set dialplan in ISDN");
01597    }
01598    return (pri_plan2str(dialplan));
01599 }
01600 #endif
01601 
01602 static char *dahdi_sig2str(int sig)
01603 {
01604    static char buf[256];
01605    switch (sig) {
01606    case SIG_EM:
01607       return "E & M Immediate";
01608    case SIG_EMWINK:
01609       return "E & M Wink";
01610    case SIG_EM_E1:
01611       return "E & M E1";
01612    case SIG_FEATD:
01613       return "Feature Group D (DTMF)";
01614    case SIG_FEATDMF:
01615       return "Feature Group D (MF)";
01616    case SIG_FEATDMF_TA:
01617       return "Feature Groud D (MF) Tandem Access";
01618    case SIG_FEATB:
01619       return "Feature Group B (MF)";
01620    case SIG_E911:
01621       return "E911 (MF)";
01622    case SIG_FGC_CAMA:
01623       return "FGC/CAMA (Dialpulse)";
01624    case SIG_FGC_CAMAMF:
01625       return "FGC/CAMA (MF)";
01626    case SIG_FXSLS:
01627       return "FXS Loopstart";
01628    case SIG_FXSGS:
01629       return "FXS Groundstart";
01630    case SIG_FXSKS:
01631       return "FXS Kewlstart";
01632    case SIG_FXOLS:
01633       return "FXO Loopstart";
01634    case SIG_FXOGS:
01635       return "FXO Groundstart";
01636    case SIG_FXOKS:
01637       return "FXO Kewlstart";
01638    case SIG_PRI:
01639       return "ISDN PRI";
01640    case SIG_SF:
01641       return "SF (Tone) Immediate";
01642    case SIG_SFWINK:
01643       return "SF (Tone) Wink";
01644    case SIG_SF_FEATD:
01645       return "SF (Tone) with Feature Group D (DTMF)";
01646    case SIG_SF_FEATDMF:
01647       return "SF (Tone) with Feature Group D (MF)";
01648    case SIG_SF_FEATB:
01649       return "SF (Tone) with Feature Group B (MF)";
01650    case SIG_GR303FXOKS:
01651       return "GR-303 with FXOKS";
01652    case SIG_GR303FXSKS:
01653       return "GR-303 with FXSKS";
01654    case 0:
01655       return "Pseudo";
01656    default:
01657       snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
01658       return buf;
01659    }
01660 }
01661 
01662 #define sig2str dahdi_sig2str
01663 
01664 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
01665 {
01666    /* If the conference already exists, and we're already in it
01667       don't bother doing anything */
01668    struct dahdi_confinfo zi;
01669    
01670    memset(&zi, 0, sizeof(zi));
01671    zi.chan = 0;
01672 
01673    if (slavechannel > 0) {
01674       /* If we have only one slave, do a digital mon */
01675       zi.confmode = DAHDI_CONF_DIGITALMON;
01676       zi.confno = slavechannel;
01677    } else {
01678       if (!index) {
01679          /* Real-side and pseudo-side both participate in conference */
01680          zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
01681             DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
01682       } else
01683          zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
01684       zi.confno = p->confno;
01685    }
01686    if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
01687       return 0;
01688    if (c->dfd < 0)
01689       return 0;
01690    if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
01691       ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
01692       return -1;
01693    }
01694    if (slavechannel < 1) {
01695       p->confno = zi.confno;
01696    }
01697    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01698    ast_log(LOG_DEBUG, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
01699    return 0;
01700 }
01701 
01702 static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
01703 {
01704    /* If they're listening to our channel, they're ours */  
01705    if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
01706       return 1;
01707    /* If they're a talker on our (allocated) conference, they're ours */
01708    if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
01709       return 1;
01710    return 0;
01711 }
01712 
01713 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
01714 {
01715    struct dahdi_confinfo zi;
01716    if (/* Can't delete if there's no dfd */
01717       (c->dfd < 0) ||
01718       /* Don't delete from the conference if it's not our conference */
01719       !isourconf(p, c)
01720       /* Don't delete if we don't think it's conferenced at all (implied) */
01721       ) return 0;
01722    memset(&zi, 0, sizeof(zi));
01723    if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
01724       ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
01725       return -1;
01726    }
01727    ast_log(LOG_DEBUG, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
01728    memcpy(&c->curconf, &zi, sizeof(c->curconf));
01729    return 0;
01730 }
01731 
01732 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
01733 {
01734    int x;
01735    int useslavenative;
01736    struct dahdi_pvt *slave = NULL;
01737    /* Start out optimistic */
01738    useslavenative = 1;
01739    /* Update conference state in a stateless fashion */
01740    for (x = 0; x < 3; x++) {
01741       /* Any three-way calling makes slave native mode *definitely* out
01742          of the question */
01743       if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
01744          useslavenative = 0;
01745    }
01746    /* If we don't have any 3-way calls, check to see if we have
01747       precisely one slave */
01748    if (useslavenative) {
01749       for (x = 0; x < MAX_SLAVES; x++) {
01750          if (p->slaves[x]) {
01751             if (slave) {
01752                /* Whoops already have a slave!  No 
01753                   slave native and stop right away */
01754                slave = NULL;
01755                useslavenative = 0;
01756                break;
01757             } else {
01758                /* We have one slave so far */
01759                slave = p->slaves[x];
01760             }
01761          }
01762       }
01763    }
01764    /* If no slave, slave native definitely out */
01765    if (!slave)
01766       useslavenative = 0;
01767    else if (slave->law != p->law) {
01768       useslavenative = 0;
01769       slave = NULL;
01770    }
01771    if (out)
01772       *out = slave;
01773    return useslavenative;
01774 }
01775 
01776 static int reset_conf(struct dahdi_pvt *p)
01777 {
01778    p->confno = -1;
01779    memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
01780    if (p->subs[SUB_REAL].dfd > -1) {
01781       struct dahdi_confinfo zi;
01782 
01783       memset(&zi, 0, sizeof(zi));
01784       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
01785          ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
01786    }
01787    return 0;
01788 }
01789 
01790 static int update_conf(struct dahdi_pvt *p)
01791 {
01792    int needconf = 0;
01793    int x;
01794    int useslavenative;
01795    struct dahdi_pvt *slave = NULL;
01796 
01797    useslavenative = isslavenative(p, &slave);
01798    /* Start with the obvious, general stuff */
01799    for (x = 0; x < 3; x++) {
01800       /* Look for three way calls */
01801       if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
01802          conf_add(p, &p->subs[x], x, 0);
01803          needconf++;
01804       } else {
01805          conf_del(p, &p->subs[x], x);
01806       }
01807    }
01808    /* If we have a slave, add him to our conference now. or DAX
01809       if this is slave native */
01810    for (x = 0; x < MAX_SLAVES; x++) {
01811       if (p->slaves[x]) {
01812          if (useslavenative)
01813             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
01814          else {
01815             conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
01816             needconf++;
01817          }
01818       }
01819    }
01820    /* If we're supposed to be in there, do so now */
01821    if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
01822       if (useslavenative)
01823          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
01824       else {
01825          conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
01826          needconf++;
01827       }
01828    }
01829    /* If we have a master, add ourselves to his conference */
01830    if (p->master) {
01831       if (isslavenative(p->master, NULL)) {
01832          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
01833       } else {
01834          conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
01835       }
01836    }
01837    if (!needconf) {
01838       /* Nobody is left (or should be left) in our conference.
01839          Kill it. */
01840       p->confno = -1;
01841    }
01842    if (option_debug)
01843       ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
01844    return 0;
01845 }
01846 
01847 static void dahdi_enable_ec(struct dahdi_pvt *p)
01848 {
01849    int x;
01850    int res;
01851    if (!p)
01852       return;
01853    if (p->echocanon) {
01854       ast_log(LOG_DEBUG, "Echo cancellation already on\n");
01855       return;
01856    }
01857    if (p->digital) {
01858       ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
01859       return;
01860    }
01861    if (p->echocancel) {
01862       if (p->sig == SIG_PRI) {
01863          x = 1;
01864          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
01865          if (res)
01866             ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
01867       }
01868       x = p->echocancel;
01869       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);
01870       if (res) 
01871          ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
01872       else {
01873          p->echocanon = 1;
01874          if (option_debug)
01875             ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
01876       }
01877    } else if (option_debug)
01878       ast_log(LOG_DEBUG, "No echo cancellation requested\n");
01879 }
01880 
01881 static void dahdi_train_ec(struct dahdi_pvt *p)
01882 {
01883    int x;
01884    int res;
01885    if (p && p->echocancel && p->echotraining) {
01886       x = p->echotraining;
01887       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
01888       if (res)
01889          ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
01890       else {
01891          ast_log(LOG_DEBUG, "Engaged echo training on channel %d\n", p->channel);
01892       }
01893    } else
01894       ast_log(LOG_DEBUG, "No echo training requested\n");
01895 }
01896 
01897 static void dahdi_disable_ec(struct dahdi_pvt *p)
01898 {
01899    int x;
01900    int res;
01901    if (p->echocancel) {
01902       x = 0;
01903       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL, &x);
01904       if (res)
01905          ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
01906       else if (option_debug)
01907          ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
01908    }
01909    p->echocanon = 0;
01910 }
01911 
01912 static void fill_txgain(struct dahdi_gains *g, float gain, int law)
01913 {
01914    int j;
01915    int k;
01916    float linear_gain = pow(10.0, gain / 20.0);
01917 
01918    switch (law) {
01919    case DAHDI_LAW_ALAW:
01920       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01921          if (gain) {
01922             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01923             if (k > 32767) k = 32767;
01924             if (k < -32767) k = -32767;
01925             g->txgain[j] = AST_LIN2A(k);
01926          } else {
01927             g->txgain[j] = j;
01928          }
01929       }
01930       break;
01931    case DAHDI_LAW_MULAW:
01932       for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
01933          if (gain) {
01934             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01935             if (k > 32767) k = 32767;
01936             if (k < -32767) k = -32767;
01937             g->txgain[j] = AST_LIN2MU(k);
01938          } else {
01939             g->txgain[j] = j;
01940          }
01941       }
01942       break;
01943    }
01944 }
01945 
01946 static void fill_rxgain(struct dahdi_gains *g, float gain, int law)
01947 {
01948    int j;
01949    int k;
01950    float linear_gain = pow(10.0, gain / 20.0);
01951 
01952    switch (law) {
01953    case DAHDI_LAW_ALAW:
01954       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01955          if (gain) {
01956             k = (int) (((float) AST_ALAW(j)) * linear_gain);
01957             if (k > 32767) k = 32767;
01958             if (k < -32767) k = -32767;
01959             g->rxgain[j] = AST_LIN2A(k);
01960          } else {
01961             g->rxgain[j] = j;
01962          }
01963       }
01964       break;
01965    case DAHDI_LAW_MULAW:
01966       for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
01967          if (gain) {
01968             k = (int) (((float) AST_MULAW(j)) * linear_gain);
01969             if (k > 32767) k = 32767;
01970             if (k < -32767) k = -32767;
01971             g->rxgain[j] = AST_LIN2MU(k);
01972          } else {
01973             g->rxgain[j] = j;
01974          }
01975       }
01976       break;
01977    }
01978 }
01979 
01980 static int set_actual_txgain(int fd, int chan, float gain, int law)
01981 {
01982    struct dahdi_gains g;
01983    int res;
01984 
01985    memset(&g, 0, sizeof(g));
01986    g.chan = chan;
01987    res = ioctl(fd, DAHDI_GETGAINS, &g);
01988    if (res) {
01989       if (option_debug)
01990          ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
01991       return res;
01992    }
01993 
01994    fill_txgain(&g, gain, law);
01995 
01996    return ioctl(fd, DAHDI_SETGAINS, &g);
01997 }
01998 
01999 static int set_actual_rxgain(int fd, int chan, float gain, int law)
02000 {
02001    struct dahdi_gains g;
02002    int res;
02003 
02004    memset(&g, 0, sizeof(g));
02005    g.chan = chan;
02006    res = ioctl(fd, DAHDI_GETGAINS, &g);
02007    if (res) {
02008       ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
02009       return res;
02010    }
02011 
02012    fill_rxgain(&g, gain, law);
02013 
02014    return ioctl(fd, DAHDI_SETGAINS, &g);
02015 }
02016 
02017 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
02018 {
02019    return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
02020 }
02021 
02022 static int bump_gains(struct dahdi_pvt *p)
02023 {
02024    int res;
02025 
02026    /* Bump receive gain by 5.0db */
02027    res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain + 5.0, p->txgain, p->law);
02028    if (res) {
02029       ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
02030       return -1;
02031    }
02032 
02033    return 0;
02034 }
02035 
02036 static int restore_gains(struct dahdi_pvt *p)
02037 {
02038    int res;
02039 
02040    res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
02041    if (res) {
02042       ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
02043       return -1;
02044    }
02045 
02046    return 0;
02047 }
02048 
02049 static inline int dahdi_set_hook(int fd, int hs)
02050 {
02051    int x, res;
02052 
02053    x = hs;
02054    res = ioctl(fd, DAHDI_HOOK, &x);
02055 
02056    if (res < 0) {
02057       if (errno == EINPROGRESS)
02058          return 0;
02059       ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
02060       /* will expectedly fail if phone is off hook during operation, such as during a restart */
02061    }
02062 
02063    return res;
02064 }
02065 
02066 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
02067 {
02068    int x, y, res;
02069    x = muted;
02070    if (p->sig == SIG_PRI) {
02071       y = 1;
02072       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
02073       if (res)
02074          ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", p->channel, strerror(errno));
02075    }
02076    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
02077    if (res < 0)
02078       ast_log(LOG_WARNING, "dahdi confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
02079    return res;
02080 }
02081 
02082 static int save_conference(struct dahdi_pvt *p)
02083 {
02084    struct dahdi_confinfo c;
02085    int res;
02086    if (p->saveconf.confmode) {
02087       ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
02088       return -1;
02089    }
02090    p->saveconf.chan = 0;
02091    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
02092    if (res) {
02093       ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
02094       p->saveconf.confmode = 0;
02095       return -1;
02096    }
02097    memset(&c, 0, sizeof(c));
02098    c.confmode = DAHDI_CONF_NORMAL;
02099    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
02100    if (res) {
02101       ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
02102       return -1;
02103    }
02104    if (option_debug)
02105       ast_log(LOG_DEBUG, "Disabled conferencing\n");
02106    return 0;
02107 }
02108 
02109 static int restore_conference(struct dahdi_pvt *p)
02110 {
02111    int res;
02112    if (p->saveconf.confmode) {
02113       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
02114       p->saveconf.confmode = 0;
02115       if (res) {
02116          ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
02117          return -1;
02118       }
02119       if (option_debug)
02120          ast_log(LOG_DEBUG, "Restored conferencing\n");
02121    }
02122    return 0;
02123 }
02124 
02125 static int send_callerid(struct dahdi_pvt *p);
02126 
02127 static int send_cwcidspill(struct dahdi_pvt *p)
02128 {
02129    p->callwaitcas = 0;
02130    p->cidcwexpire = 0;
02131    p->cid_suppress_expire = 0;
02132    if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
02133       return -1;
02134    p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
02135    /* Make sure we account for the end */
02136    p->cidlen += READ_SIZE * 4;
02137    p->cidpos = 0;
02138    send_callerid(p);
02139    if (option_verbose > 2)
02140       ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
02141    return 0;
02142 }
02143 
02144 static int has_voicemail(struct dahdi_pvt *p)
02145 {
02146 
02147    return ast_app_has_voicemail(p->mailbox, NULL);
02148 }
02149 
02150 static int send_callerid(struct dahdi_pvt *p)
02151 {
02152    /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
02153    int res;
02154    /* Take out of linear mode if necessary */
02155    if (p->subs[SUB_REAL].linear) {
02156       p->subs[SUB_REAL].linear = 0;
02157       dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
02158    }
02159    while (p->cidpos < p->cidlen) {
02160       res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
02161       if (res < 0) {
02162          if (errno == EAGAIN)
02163             return 0;
02164          else {
02165             ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
02166             return -1;
02167          }
02168       }
02169       if (!res)
02170          return 0;
02171       p->cidpos += res;
02172    }
02173    p->cid_suppress_expire = CALLWAITING_SUPPRESS_SAMPLES;
02174    free(p->cidspill);
02175    p->cidspill = NULL;
02176    if (p->callwaitcas) {
02177       /* Wait for CID/CW to expire */
02178       p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
02179       p->cid_suppress_expire = p->cidcwexpire;
02180    } else
02181       restore_conference(p);
02182    return 0;
02183 }
02184 
02185 static int dahdi_callwait(struct ast_channel *ast)
02186 {
02187    struct dahdi_pvt *p = ast->tech_pvt;
02188    p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
02189    if (p->cidspill) {
02190       ast_log(LOG_WARNING, "Spill already exists?!?\n");
02191       free(p->cidspill);
02192    }
02193 
02194    /*
02195     * SAS: Subscriber Alert Signal, 440Hz for 300ms
02196     * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
02197     */
02198    if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
02199       return -1;
02200    save_conference(p);
02201    /* Silence */
02202    memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
02203    if (!p->callwaitrings && p->callwaitingcallerid) {
02204       ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
02205       p->callwaitcas = 1;
02206       p->cidlen = 2400 + 680 + READ_SIZE * 4;
02207    } else {
02208       ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
02209       p->callwaitcas = 0;
02210       p->cidlen = 2400 + READ_SIZE * 4;
02211    }
02212    p->cidpos = 0;
02213    send_callerid(p);
02214    
02215    return 0;
02216 }
02217 
02218 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
02219 {
02220    struct dahdi_pvt *p = ast->tech_pvt;
02221    int x, res, index,mysig;
02222    char *c, *n, *l;
02223 #ifdef HAVE_PRI
02224    char *s = NULL;
02225 #endif
02226    char dest[256]; /* must be same length as p->dialdest */
02227    ast_mutex_lock(&p->lock);
02228    ast_copy_string(dest, rdest, sizeof(dest));
02229    ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
02230    if ((ast->_state == AST_STATE_BUSY)) {
02231       p->subs[SUB_REAL].needbusy = 1;
02232       ast_mutex_unlock(&p->lock);
02233       return 0;
02234    }
02235    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
02236       ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name);
02237       ast_mutex_unlock(&p->lock);
02238       return -1;
02239    }
02240    p->dialednone = 0;
02241    if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
02242    {
02243       /* Special pseudo -- automatically up */
02244       ast_setstate(ast, AST_STATE_UP); 
02245       ast_mutex_unlock(&p->lock);
02246       return 0;
02247    }
02248    x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
02249    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
02250    if (res)
02251       ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
02252    p->outgoing = 1;
02253 
02254    if (IS_DIGITAL(ast->transfercapability)) {
02255       set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, 0, p->law);
02256    } else {
02257       set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
02258    }
02259 
02260    mysig = p->sig;
02261    if (p->outsigmod > -1)
02262       mysig = p->outsigmod;
02263 
02264    switch (mysig) {
02265    case SIG_FXOLS:
02266    case SIG_FXOGS:
02267    case SIG_FXOKS:
02268       if (p->owner == ast) {
02269          /* Normal ring, on hook */
02270          
02271          /* Don't send audio while on hook, until the call is answered */
02272          p->dialing = 1;
02273          if (p->use_callerid) {
02274             /* Generate the Caller-ID spill if desired */
02275             if (p->cidspill) {
02276                ast_log(LOG_WARNING, "cidspill already exists??\n");
02277                free(p->cidspill);
02278             }
02279             p->callwaitcas = 0;
02280             if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
02281                p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
02282                p->cidpos = 0;
02283                send_callerid(p);
02284             }
02285          }
02286          /* Choose proper cadence */
02287          if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
02288             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
02289                ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
02290             p->cidrings = cidrings[p->distinctivering - 1];
02291          } else {
02292             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
02293                ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
02294             p->cidrings = p->sendcalleridafter;
02295          }
02296 
02297          /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
02298          c = strchr(dest, '/');
02299          if (c)
02300             c++;
02301          if (c && (strlen(c) < p->stripmsd)) {
02302             ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02303             c = NULL;
02304          }
02305          if (c) {
02306             p->dop.op = DAHDI_DIAL_OP_REPLACE;
02307             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
02308             ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
02309          } else {
02310             p->dop.dialstr[0] = '\0';
02311          }
02312          x = DAHDI_RING;
02313          if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x) && (errno != EINPROGRESS)) {
02314             ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
02315             ast_mutex_unlock(&p->lock);
02316             return -1;
02317          }
02318          p->dialing = 1;
02319       } else {
02320          /* Call waiting call */
02321          p->callwaitrings = 0;
02322          if (ast->cid.cid_num)
02323             ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
02324          else
02325             p->callwait_num[0] = '\0';
02326          if (ast->cid.cid_name)
02327             ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
02328          else
02329             p->callwait_name[0] = '\0';
02330          /* Call waiting tone instead */
02331          if (dahdi_callwait(ast)) {
02332             ast_mutex_unlock(&p->lock);
02333             return -1;
02334          }
02335          /* Make ring-back */
02336          if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].dfd, DAHDI_TONE_RINGTONE))
02337             ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
02338             
02339       }
02340       n = ast->cid.cid_name;
02341       l = ast->cid.cid_num;
02342       if (l)
02343          ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
02344       else
02345          p->lastcid_num[0] = '\0';
02346       if (n)
02347          ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
02348       else
02349          p->lastcid_name[0] = '\0';
02350       ast_setstate(ast, AST_STATE_RINGING);
02351       index = dahdi_get_index(ast, p, 0);
02352       if (index > -1) {
02353          p->subs[index].needringing = 1;
02354       }
02355       break;
02356    case SIG_FXSLS:
02357    case SIG_FXSGS:
02358    case SIG_FXSKS:
02359    case SIG_EMWINK:
02360    case SIG_EM:
02361    case SIG_EM_E1:
02362    case SIG_FEATD:
02363    case SIG_FEATDMF:
02364    case SIG_E911:
02365    case SIG_FGC_CAMA:
02366    case SIG_FGC_CAMAMF:
02367    case SIG_FEATB:
02368    case SIG_SFWINK:
02369    case SIG_SF:
02370    case SIG_SF_FEATD:
02371    case SIG_SF_FEATDMF:
02372    case SIG_FEATDMF_TA:
02373    case SIG_SF_FEATB:
02374       c = strchr(dest, '/');
02375       if (c)
02376          c++;
02377       else
02378          c = "";
02379       if (strlen(c) < p->stripmsd) {
02380          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02381          ast_mutex_unlock(&p->lock);
02382          return -1;
02383       }
02384 #ifdef HAVE_PRI
02385       /* Start the trunk, if not GR-303 */
02386       if (!p->pri) {
02387 #endif
02388          x = DAHDI_START;
02389          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
02390          if (res < 0) {
02391             if (errno != EINPROGRESS) {
02392                ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
02393                ast_mutex_unlock(&p->lock);
02394                return -1;
02395             }
02396          }
02397 #ifdef HAVE_PRI
02398       }
02399 #endif
02400       ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
02401       p->dop.op = DAHDI_DIAL_OP_REPLACE;
02402 
02403       c += p->stripmsd;
02404 
02405       switch (mysig) {
02406       case SIG_FEATD:
02407          l = ast->cid.cid_num;
02408          if (l) 
02409             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
02410          else
02411             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
02412          break;
02413       case SIG_FEATDMF:
02414          l = ast->cid.cid_num;
02415          if (l) 
02416             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
02417          else
02418             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
02419          break;
02420       case SIG_FEATDMF_TA:
02421       {
02422          const char *cic, *ozz;
02423 
02424          /* If you have to go through a Tandem Access point you need to use this */
02425          ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
02426          if (!ozz)
02427             ozz = defaultozz;
02428          cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
02429          if (!cic)
02430             cic = defaultcic;
02431          if (!ozz || !cic) {
02432             ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
02433             ast_mutex_unlock(&p->lock);
02434             return -1;
02435          }
02436          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
02437          snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
02438          p->whichwink = 0;
02439       }
02440          break;
02441       case SIG_E911:
02442          ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
02443          break;
02444       case SIG_FGC_CAMA:
02445          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
02446          break;
02447       case SIG_FGC_CAMAMF:
02448       case SIG_FEATB:
02449          snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
02450          break;
02451       default:
02452          if (p->pulse)
02453             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
02454          else
02455             snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
02456          break;
02457       }
02458 
02459       if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
02460          memset(p->echorest, 'w', sizeof(p->echorest) - 1);
02461          strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
02462          p->echorest[sizeof(p->echorest) - 1] = '\0';
02463          p->echobreak = 1;
02464          p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
02465       } else
02466          p->echobreak = 0;
02467       if (!res) {
02468          if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
02469             int saveerr = errno;
02470 
02471             x = DAHDI_ONHOOK;
02472             ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
02473             ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
02474             ast_mutex_unlock(&p->lock);
02475             return -1;
02476          }
02477       } else
02478          ast_log(LOG_DEBUG, "Deferring dialing... (res %d)\n", res);
02479       p->dialing = 1;
02480       if (ast_strlen_zero(c))
02481          p->dialednone = 1;
02482       ast_setstate(ast, AST_STATE_DIALING);
02483       break;
02484    case 0:
02485       /* Special pseudo -- automatically up*/
02486       ast_setstate(ast, AST_STATE_UP);
02487       break;      
02488    case SIG_PRI:
02489       /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
02490       p->dialdest[0] = '\0';
02491       p->dialing = 1;
02492       break;
02493    default:
02494       ast_log(LOG_DEBUG, "not yet implemented\n");
02495       ast_mutex_unlock(&p->lock);
02496       return -1;
02497    }
02498 #ifdef HAVE_PRI
02499    if (p->pri) {
02500       struct pri_sr *sr;
02501 #ifdef SUPPORT_USERUSER
02502       const char *useruser;
02503 #endif
02504       int pridialplan;
02505       int dp_strip;
02506       int prilocaldialplan;
02507       int ldp_strip;
02508       int exclusive;
02509       const char *rr_str;
02510       int redirect_reason;
02511 
02512       c = strchr(dest, '/');
02513       if (c) {
02514          c++;
02515       } else {
02516          c = "";
02517       }
02518 
02519       l = NULL;
02520       n = NULL;
02521       if (!p->hidecallerid) {
02522          l = ast->cid.cid_num;
02523          if (!p->hidecalleridname) {
02524             n = ast->cid.cid_name;
02525          }
02526       }
02527 
02528 
02529       if (strlen(c) < p->stripmsd) {
02530          ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
02531          ast_mutex_unlock(&p->lock);
02532          return -1;
02533       }
02534       if (mysig != SIG_FXSKS) {
02535          p->dop.op = DAHDI_DIAL_OP_REPLACE;
02536          s = strchr(c + p->stripmsd, 'w');
02537          if (s) {
02538             if (strlen(s) > 1)
02539                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
02540             else
02541                p->dop.dialstr[0] = '\0';
02542             *s = '\0';
02543          } else {
02544             p->dop.dialstr[0] = '\0';
02545          }
02546       }
02547       if (pri_grab(p, p->pri)) {
02548          ast_log(LOG_WARNING, "Failed to grab PRI!\n");
02549          ast_mutex_unlock(&p->lock);
02550          return -1;
02551       }
02552       if (!(p->call = pri_new_call(p->pri->pri))) {
02553          ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
02554          pri_rel(p->pri);
02555          ast_mutex_unlock(&p->lock);
02556          return -1;
02557       }
02558       if (!(sr = pri_sr_new())) {
02559          ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
02560          pri_destroycall(p->pri->pri, p->call);
02561          p->call = NULL;
02562          pri_rel(p->pri);
02563          ast_mutex_unlock(&p->lock);
02564          return -1;
02565       }
02566       if (p->bearer || (mysig == SIG_FXSKS)) {
02567          if (p->bearer) {
02568             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);
02569             p->bearer->call = p->call;
02570          } else
02571             ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
02572          pri_set_crv(p->pri->pri, p->call, p->channel, 0);
02573       }
02574       p->digital = IS_DIGITAL(ast->transfercapability);
02575 
02576       /* Should the picked channel be used exclusively? */
02577       if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
02578          exclusive = 1;
02579       } else {
02580          exclusive = 0;
02581       }
02582       
02583       pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
02584       pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
02585                (p->digital ? -1 : 
02586                   ((p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
02587       if (p->pri->facilityenable)
02588          pri_facility_enable(p->pri->pri);
02589 
02590       if (option_verbose > 2)
02591          ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
02592       dp_strip = 0;
02593       pridialplan = p->pri->dialplan - 1;
02594       if (pridialplan == -2) { /* compute dynamically */
02595          if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02596             dp_strip = strlen(p->pri->internationalprefix);
02597             pridialplan = PRI_INTERNATIONAL_ISDN;
02598          } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02599             dp_strip = strlen(p->pri->nationalprefix);
02600             pridialplan = PRI_NATIONAL_ISDN;
02601          } else {
02602             pridialplan = PRI_LOCAL_ISDN;
02603          }
02604       }
02605       pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
02606 
02607       ldp_strip = 0;
02608       prilocaldialplan = p->pri->localdialplan - 1;
02609       if ((l != NULL) && (prilocaldialplan == -2)) { /* compute dynamically */
02610          if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
02611             ldp_strip = strlen(p->pri->internationalprefix);
02612             prilocaldialplan = PRI_INTERNATIONAL_ISDN;
02613          } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
02614             ldp_strip = strlen(p->pri->nationalprefix);
02615             prilocaldialplan = PRI_NATIONAL_ISDN;
02616          } else {
02617             prilocaldialplan = PRI_LOCAL_ISDN;
02618          }
02619       }
02620       pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
02621          p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
02622       if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
02623          if (!strcasecmp(rr_str, "UNKNOWN"))
02624             redirect_reason = 0;
02625          else if (!strcasecmp(rr_str, "BUSY"))
02626             redirect_reason = 1;
02627          else if (!strcasecmp(rr_str, "NO_REPLY"))
02628             redirect_reason = 2;
02629          else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
02630             redirect_reason = 15;
02631          else
02632             redirect_reason = PRI_REDIR_UNCONDITIONAL;
02633       } else
02634          redirect_reason = PRI_REDIR_UNCONDITIONAL;
02635       pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
02636 
02637 #ifdef SUPPORT_USERUSER
02638       /* User-user info */
02639       useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
02640 
02641       if (useruser)
02642          pri_sr_set_useruser(sr, useruser);
02643 #endif
02644 
02645       if (pri_setup(p->pri->pri, p->call, sr)) {
02646          ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
02647             c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
02648          pri_destroycall(p->pri->pri, p->call);
02649          p->call = NULL;
02650          pri_rel(p->pri);
02651          ast_mutex_unlock(&p->lock);
02652          pri_sr_free(sr);
02653          return -1;
02654       }
02655       p->call_level = DAHDI_CALL_LEVEL_SETUP;
02656       pri_sr_free(sr);
02657       ast_setstate(ast, AST_STATE_DIALING);
02658       pri_rel(p->pri);
02659    }
02660 #endif      
02661    ast_mutex_unlock(&p->lock);
02662    return 0;
02663 }
02664 
02665 static void destroy_dahdi_pvt(struct dahdi_pvt **pvt)
02666 {
02667    struct dahdi_pvt *p = *pvt;
02668    /* Remove channel from the list */
02669    if (p->prev)
02670       p->prev->next = p->next;
02671    if (p->next)
02672       p->next->prev = p->prev;
02673 
02674    free(p->cidspill);
02675    if (p->use_smdi)
02676       ast_smdi_interface_unref(p->smdi_iface);
02677    ast_mutex_destroy(&p->lock);
02678    dahdi_close_sub(p, SUB_REAL);
02679    if (p->owner)
02680       p->owner->tech_pvt = NULL;
02681    free(p);
02682    *pvt = NULL;
02683 }
02684 
02685 static int destroy_channel(struct dahdi_pvt *prev, struct dahdi_pvt *cur, int now)
02686 {
02687    int owned = 0;
02688    int i = 0;
02689 
02690    if (!now) {
02691       if (cur->owner) {
02692          owned = 1;
02693       }
02694 
02695       for (i = 0; i < 3; i++) {
02696          if (cur->subs[i].owner) {
02697             owned = 1;
02698          }
02699       }
02700       if (!owned) {
02701          if (prev) {
02702             prev->next = cur->next;
02703             if (prev->next)
02704                prev->next->prev = prev;
02705             else
02706                ifend = prev;
02707          } else {
02708             iflist = cur->next;
02709             if (iflist)
02710                iflist->prev = NULL;
02711             else
02712                ifend = NULL;
02713          }
02714          destroy_dahdi_pvt(&cur);
02715       }
02716    } else {
02717       if (prev) {
02718          prev->next = cur->next;
02719          if (prev->next)
02720             prev->next->prev = prev;
02721          else
02722             ifend = prev;
02723       } else {
02724          iflist = cur->next;
02725          if (iflist)
02726             iflist->prev = NULL;
02727          else
02728             ifend = NULL;
02729       }
02730       destroy_dahdi_pvt(&cur);
02731    }
02732    return 0;
02733 }
02734 
02735 static void destroy_all_channels(void)
02736 {
02737    int x;
02738    struct dahdi_pvt *p, *pl;
02739 
02740    while (num_restart_pending) {
02741       usleep(1);
02742    }
02743 
02744    ast_mutex_lock(&iflock);
02745    /* Destroy all the interfaces and free their memory */
02746    p = iflist;
02747    while (p) {
02748       pl = p;
02749       p = p->next;
02750       x = pl->channel;
02751       /* Free associated memory */
02752       destroy_dahdi_pvt(&pl);
02753       if (option_verbose > 2) 
02754          ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x);
02755    }
02756    iflist = NULL;
02757    ifcount = 0;
02758    ast_mutex_unlock(&iflock);
02759 }
02760 
02761 #ifdef HAVE_PRI
02762 static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
02763 static char *zap_send_keypad_facility_app = "ZapSendKeypadFacility";
02764 
02765 static char *dahdi_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02766 static char *zap_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
02767 
02768 static char *dahdi_send_keypad_facility_descrip = 
02769 "  DAHDISendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02770 "  IE over the current channel.\n";
02771 static char *zap_send_keypad_facility_descrip = 
02772 "  ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
02773 "  IE over the current channel.\n";
02774 
02775 static int send_keypad_facility_exec(struct ast_channel *chan, void *data)
02776 {
02777    /* Data will be our digit string */
02778    struct dahdi_pvt *p;
02779    char *digits = (char *) data;
02780 
02781    if (ast_strlen_zero(digits)) {
02782       ast_log(LOG_DEBUG, "No digit string sent to application!\n");
02783       return -1;
02784    }
02785 
02786    p = (struct dahdi_pvt *)chan->tech_pvt;
02787 
02788    if (!p) {
02789       ast_log(LOG_DEBUG, "Unable to find technology private\n");
02790       return -1;
02791    }
02792 
02793    ast_mutex_lock(&p->lock);
02794 
02795    if (!p->pri || !p->call) {
02796       ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
02797       ast_mutex_unlock(&p->lock);
02798       return -1;
02799    }
02800 
02801    if (!pri_grab(p, p->pri)) {
02802       pri_keypad_facility(p->pri->pri, p->call, digits);
02803       pri_rel(p->pri);
02804    } else {
02805       ast_log(LOG_DEBUG, "Unable to grab pri to send keypad facility!\n");
02806       ast_mutex_unlock(&p->lock);
02807       return -1;
02808    }
02809 
02810    ast_mutex_unlock(&p->lock);
02811 
02812    return 0;
02813 }
02814 
02815 static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02816 {
02817    return send_keypad_facility_exec(chan, data);
02818 }
02819 
02820 static int zap_send_keypad_facility_exec(struct ast_channel *chan, void *data)
02821 {
02822    ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_send_keypad_facility_app, dahdi_send_keypad_facility_app);  
02823    return send_keypad_facility_exec(chan, data);
02824 }
02825 
02826 static int pri_is_up(struct dahdi_pri *pri)
02827 {
02828    int x;
02829    for (x = 0; x < NUM_DCHANS; x++) {
02830       if (pri->dchanavail[x] == DCHAN_AVAILABLE)
02831          return 1;
02832    }
02833    return 0;
02834 }
02835 
02836 static int pri_assign_bearer(struct dahdi_pvt *crv, struct dahdi_pri *pri, struct dahdi_pvt *bearer)
02837 {
02838    bearer->owner = &inuse;
02839    bearer->realcall = crv;
02840    crv->subs[SUB_REAL].dfd = bearer->subs[SUB_REAL].dfd;
02841    if (crv->subs[SUB_REAL].owner)
02842       crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].dfd;
02843    crv->bearer = bearer;
02844    crv->call = bearer->call;
02845    crv->pri = pri;
02846    return 0;
02847 }
02848 
02849 static char *pri_order(int level)
02850 {
02851    switch (level) {
02852    case 0:
02853       return "Primary";
02854    case 1:
02855       return "Secondary";
02856    case 2:
02857       return "Tertiary";
02858    case 3:
02859       return "Quaternary";
02860    default:
02861       return "<Unknown>";
02862    }     
02863 }
02864 
02865 /* Returns fd of the active dchan */
02866 static int pri_active_dchan_fd(struct dahdi_pri *pri)
02867 {
02868    int x = -1;
02869 
02870    for (x = 0; x < NUM_DCHANS; x++) {
02871       if ((pri->dchans[x] == pri->pri))
02872          break;
02873    }
02874 
02875    return pri->fds[x];
02876 }
02877 
02878 static int pri_find_dchan(struct dahdi_pri *pri)
02879 {
02880    int oldslot = -1;
02881    struct pri *old;
02882    int newslot = -1;
02883    int x;
02884    old = pri->pri;
02885    for (x = 0; x < NUM_DCHANS; x++) {
02886       if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
02887          newslot = x;
02888       if (pri->dchans[x] == old) {
02889          oldslot = x;
02890       }
02891    }
02892    if (newslot < 0) {
02893       newslot = 0;
02894       if (!pri->no_d_channels) {
02895          pri->no_d_channels = 1;
02896          ast_log(LOG_WARNING,
02897             "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
02898             pri->dchannels[newslot]);
02899       }
02900    } else {
02901       pri->no_d_channels = 0;
02902    }
02903    if (old && (oldslot != newslot))
02904       ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
02905          pri->dchannels[oldslot], pri->dchannels[newslot]);
02906    pri->pri = pri->dchans[newslot];
02907    return 0;
02908 }
02909 #endif
02910 
02911 static int dahdi_hangup(struct ast_channel *ast)
02912 {
02913    int res;
02914    int index,x, law;
02915    /*static int restore_gains(struct dahdi_pvt *p);*/
02916    struct dahdi_pvt *p = ast->tech_pvt;
02917    struct dahdi_pvt *tmp = NULL;
02918    struct dahdi_pvt *prev = NULL;
02919    struct dahdi_params par;
02920 
02921    if (option_debug)
02922       ast_log(LOG_DEBUG, "dahdi_hangup(%s)\n", ast->name);
02923    if (!ast->tech_pvt) {
02924       ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
02925       return 0;
02926    }
02927    
02928    ast_mutex_lock(&p->lock);
02929    
02930    index = dahdi_get_index(ast, p, 1);
02931 
02932    if (p->sig == SIG_PRI) {
02933       x = 1;
02934       ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
02935       p->cid_num[0] = '\0';
02936       p->cid_name[0] = '\0';
02937    }
02938 
02939    x = 0;
02940    dahdi_confmute(p, 0);
02941    restore_gains(p);
02942    if (p->origcid_num) {
02943       ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
02944       free(p->origcid_num);
02945       p->origcid_num = NULL;
02946    }  
02947    if (p->origcid_name) {
02948       ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
02949       free(p->origcid_name);
02950       p->origcid_name = NULL;
02951    }  
02952    if (p->dsp)
02953       ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);
02954    p->exten[0] = '\0';
02955 
02956    if (option_debug)
02957       ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
02958       p->channel, index, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
02959    p->ignoredtmf = 0;
02960    
02961    if (index > -1) {
02962       /* Real channel, do some fixup */
02963       p->subs[index].owner = NULL;
02964       p->subs[index].needanswer = 0;
02965       p->subs[index].needflash = 0;
02966       p->subs[index].needringing = 0;
02967       p->subs[index].needbusy = 0;
02968       p->subs[index].needcongestion = 0;
02969       p->subs[index].linear = 0;
02970       p->subs[index].needcallerid = 0;
02971       p->polarity = POLARITY_IDLE;
02972       dahdi_setlinear(p->subs[index].dfd, 0);
02973       switch (index) {
02974       case SUB_REAL:
02975          if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
02976             ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
02977             if (p->subs[SUB_CALLWAIT].inthreeway) {
02978                /* We had flipped over to answer a callwait and now it's gone */
02979                ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
02980                /* Move to the call-wait, but un-own us until they flip back. */
02981                swap_subs(p, SUB_CALLWAIT, SUB_REAL);
02982                unalloc_sub(p, SUB_CALLWAIT);
02983                p->owner = NULL;
02984             } else {
02985                /* The three way hung up, but we still have a call wait */
02986                ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
02987                swap_subs(p, SUB_THREEWAY, SUB_REAL);
02988                unalloc_sub(p, SUB_THREEWAY);
02989                if (p->subs[SUB_REAL].inthreeway) {
02990                   /* This was part of a three way call.  Immediately make way for
02991                      another call */
02992                   ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
02993                   p->subs[SUB_REAL].inthreeway = 0;
02994                   p->owner = p->subs[SUB_REAL].owner;
02995                } else {
02996                   /* This call hasn't been completed yet...  Set owner to NULL */
02997                   ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
02998                   p->owner = NULL;
02999                }
03000             }
03001          } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
03002             /* Need to hold the lock for real-call, private, and call-waiting call */
03003             dahdi_lock_sub_owner(p, SUB_CALLWAIT);
03004             if (!p->subs[SUB_CALLWAIT].owner) {
03005                /* The call waiting call dissappeared. */
03006                p->owner = NULL;
03007                break;
03008             }
03009 
03010             /* Move to the call-wait and switch back to them. */
03011             swap_subs(p, SUB_CALLWAIT, SUB_REAL);
03012             unalloc_sub(p, SUB_CALLWAIT);
03013             p->owner = p->subs[SUB_REAL].owner;
03014             if (p->owner->_state != AST_STATE_UP)
03015                p->subs[SUB_REAL].needanswer = 1;
03016             if (ast_bridged_channel(p->subs[SUB_REAL].owner))
03017                ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
03018             /* Unlock the call-waiting call that we swapped to real-call. */
03019             ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
03020          } else if (p->subs[SUB_THREEWAY].dfd > -1) {
03021             swap_subs(p, SUB_THREEWAY, SUB_REAL);
03022             unalloc_sub(p, SUB_THREEWAY);
03023             if (p->subs[SUB_REAL].inthreeway) {
03024                /* This was part of a three way call.  Immediately make way for
03025                   another call */
03026                ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
03027                p->subs[SUB_REAL].inthreeway = 0;
03028                p->owner = p->subs[SUB_REAL].owner;
03029             } else {
03030                /* This call hasn't been completed yet...  Set owner to NULL */
03031                ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
03032                p->owner = NULL;
03033             }
03034          }
03035          break;
03036       case SUB_CALLWAIT:
03037          /* Ditch the holding callwait call, and immediately make it availabe */
03038          if (p->subs[SUB_CALLWAIT].inthreeway) {
03039             /* Need to hold the lock for call-waiting call, private, and 3-way call */
03040             dahdi_lock_sub_owner(p, SUB_THREEWAY);
03041 
03042             /* This is actually part of a three way, placed on hold.  Place the third part
03043                on music on hold now */
03044             if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
03045                ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
03046                   S_OR(p->mohsuggest, NULL),
03047                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03048             }
03049             p->subs[SUB_THREEWAY].inthreeway = 0;
03050             /* Make it the call wait now */
03051             swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
03052             unalloc_sub(p, SUB_THREEWAY);
03053             if (p->subs[SUB_CALLWAIT].owner) {
03054                /* Unlock the 3-way call that we swapped to call-waiting call. */
03055                ast_mutex_unlock(&p->subs[SUB_CALLWAIT].owner->lock);
03056             }
03057          } else
03058             unalloc_sub(p, SUB_CALLWAIT);
03059          break;
03060       case SUB_THREEWAY:
03061          /* Need to hold the lock for 3-way call, private, and call-waiting call */
03062          dahdi_lock_sub_owner(p, SUB_CALLWAIT);
03063          if (p->subs[SUB_CALLWAIT].inthreeway) {
03064             /* The other party of the three way call is currently in a call-wait state.
03065                Start music on hold for them, and take the main guy out of the third call */
03066             p->subs[SUB_CALLWAIT].inthreeway = 0;
03067             if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
03068                ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
03069                   S_OR(p->mohsuggest, NULL),
03070                   !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
03071             }
03072          }
03073          if (p->subs[SUB_CALLWAIT].owner) {
03074             ast_mutex_unlock(&p->subs[SUB_CALLWAIT].owner->lock);
03075          }
03076          p->subs[SUB_REAL].inthreeway = 0;
03077          /* If this was part of a three way call index, let us make
03078             another three way call */
03079          unalloc_sub(p, SUB_THREEWAY);
03080          break;
03081       default:
03082          /*
03083           * Should never happen.
03084           * This wasn't any sort of call, so how are we an index?
03085           */
03086          ast_log(LOG_ERROR, "Index found but not any type of call?\n");
03087          break;
03088       }
03089    }
03090 
03091    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
03092       p->ringt = 0;
03093       p->distinctivering = 0;
03094       p->confirmanswer = 0;
03095       p->cidrings = 1;
03096       p->outgoing = 0;
03097       p->digital = 0;
03098       p->faxhandled = 0;
03099       p->pulsedial = 0;
03100       p->onhooktime = time(NULL);
03101 #ifdef HAVE_PRI
03102       p->dialing = 0;
03103       p->progress = 0;
03104       p->call_level = DAHDI_CALL_LEVEL_IDLE;
03105 #endif      
03106       if (p->dsp) {
03107          ast_dsp_free(p->dsp);
03108          p->dsp = NULL;
03109       }
03110 
03111       if (p->bufferoverrideinuse) {
03112          /* faxbuffers are in use, revert them */
03113          struct dahdi_bufferinfo bi = {
03114             .txbufpolicy = p->buf_policy,
03115             .rxbufpolicy = p->buf_policy,
03116             .bufsize = p->bufsize,
03117             .numbufs = p->buf_no
03118          };
03119          int bpres;
03120 
03121          if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
03122             ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
03123          }
03124          p->bufferoverrideinuse = 0;   
03125       }
03126 
03127       law = DAHDI_LAW_DEFAULT;
03128       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
03129       if (res < 0) 
03130          ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
03131       /* Perform low level hangup if no owner left */
03132 #if defined(HAVE_PRI)
03133       if (p->pri) {
03134 #ifdef SUPPORT_USERUSER
03135          const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
03136 #endif
03137 
03138          /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
03139          pri_grab(p, p->pri);
03140          if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
03141             if (p->alreadyhungup) {
03142                ast_log(LOG_DEBUG, "Already hungup...  Calling hangup once, and clearing call\n");
03143 
03144 #ifdef SUPPORT_USERUSER
03145                pri_call_set_useruser(p->call, useruser);
03146 #endif
03147 
03148                pri_hangup(p->pri->pri, p->call, -1);
03149                p->call = NULL;
03150                if (p->bearer)
03151                   p->bearer->call = NULL;
03152             } else {
03153                const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
03154                int icause = ast->hangupcause ? ast->hangupcause : -1;
03155                ast_log(LOG_DEBUG, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
03156 
03157 #ifdef SUPPORT_USERUSER
03158                pri_call_set_useruser(p->call, useruser);
03159 #endif
03160 
03161                p->alreadyhungup = 1;
03162                if (p->bearer)
03163                   p->bearer->alreadyhungup = 1;
03164                if (cause) {
03165                   if (atoi(cause))
03166                      icause = atoi(cause);
03167                }
03168                pri_hangup(p->pri->pri, p->call, icause);
03169             }
03170          } else {
03171             if (p->bearer)
03172                ast_log(LOG_DEBUG, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
03173             p->call = NULL;
03174          }
03175          p->allocated = 0;
03176          p->owner = NULL;
03177          pri_rel(p->pri);
03178          res = 0;
03179       } else
03180 #endif   /* defined(HAVE_PRI) */
03181       {
03182          p->owner = NULL;
03183       }
03184       if (p->sig && (p->sig != SIG_PRI))
03185          res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
03186       if (res < 0) {
03187          ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
03188       }
03189       switch (p->sig) {
03190       case SIG_FXOGS:
03191       case SIG_FXOLS:
03192       case SIG_FXOKS:
03193          memset(&par, 0, sizeof(par));
03194          res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
03195          if (!res) {
03196 #if 0
03197             ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
03198 #endif
03199             /* If they're off hook, try playing congestion */
03200             if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
03201                tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
03202             else
03203                tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
03204          }
03205          break;
03206       case SIG_FXSGS:
03207       case SIG_FXSLS:
03208       case SIG_FXSKS:
03209          /* Make sure we're not made available for at least two seconds assuming
03210             we were actually used for an inbound or outbound call. */
03211          if (ast->_state != AST_STATE_RESERVED) {
03212             time(&p->guardtime);
03213             p->guardtime += 2;
03214          }
03215          break;
03216       default:
03217          tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
03218       }
03219       free(p->cidspill);
03220       p->cidspill = NULL;
03221       if (p->sig)
03222          dahdi_disable_ec(p);
03223       x = 0;
03224       ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
03225       ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
03226       p->didtdd = 0;
03227       p->callwaitcas = 0;
03228       p->callwaiting = p->permcallwaiting;
03229       p->hidecallerid = p->permhidecallerid;
03230       p->dialing = 0;
03231       p->rdnis[0] = '\0';
03232       update_conf(p);
03233       reset_conf(p);
03234       /* Restore data mode */
03235       if (p->sig == SIG_PRI) {
03236          x = 0;
03237          ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
03238       }
03239 #ifdef HAVE_PRI
03240       if (p->bearer) {
03241          ast_log(LOG_DEBUG, "Freeing up bearer channel %d\n", p->bearer->channel);
03242          /* Free up the bearer channel as well, and
03243             don't use its file descriptor anymore */
03244          update_conf(p->bearer);
03245          reset_conf(p->bearer);
03246          p->bearer->owner = NULL;
03247          p->bearer->realcall = NULL;
03248          p->bearer = NULL;
03249          p->subs[SUB_REAL].dfd = -1;
03250          p->pri = NULL;
03251       }
03252 #endif
03253       if (num_restart_pending == 0)
03254          restart_monitor();
03255    }
03256 
03257    p->callwaitingrepeat = 0;
03258    p->cidcwexpire = 0;
03259    p->cid_suppress_expire = 0;
03260    p->oprmode = 0;
03261    ast->tech_pvt = NULL;
03262    ast_mutex_unlock(&p->lock);
03263    if (option_verbose > 2) 
03264       ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
03265 
03266    ast_mutex_lock(&iflock);
03267    if (p->restartpending) {
03268       num_restart_pending--;
03269    }
03270 
03271    tmp = iflist;
03272    prev = NULL;
03273    if (p->destroy) {
03274       while (tmp) {
03275          if (tmp == p) {
03276             destroy_channel(prev, tmp, 0);
03277             break;
03278          } else {
03279             prev = tmp;
03280             tmp = tmp->next;
03281          }
03282       }
03283    }
03284    ast_mutex_unlock(&iflock);
03285 
03286    ast_module_unref(ast_module_info->self);
03287    return 0;
03288 }
03289 
03290 static int dahdi_answer(struct ast_channel *ast)
03291 {
03292    struct dahdi_pvt *p = ast->tech_pvt;
03293    int res = 0;
03294    int index;
03295    int oldstate = ast->_state;
03296    ast_setstate(ast, AST_STATE_UP);
03297    ast_mutex_lock(&p->lock);
03298    index = dahdi_get_index(ast, p, 0);
03299    if (index < 0)
03300       index = SUB_REAL;
03301    /* nothing to do if a radio channel */
03302    if ((p->radio || (p->oprmode < 0))) {
03303       ast_mutex_unlock(&p->lock);
03304       return 0;
03305    }
03306    switch (p->sig) {
03307    case SIG_FXSLS:
03308    case SIG_FXSGS:
03309    case SIG_FXSKS:
03310       p->ringt = 0;
03311       /* Fall through */
03312    case SIG_EM:
03313    case SIG_EM_E1:
03314    case SIG_EMWINK:
03315    case SIG_FEATD:
03316    case SIG_FEATDMF:
03317    case SIG_FEATDMF_TA:
03318    case SIG_E911:
03319    case SIG_FGC_CAMA:
03320    case SIG_FGC_CAMAMF:
03321    case SIG_FEATB:
03322    case SIG_SF:
03323    case SIG_SFWINK:
03324    case SIG_SF_FEATD:
03325    case SIG_SF_FEATDMF:
03326    case SIG_SF_FEATB:
03327    case SIG_FXOLS:
03328    case SIG_FXOGS:
03329    case SIG_FXOKS:
03330       /* Pick up the line */
03331       ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
03332       if (p->hanguponpolarityswitch) {
03333          gettimeofday(&p->polaritydelaytv, NULL);
03334       }
03335       res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
03336       tone_zone_play_tone(p->subs[index].dfd, -1);
03337       p->dialing = 0;
03338       if ((index == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
03339          if (oldstate == AST_STATE_RINGING) {
03340             ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
03341             tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, -1);
03342             swap_subs(p, SUB_THREEWAY, SUB_REAL);
03343             p->owner = p->subs[SUB_REAL].owner;
03344          }
03345       }
03346       if (p->sig & __DAHDI_SIG_FXS) {
03347          dahdi_enable_ec(p);
03348          dahdi_train_ec(p);
03349       }
03350       break;
03351 #ifdef HAVE_PRI
03352    case SIG_PRI:
03353       /* Send a pri acknowledge */
03354       if (!pri_grab(p, p->pri)) {
03355          if (p->call_level < DAHDI_CALL_LEVEL_CONNECT) {
03356             p->call_level = DAHDI_CALL_LEVEL_CONNECT;
03357          }
03358          p->dialing = 0;
03359          res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
03360          pri_rel(p->pri);
03361       } else {
03362          ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
03363          res = -1;
03364       }
03365       break;
03366 #endif
03367    case 0:
03368       ast_mutex_unlock(&p->lock);
03369       return 0;
03370    default:
03371       ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
03372       res = -1;
03373    }
03374    ast_mutex_unlock(&p->lock);
03375    return res;
03376 }
03377 
03378 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
03379 {
03380    char *cp;
03381    signed char *scp;
03382    int x;
03383    int index;
03384    struct dahdi_pvt *p = chan->tech_pvt, *pp;
03385    struct oprmode *oprmode;
03386    
03387 
03388    /* all supported options require data */
03389    if (!data || (datalen < 1)) {
03390       errno = EINVAL;
03391       return -1;
03392    }
03393 
03394    switch (option) {
03395    case AST_OPTION_TXGAIN:
03396       scp = (signed char *) data;
03397       index = dahdi_get_index(chan, p, 0);
03398       if (index < 0) {
03399          ast_log(LOG_WARNING, "No index in TXGAIN?\n");
03400          return -1;
03401       }
03402       if (option_debug)
03403          ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
03404       return set_actual_txgain(p->subs[index].dfd, 0, p->txgain + (float) *scp, p->law);
03405    case AST_OPTION_RXGAIN:
03406       scp = (signed char *) data;
03407       index = dahdi_get_index(chan, p, 0);
03408       if (index < 0) {
03409          ast_log(LOG_WARNING, "No index in RXGAIN?\n");
03410          return -1;
03411       }
03412       if (option_debug)
03413          ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
03414       return set_actual_rxgain(p->subs[index].dfd, 0, p->rxgain + (float) *scp, p->law);
03415    case AST_OPTION_TONE_VERIFY:
03416       if (!p->dsp)
03417          break;
03418       cp = (char *) data;
03419       switch (*cp) {
03420       case 1:
03421          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
03422          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
03423          break;
03424       case 2:
03425          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
03426          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
03427          break;
03428       default:
03429          ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
03430          ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
03431          break;
03432       }
03433       break;
03434    case AST_OPTION_TDD:
03435       /* turn on or off TDD */
03436       cp = (char *) data;
03437       p->mate = 0;
03438       if (!*cp) { /* turn it off */
03439          if (option_debug)
03440             ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
03441          if (p->tdd)
03442             tdd_free(p->tdd);
03443          p->tdd = 0;
03444          break;
03445       }
03446       ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
03447          (*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
03448       dahdi_disable_ec(p);
03449       /* otherwise, turn it on */
03450       if (!p->didtdd) { /* if havent done it yet */
03451          unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
03452          unsigned char *buf;
03453          int size, res, fd, len;
03454          struct pollfd fds[1];
03455 
03456          buf = mybuf;
03457          memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
03458          ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
03459          len = 40000;
03460          index = dahdi_get_index(chan, p, 0);
03461          if (index < 0) {
03462             ast_log(LOG_WARNING, "No index in TDD?\n");
03463             return -1;
03464          }
03465          fd = p->subs[index].dfd;
03466          while (len) {
03467             if (ast_check_hangup(chan))
03468                return -1;
03469             size = len;
03470             if (size > READ_SIZE)
03471                size = READ_SIZE;
03472             fds[0].fd = fd;
03473             fds[0].events = POLLPRI | POLLOUT;
03474             fds[0].revents = 0;
03475             res = poll(fds, 1, -1);
03476             if (!res) {
03477                ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
03478                continue;
03479             }
03480             /* if got exception */
03481             if (fds[0].revents & POLLPRI)
03482                return -1;
03483             if (!(fds[0].revents & POLLOUT)) {
03484                ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
03485                continue;
03486             }
03487             res = write(fd, buf, size);
03488             if (res != size) {
03489                if (res == -1) return -1;
03490                ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
03491                break;
03492             }
03493             len -= size;
03494             buf += size;
03495          }
03496          p->didtdd = 1; /* set to have done it now */    
03497       }
03498       if (*cp == 2) { /* Mate mode */
03499          if (p->tdd)
03500             tdd_free(p->tdd);
03501          p->tdd = 0;
03502          p->mate = 1;
03503          break;
03504       }     
03505       if (!p->tdd) { /* if we dont have one yet */
03506          p->tdd = tdd_new(); /* allocate one */
03507       }     
03508       break;
03509    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
03510       if (!p->dsp)
03511          break;
03512       cp = (char *) data;
03513       ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
03514          *cp ? "ON" : "OFF", (int) *cp, chan->name);
03515                 p->dtmfrelax = 0;
03516                 if (*cp) p->dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
03517                 ast_dsp_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
03518       break;
03519    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
03520       cp = (char *) data;
03521       if (!*cp) {    
03522          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
03523          x = 0;
03524          dahdi_disable_ec(p);
03525       } else {    
03526          ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
03527          x = 1;
03528       }
03529       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
03530          ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
03531       break;
03532    case AST_OPTION_OPRMODE:  /* Operator services mode */
03533       oprmode = (struct oprmode *) data;
03534       pp = oprmode->peer->tech_pvt;
03535       p->oprmode = pp->oprmode = 0;
03536       /* setup peers */
03537       p->oprpeer = pp;
03538       pp->oprpeer = p;
03539       /* setup modes, if any */
03540       if (oprmode->mode) 
03541       {
03542          pp->oprmode = oprmode->mode;
03543          p->oprmode = -oprmode->mode;
03544       }
03545       ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
03546          oprmode->mode, chan->name,oprmode->peer->name);;
03547       break;
03548    case AST_OPTION_ECHOCAN:
03549       cp = (char *) data;
03550       if (*cp) {
03551          ast_log(LOG_DEBUG, "Enabling echo cancellation on %s\n", chan->name);
03552          dahdi_enable_ec(p);
03553       } else {
03554          ast_log(LOG_DEBUG, "Disabling echo cancellation on %s\n", chan->name);
03555          dahdi_disable_ec(p);
03556       }
03557       break;
03558    }
03559    errno = 0;
03560 
03561    return 0;
03562 }
03563 
03564 static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len)
03565 {
03566    struct dahdi_pvt *p = chan->tech_pvt;
03567    int res = 0;
03568    
03569    if (!strcasecmp(data, "rxgain")) {
03570       ast_mutex_lock(&p->lock);
03571       snprintf(buf, len, "%f", p->rxgain);
03572       ast_mutex_unlock(&p->lock);   
03573    } else if (!strcasecmp(data, "txgain")) {
03574       ast_mutex_lock(&p->lock);
03575       snprintf(buf, len, "%f", p->txgain);
03576       ast_mutex_unlock(&p->lock);   
03577    } else {
03578       ast_copy_string(buf, "", len);
03579       res = -1;
03580    }
03581 
03582    return res;
03583 }
03584 
03585 
03586 static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
03587 {
03588    int res;
03589    char policy_str[21] = "";
03590    
03591    if (((res = sscanf(parse, "%d,%20s", num_buffers, policy_str)) != 2) &&
03592       ((res = sscanf(parse, "%d|%20s", num_buffers, policy_str)) != 2)) {
03593       ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
03594       return 1;
03595    }
03596    if (*num_buffers < 0) {
03597       ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
03598       return -1;
03599    }
03600    if (!strcasecmp(policy_str, "full")) {
03601       *policy = DAHDI_POLICY_WHEN_FULL;
03602    } else if (!strcasecmp(policy_str, "immediate")) {
03603       *policy = DAHDI_POLICY_IMMEDIATE;
03604 #ifdef DAHDI_POLICY_HALF_FULL
03605    } else if (!strcasecmp(policy_str, "half")) {
03606       *policy = DAHDI_POLICY_HALF_FULL;
03607 #endif
03608    } else {
03609       ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
03610       return -1;
03611    }
03612 
03613    return 0;
03614 }
03615 
03616 static int dahdi_func_write(struct ast_channel *chan, char *function, char *data, const char *value)
03617 {
03618    struct dahdi_pvt *p = chan->tech_pvt;
03619    int res = 0;
03620 
03621    if (!strcasecmp(data, "buffers")) {
03622       int num_bufs, policy;
03623 
03624       if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
03625          struct dahdi_bufferinfo bi = {
03626             .txbufpolicy = policy,
03627             .rxbufpolicy = policy,
03628             .bufsize = p->bufsize,
03629             .numbufs = num_bufs,
03630          };
03631          int bpres;
03632 
03633          if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
03634             ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
03635          } else {
03636             p->bufferoverrideinuse = 1;
03637          }
03638       } else {
03639          res = -1;
03640       }
03641    } else {
03642       res = -1;
03643    }
03644 
03645    return res;
03646 }
03647 
03648 static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
03649 {
03650    /* Unlink a specific slave or all slaves/masters from a given master */
03651    int x;
03652    int hasslaves;
03653    if (!master)
03654       return;
03655    if (needlock) {
03656       ast_mutex_lock(&master->lock);
03657       if (slave) {
03658          while (ast_mutex_trylock(&slave->lock)) {
03659             DEADLOCK_AVOIDANCE(&master->lock);
03660          }
03661       }
03662    }
03663    hasslaves = 0;
03664    for (x = 0; x < MAX_SLAVES; x++) {
03665       if (master->slaves[x]) {
03666          if (!slave || (master->slaves[x] == slave)) {
03667             /* Take slave out of the conference */
03668             ast_log(LOG_DEBUG, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
03669             conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
03670             conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
03671             master->slaves[x]->master = NULL;
03672             master->slaves[x] = NULL;
03673          } else
03674             hasslaves = 1;
03675       }
03676       if (!hasslaves)
03677          master->inconference = 0;
03678    }
03679    if (!slave) {
03680       if (master->master) {
03681          /* Take master out of the conference */
03682          conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
03683          conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
03684          hasslaves = 0;
03685          for (x = 0; x < MAX_SLAVES; x++) {
03686             if (master->master->slaves[x] == master)
03687                master->master->slaves[x] = NULL;
03688             else if (master->master->slaves[x])
03689                hasslaves = 1;
03690          }
03691          if (!hasslaves)
03692             master->master->inconference = 0;
03693       }
03694       master->master = NULL;
03695    }
03696    update_conf(master);
03697    if (needlock) {
03698       if (slave)
03699          ast_mutex_unlock(&slave->lock);
03700       ast_mutex_unlock(&master->lock);
03701    }
03702 }
03703 
03704 static void dahdi_link(struct dahdi_pvt *slave, struct dahdi_pvt *master) {
03705    int x;
03706    if (!slave || !master) {
03707       ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
03708       return;
03709    }
03710    for (x = 0; x < MAX_SLAVES; x++) {
03711       if (!master->slaves[x]) {
03712          master->slaves[x] = slave;
03713          break;
03714       }
03715    }
03716    if (x >= MAX_SLAVES) {
03717       ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
03718       master->slaves[MAX_SLAVES - 1] = slave;
03719    }
03720    if (slave->master) 
03721       ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
03722    slave->master = master;
03723    
03724    ast_log(LOG_DEBUG, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
03725 }
03726 
03727 static void disable_dtmf_detect(struct dahdi_pvt *p)
03728 {
03729 #ifdef DAHDI_TONEDETECT
03730    int val;
03731 #endif
03732 
03733    p->ignoredtmf = 1;
03734 
03735 #ifdef DAHDI_TONEDETECT
03736    val = 0;
03737    ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
03738 #endif      
03739    if (!p->hardwaredtmf && p->dsp) {
03740       p->dsp_features &= ~DSP_FEATURE_DTMF_DETECT;
03741       ast_dsp_set_features(p->dsp, p->dsp_features);
03742    }
03743 }
03744 
03745 static void enable_dtmf_detect(struct dahdi_pvt *p)
03746 {
03747 #ifdef DAHDI_TONEDETECT
03748    int val;
03749 #endif
03750 
03751    if (p->channel == CHAN_PSEUDO)
03752       return;
03753 
03754    p->ignoredtmf = 0;
03755 
03756 #ifdef DAHDI_TONEDETECT
03757    val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
03758    ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
03759 #endif      
03760    if (!p->hardwaredtmf && p->dsp) {
03761       p->dsp_features |= DSP_FEATURE_DTMF_DETECT;
03762       ast_dsp_set_features(p->dsp, p->dsp_features);
03763    }
03764 }
03765 
03766 static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
03767 {
03768    struct ast_channel *who;
03769    struct dahdi_pvt *p0, *p1, *op0, *op1;
03770    struct dahdi_pvt *master = NULL, *slave = NULL;
03771    struct ast_frame *f;
03772    int inconf = 0;
03773    int nothingok = 1;
03774    int ofd0, ofd1;
03775    int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
03776    int os0 = -1, os1 = -1;
03777    int priority = 0;
03778    struct ast_channel *oc0, *oc1;
03779    enum ast_bridge_result res;
03780 
03781 #ifdef PRI_2BCT
03782    int triedtopribridge = 0;
03783 #endif
03784 
03785    /* For now, don't attempt to native bridge if either channel needs DTMF detection.
03786       There is code below to handle it properly until DTMF is actually seen,
03787       but due to currently unresolved issues it's ignored...
03788    */
03789 
03790    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
03791       return AST_BRIDGE_FAILED_NOWARN;
03792 
03793    ast_mutex_lock(&c0->lock);
03794    while (ast_mutex_trylock(&c1->lock)) {
03795       DEADLOCK_AVOIDANCE(&c0->lock);
03796    }
03797 
03798    p0 = c0->tech_pvt;
03799    p1 = c1->tech_pvt;
03800    /* cant do pseudo-channels here */
03801    if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
03802       ast_mutex_unlock(&c0->lock);
03803       ast_mutex_unlock(&c1->lock);
03804       return AST_BRIDGE_FAILED_NOWARN;
03805    }
03806 
03807    oi0 = dahdi_get_index(c0, p0, 0);
03808    oi1 = dahdi_get_index(c1, p1, 0);
03809    if ((oi0 < 0) || (oi1 < 0)) {
03810       ast_mutex_unlock(&c0->lock);
03811       ast_mutex_unlock(&c1->lock);
03812       return AST_BRIDGE_FAILED;
03813    }
03814 
03815    op0 = p0 = c0->tech_pvt;
03816    op1 = p1 = c1->tech_pvt;
03817    ofd0 = c0->fds[0];
03818    ofd1 = c1->fds[0];
03819    oc0 = p0->owner;
03820    oc1 = p1->owner;
03821 
03822    if (ast_mutex_trylock(&p0->lock)) {
03823       /* Don't block, due to potential for deadlock */
03824       ast_mutex_unlock(&c0->lock);
03825       ast_mutex_unlock(&c1->lock);
03826       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03827       return AST_BRIDGE_RETRY;
03828    }
03829    if (ast_mutex_trylock(&p1->lock)) {
03830       /* Don't block, due to potential for deadlock */
03831       ast_mutex_unlock(&p0->lock);
03832       ast_mutex_unlock(&c0->lock);
03833       ast_mutex_unlock(&c1->lock);
03834       ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
03835       return AST_BRIDGE_RETRY;
03836    }
03837 
03838    if ((p0->callwaiting && p0->callwaitingcallerid)
03839       || (p1->callwaiting && p1->callwaitingcallerid)) {
03840       /*
03841        * Call Waiting Caller ID requires DTMF detection to know if it
03842        * can send the CID spill.
03843        *
03844        * For now, don't attempt to native bridge if either channel
03845        * needs DTMF detection.  There is code below to handle it
03846        * properly until DTMF is actually seen, but due to currently
03847        * unresolved issues it's ignored...
03848        */
03849       ast_mutex_unlock(&p0->lock);
03850       ast_mutex_unlock(&p1->lock);
03851       ast_mutex_unlock(&c0->lock);
03852       ast_mutex_unlock(&c1->lock);
03853       return AST_BRIDGE_FAILED_NOWARN;
03854    }
03855 
03856    if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03857       if (p0->owner && p1->owner) {
03858          /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
03859          if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
03860             master = p0;
03861             slave = p1;
03862             inconf = 1;
03863          } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
03864             master = p1;
03865             slave = p0;
03866             inconf = 1;
03867          } else {
03868             ast_log(LOG_WARNING, "Huh?  Both calls are callwaits or 3-ways?  That's clever...?\n");
03869             ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
03870                p0->channel,
03871                oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
03872                p0->subs[SUB_REAL].inthreeway, p0->channel,
03873                oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
03874                p1->subs[SUB_REAL].inthreeway);
03875          }
03876          nothingok = 0;
03877       }
03878    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
03879       if (p1->subs[SUB_THREEWAY].inthreeway) {
03880          master = p1;
03881          slave = p0;
03882          nothingok = 0;
03883       }
03884    } else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
03885       if (p0->subs[SUB_THREEWAY].inthreeway) {
03886          master = p0;
03887          slave = p1;
03888          nothingok = 0;
03889       }
03890    } else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
03891       /* We have a real and a call wait.  If we're in a three way call, put us in it, otherwise, 
03892          don't put us in anything */
03893       if (p1->subs[SUB_CALLWAIT].inthreeway) {
03894          master = p1;
03895          slave = p0;
03896          nothingok = 0;
03897       }
03898    } else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
03899       /* Same as previous */
03900       if (p0->subs[SUB_CALLWAIT].inthreeway) {
03901          master = p0;
03902          slave = p1;
03903          nothingok = 0;
03904       }
03905    }
03906    ast_log(LOG_DEBUG, "master: %d, slave: %d, nothingok: %d\n",
03907       master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
03908    if (master && slave) {
03909       /* Stop any tones, or play ringtone as appropriate.  If they're bridged
03910          in an active threeway call with a channel that is ringing, we should
03911          indicate ringing. */
03912       if ((oi1 == SUB_THREEWAY) && 
03913           p1->subs[SUB_THREEWAY].inthreeway && 
03914           p1->subs[SUB_REAL].owner && 
03915           p1->subs[SUB_REAL].inthreeway && 
03916           (p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03917          ast_log(LOG_DEBUG,
03918             "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
03919             p0->channel, oi0, c0->name, p1->channel, oi1, c1->name);
03920          tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE);
03921          os1 = p1->subs[SUB_REAL].owner->_state;
03922       } else {
03923          ast_log(LOG_DEBUG, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
03924             p0->channel, oi0, c0->name, p1->channel, oi1, c1->name);
03925          tone_zone_play_tone(p0->subs[oi0].dfd, -1);
03926       }
03927       if ((oi0 == SUB_THREEWAY) && 
03928           p0->subs[SUB_THREEWAY].inthreeway && 
03929           p0->subs[SUB_REAL].owner && 
03930           p0->subs[SUB_REAL].inthreeway && 
03931           (p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
03932          ast_log(LOG_DEBUG,
03933             "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
03934             p1->channel, oi1, c1->name, p0->channel, oi0, c0->name);
03935          tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE);
03936          os0 = p0->subs[SUB_REAL].owner->_state;
03937       } else {
03938          ast_log(LOG_DEBUG, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
03939             p1->channel, oi1, c1->name, p0->channel, oi0, c0->name);
03940          tone_zone_play_tone(p1->subs[oi1].dfd, -1);
03941       }
03942       if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
03943          if (!p0->echocanbridged || !p1->echocanbridged) {
03944             /* Disable echo cancellation if appropriate */
03945             dahdi_disable_ec(p0);
03946             dahdi_disable_ec(p1);
03947          }
03948       }
03949       dahdi_link(slave, master);
03950       master->inconference = inconf;
03951    } else if (!nothingok)
03952       ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
03953 
03954    update_conf(p0);
03955    update_conf(p1);
03956    t0 = p0->subs[SUB_REAL].inthreeway;
03957    t1 = p1->subs[SUB_REAL].inthreeway;
03958 
03959    ast_mutex_unlock(&p0->lock);
03960    ast_mutex_unlock(&p1->lock);
03961 
03962    ast_mutex_unlock(&c0->lock);
03963    ast_mutex_unlock(&c1->lock);
03964 
03965    /* Native bridge failed */
03966    if ((!master || !slave) && !nothingok) {
03967       dahdi_enable_ec(p0);
03968       dahdi_enable_ec(p1);
03969       return AST_BRIDGE_FAILED;
03970    }
03971    
03972    if (option_verbose > 2) 
03973       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
03974 
03975    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
03976       disable_dtmf_detect(op0);
03977 
03978    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
03979       disable_dtmf_detect(op1);
03980 
03981    for (;;) {
03982       struct ast_channel *c0_priority[2] = {c0, c1};
03983       struct ast_channel *c1_priority[2] = {c1, c0};
03984 
03985       /* Here's our main loop...  Start by locking things, looking for private parts, 
03986          and then balking if anything is wrong */
03987       ast_mutex_lock(&c0->lock);
03988       while (ast_mutex_trylock(&c1->lock)) {
03989          DEADLOCK_AVOIDANCE(&c0->lock);
03990       }
03991 
03992       p0 = c0->tech_pvt;
03993       p1 = c1->tech_pvt;
03994 
03995       if (op0 == p0)
03996          i0 = dahdi_get_index(c0, p0, 1);
03997       if (op1 == p1)
03998          i1 = dahdi_get_index(c1, p1, 1);
03999       ast_mutex_unlock(&c0->lock);
04000       ast_mutex_unlock(&c1->lock);
04001 
04002       if (!timeoutms || 
04003           (op0 != p0) ||
04004           (op1 != p1) || 
04005           (ofd0 != c0->fds[0]) || 
04006           (ofd1 != c1->fds[0]) ||
04007           (p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) || 
04008           (p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) || 
04009           (oc0 != p0->owner) || 
04010           (oc1 != p1->owner) ||
04011           (t0 != p0->subs[SUB_REAL].inthreeway) ||
04012           (t1 != p1->subs[SUB_REAL].inthreeway) ||
04013           (oi0 != i0) ||
04014           (oi1 != i1)) {
04015          ast_log(LOG_DEBUG, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
04016             op0->channel, oi0, op1->channel, oi1);
04017          res = AST_BRIDGE_RETRY;
04018          goto return_from_bridge;
04019       }
04020 
04021 #ifdef PRI_2BCT
04022       if (!triedtopribridge) {
04023          triedtopribridge = 1;
04024          if (p0->pri && p0->pri == p1->pri && p0->transfer && p1->transfer) {
04025             ast_mutex_lock(&p0->pri->lock);
04026             if (p0->call && p1->call) {
04027                pri_channel_bridge(p0->call, p1->call);
04028             }
04029             ast_mutex_unlock(&p0->pri->lock);
04030          }
04031       }
04032 #endif
04033 
04034       who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
04035       if (!who) {
04036          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
04037          continue;
04038       }
04039       f = ast_read(who);
04040       if (!f || (f->frametype == AST_FRAME_CONTROL)) {
04041          *fo = f;
04042          *rc = who;
04043          res = AST_BRIDGE_COMPLETE;
04044          goto return_from_bridge;
04045       }
04046       if (f->frametype == AST_FRAME_DTMF) {
04047          if ((who == c0) && p0->pulsedial) {
04048             ast_write(c1, f);
04049          } else if ((who == c1) && p1->pulsedial) {
04050             ast_write(c0, f);
04051          } else {
04052             *fo = f;
04053             *rc = who;
04054             res = AST_BRIDGE_COMPLETE;
04055             goto return_from_bridge;
04056          }
04057       }
04058       ast_frfree(f);
04059       
04060       /* Swap who gets priority */
04061       priority = !priority;
04062    }
04063 
04064 return_from_bridge:
04065    if (op0 == p0)
04066       dahdi_enable_ec(p0);
04067 
04068    if (op1 == p1)
04069       dahdi_enable_ec(p1);
04070 
04071    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
04072       enable_dtmf_detect(op0);
04073 
04074    if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
04075       enable_dtmf_detect(op1);
04076 
04077    dahdi_unlink(slave, master, 1);
04078 
04079    return res;
04080 }
04081 
04082 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
04083 {
04084    struct dahdi_pvt *p = newchan->tech_pvt;
04085    int x;
04086    ast_mutex_lock(&p->lock);
04087    ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
04088    if (p->owner == oldchan) {
04089       p->owner = newchan;
04090    }
04091    for (x = 0; x < 3; x++)
04092       if (p->subs[x].owner == oldchan) {
04093          if (!x)
04094             dahdi_unlink(NULL, p, 0);
04095          p->subs[x].owner = newchan;
04096       }
04097    update_conf(p);
04098    ast_mutex_unlock(&p->lock);
04099    if (newchan->_state == AST_STATE_RINGING) 
04100       dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
04101    return 0;
04102 }
04103 
04104 static int dahdi_ring_phone(struct dahdi_pvt *p)
04105 {
04106    int x;
04107    int res;
04108    /* Make sure our transmit state is on hook */
04109    x = 0;
04110    x = DAHDI_ONHOOK;
04111    res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
04112    do {
04113       x = DAHDI_RING;
04114       res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
04115       if (res) {
04116          switch (errno) {
04117          case EBUSY:
04118          case EINTR:
04119             /* Wait just in case */
04120             usleep(10000);
04121             continue;
04122          case EINPROGRESS:
04123             res = 0;
04124             break;
04125          default:
04126             ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
04127             res = 0;
04128          }
04129       }
04130    } while (res);
04131    return res;
04132 }
04133 
04134 static void *ss_thread(void *data);
04135 
04136 static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
04137 
04138 /*!
04139  * \internal
04140  * \brief Attempt to transfer 3-way call.
04141  *
04142  * \param p private structure.
04143  *
04144  * \note
04145  * On entry these locks are held: real-call, private, 3-way call.
04146  *
04147  * \retval 1 Transfer successful.  3-way call is unlocked and subchannel is unalloced.
04148  *         Swapped real and 3-way subchannel.
04149  * \retval 0 Transfer successful.  3-way call is unlocked and subchannel is unalloced.
04150  * \retval -1 on error.  Caller must unlock 3-way call.
04151  */
04152 static int attempt_transfer(struct dahdi_pvt *p)
04153 {
04154    /* In order to transfer, we need at least one of the channels to
04155       actually be in a call bridge.  We can't conference two applications
04156       together (but then, why would we want to?) */
04157    if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04158       /* The three-way person we're about to transfer to could still be in MOH, so
04159          stop it now if appropriate */
04160       if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
04161          ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
04162       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
04163          /*
04164           * This may not be safe.
04165           * We currently hold the locks on the real-call, private, and 3-way call.
04166           * We could possibly avoid this here by using an ast_queue_control() instead.
04167           * However, the following ast_channel_masquerade() is going to be locking
04168           * the bridged channel again anyway.
04169           */
04170          ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
04171       }
04172       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
04173          tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
04174       }
04175        if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
04176          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
04177                ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
04178          return -1;
04179       }
04180       /* Orphan the channel after releasing the lock */
04181       ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04182       unalloc_sub(p, SUB_THREEWAY);
04183    } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
04184       ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
04185       if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
04186          /*
04187           * This may not be safe.
04188           * We currently hold the locks on the real-call, private, and 3-way call.
04189           * We could possibly avoid this here by using an ast_queue_control() instead.
04190           * However, the following ast_channel_masquerade() is going to be locking
04191           * the bridged channel again anyway.
04192           */
04193          ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
04194       }
04195       if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
04196          tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
04197       }
04198       if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
04199          ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
04200                ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
04201          return -1;
04202       }
04203       /* Three-way is now the REAL */
04204       swap_subs(p, SUB_THREEWAY, SUB_REAL);
04205       ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
04206       unalloc_sub(p, SUB_THREEWAY);
04207       /* Tell the caller not to hangup */
04208       return 1;
04209    } else {
04210       ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
04211                p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
04212       return -1;
04213    }
04214    return 0;
04215 }
04216 
04217 static int check_for_conference(struct dahdi_pvt *p)
04218 {
04219    struct dahdi_confinfo ci;
04220    /* Fine if we already have a master, etc */
04221    if (p->master || (p->confno > -1))
04222       return 0;
04223    memset(&ci, 0, sizeof(ci));
04224    if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
04225       ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
04226       return 0;
04227    }
04228    /* If we have no master and don't have a confno, then 
04229       if we're in a conference, it's probably a MeetMe room or
04230       some such, so don't let us 3-way out! */
04231    if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
04232       if (option_verbose > 2) 
04233          ast_verbose(VERBOSE_PREFIX_3 "Avoiding 3-way call when in an external conference\n");
04234       return 1;
04235    }
04236    return 0;
04237 }
04238 
04239 static int get_alarms(struct dahdi_pvt *p)
04240 {
04241    int res;
04242    struct dahdi_spaninfo zi;
04243 #if !defined(HAVE_ZAPTEL) || defined(HAVE_ZAPTEL_CHANALARMS)
04244    /*
04245     * The conditional compilation is needed only in asterisk-1.4 for
04246     * backward compatibility with old zaptel drivers that don't have
04247     * a DAHDI_PARAMS.chan_alarms field.
04248     */
04249    struct dahdi_params params;
04250 #endif
04251 
04252    memset(&zi, 0, sizeof(zi));
04253    zi.spanno = p->span;
04254 
04255    /* First check for span alarms */
04256    if((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) < 0) {
04257       ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
04258       return 0;
04259    }
04260    if (zi.alarms != DAHDI_ALARM_NONE)
04261       return zi.alarms;
04262 #if !defined(HAVE_ZAPTEL) || defined(HAVE_ZAPTEL_CHANALARMS)
04263    /* No alarms on the span. Check for channel alarms. */
04264    memset(&params, 0, sizeof(params));
04265    if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &params)) >= 0)
04266       return params.chan_alarms;
04267    /* ioctl failed */
04268    ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
04269 #endif
04270    return DAHDI_ALARM_NONE;
04271 }
04272 
04273 static void dahdi_handle_dtmf(struct ast_channel *ast, int index, struct ast_frame **dest)
04274 {
04275    struct dahdi_pvt *p = ast->tech_pvt;
04276    struct ast_frame *f = *dest;
04277 
04278    if (option_debug)
04279       ast_log(LOG_DEBUG, "%s DTMF digit: 0x%02X '%c' on %s\n",
04280          f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
04281          f->subclass, f->subclass, ast->name);
04282 
04283    if (p->confirmanswer) {
04284       if (f->frametype == AST_FRAME_DTMF_END) {
04285          if (option_debug)
04286             ast_log(LOG_DEBUG, "Confirm answer on %s!\n", ast->name);
04287          /* Upon receiving a DTMF digit, consider this an answer confirmation instead
04288             of a DTMF digit */
04289          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04290          p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04291          /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
04292          p->confirmanswer = 0;
04293       } else {
04294          p->subs[index].f.frametype = AST_FRAME_NULL;
04295          p->subs[index].f.subclass = 0;
04296       }
04297       *dest = &p->subs[index].f;
04298    } else if (p->callwaitcas) {
04299       if (f->frametype == AST_FRAME_DTMF_END) {
04300          if ((f->subclass == 'A') || (f->subclass == 'D')) {
04301             if (option_debug)
04302                ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
04303             free(p->cidspill);
04304             p->cidspill = NULL;
04305             send_cwcidspill(p);
04306          }
04307          if ((f->subclass != 'm') && (f->subclass != 'u')) 
04308             p->callwaitcas = 0;
04309       }
04310       p->subs[index].f.frametype = AST_FRAME_NULL;
04311       p->subs[index].f.subclass = 0;
04312       *dest = &p->subs[index].f;
04313    } else if (f->subclass == 'f') {
04314       if (f->frametype == AST_FRAME_DTMF_END) {
04315          /* Fax tone -- Handle and return NULL */
04316          if ((p->callprogress & 0x6) && !p->faxhandled) {
04317             p->faxhandled = 1;
04318             if (strcmp(ast->exten, "fax")) {
04319                const char *target_context = S_OR(ast->macrocontext, ast->context);
04320 
04321                /* We need to unlock 'ast' here because ast_exists_extension has the
04322                 * potential to start autoservice on the channel. Such action is prone
04323                 * to deadlock.
04324                 */
04325                ast_mutex_unlock(&p->lock);
04326                ast_channel_unlock(ast);
04327                if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
04328                   ast_channel_lock(ast);
04329                   ast_mutex_lock(&p->lock);
04330                   if (option_verbose > 2)
04331                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
04332                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
04333                   pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
04334                   if (ast_async_goto(ast, target_context, "fax", 1))
04335                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
04336                } else {
04337                   ast_channel_lock(ast);
04338                   ast_mutex_lock(&p->lock);
04339                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
04340                }
04341             } else if (option_debug)
04342                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
04343          } else if (option_debug)
04344             ast_log(LOG_DEBUG, "Fax already handled\n");
04345          dahdi_confmute(p, 0);
04346       }
04347       p->subs[index].f.frametype = AST_FRAME_NULL;
04348       p->subs[index].f.subclass = 0;
04349       *dest = &p->subs[index].f;
04350    } else if (f->subclass == 'm') {
04351       if (f->frametype == AST_FRAME_DTMF_END) {
04352          /* Confmute request */
04353          dahdi_confmute(p, 1);
04354       }
04355       p->subs[index].f.frametype = AST_FRAME_NULL;
04356       p->subs[index].f.subclass = 0;
04357       *dest = &p->subs[index].f;    
04358    } else if (f->subclass == 'u') {
04359       if (f->frametype == AST_FRAME_DTMF_END) {
04360          /* Unmute */
04361          dahdi_confmute(p, 0);
04362       }
04363       p->subs[index].f.frametype = AST_FRAME_NULL;
04364       p->subs[index].f.subclass = 0;
04365       *dest = &p->subs[index].f;    
04366    } else {
04367       if (f->frametype == AST_FRAME_DTMF_END) {
04368          dahdi_confmute(p, 0);
04369       }
04370    }
04371 }
04372          
04373 static void handle_alarms(struct dahdi_pvt *p, int alarms)
04374 {
04375    const char *alarm_str = alarm2str(alarms);
04376    
04377    /* hack alert! Zaptel 1.4 and DAHDI expose FXO battery as an alarm, but this code
04378     * doesn't know what to do with it.  Don't confuse users with log messages. */
04379    if (!strcasecmp(alarm_str, "No Alarm") || !strcasecmp(alarm_str, "Unknown Alarm")) {
04380       p->unknown_alarm = 1;
04381       return;
04382    } else {
04383       p->unknown_alarm = 0;
04384    }
04385    
04386    ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
04387    manager_event(EVENT_FLAG_SYSTEM, "Alarm",
04388             "Alarm: %s\r\n"
04389             "Channel: %d\r\n",
04390             alarm_str, p->channel);
04391 }
04392 
04393 static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
04394 {
04395    int res, x;
04396    int index, mysig;
04397    char *c;
04398    struct dahdi_pvt *p = ast->tech_pvt;
04399    pthread_t threadid;
04400    pthread_attr_t attr;
04401    struct ast_channel *chan;
04402    struct ast_frame *f;
04403 
04404    index = dahdi_get_index(ast, p, 0);
04405    if (index < 0) {
04406       return &ast_null_frame;
04407    }
04408    if (index != SUB_REAL) {
04409       ast_log(LOG_ERROR, "We got an event on a non real sub.  Fix it!\n");
04410    }
04411 
04412    mysig = p->sig;
04413    if (p->outsigmod > -1)
04414       mysig = p->outsigmod;
04415 
04416    p->subs[index].f.frametype = AST_FRAME_NULL;
04417    p->subs[index].f.subclass = 0;
04418    p->subs[index].f.datalen = 0;
04419    p->subs[index].f.samples = 0;
04420    p->subs[index].f.mallocd = 0;
04421    p->subs[index].f.offset = 0;
04422    p->subs[index].f.src = "dahdi_handle_event";
04423    p->subs[index].f.data = NULL;
04424    f = &p->subs[index].f;
04425 
04426    if (p->fake_event) {
04427       res = p->fake_event;
04428       p->fake_event = 0;
04429    } else
04430       res = dahdi_get_event(p->subs[index].dfd);
04431 
04432    if (option_debug)
04433       ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
04434 
04435    if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
04436       p->pulsedial =  (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
04437 
04438       ast_log(LOG_DEBUG, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
04439 #ifdef HAVE_PRI
04440       if (p->sig == SIG_PRI
04441          && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
04442          && p->pri
04443          && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
04444          /* absorb event */
04445       } else
04446 #endif
04447       {
04448          p->subs[index].f.frametype = AST_FRAME_DTMF_END;
04449          p->subs[index].f.subclass = res & 0xff;
04450          dahdi_handle_dtmf(ast, index, &f);
04451       }
04452       return f;
04453    }
04454 
04455    if (res & DAHDI_EVENT_DTMFDOWN) {
04456       if (option_debug)
04457          ast_log(LOG_DEBUG, "DTMF Down '%c'\n", res & 0xff);
04458 #ifdef HAVE_PRI
04459       if (p->sig == SIG_PRI
04460          && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
04461          && p->pri
04462          && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
04463          /* absorb event */
04464       } else
04465 #endif
04466       {
04467          /* Mute conference */
04468          dahdi_confmute(p, 1);
04469          p->subs[index].f.frametype = AST_FRAME_DTMF_BEGIN;
04470          p->subs[index].f.subclass = res & 0xff;
04471          dahdi_handle_dtmf(ast, index, &f);
04472       }
04473       return &p->subs[index].f;
04474    }
04475 
04476    switch (res) {
04477 #ifdef DAHDI_EVENT_EC_DISABLED
04478       case DAHDI_EVENT_EC_DISABLED:
04479          if (option_verbose > 2) 
04480             ast_verbose(VERBOSE_PREFIX_3 "Channel %d echo canceler disabled due to CED detection\n", p->channel);
04481          p->echocanon = 0;
04482          break;
04483 #endif
04484       case DAHDI_EVENT_BITSCHANGED:
04485          ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
04486       case DAHDI_EVENT_PULSE_START:
04487          /* Stop tone if there's a pulse start and the PBX isn't started */
04488          if (!ast->pbx)
04489             tone_zone_play_tone(p->subs[index].dfd, -1);
04490          break;   
04491       case DAHDI_EVENT_DIALCOMPLETE:
04492          if (p->inalarm) break;
04493          if ((p->radio || (p->oprmode < 0))) break;
04494          if (ioctl(p->subs[index].dfd,DAHDI_DIALING,&x) == -1) {
04495             ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno));
04496             return NULL;
04497          }
04498          if (!x) { /* if not still dialing in driver */
04499             dahdi_enable_ec(p);
04500             if (p->echobreak) {
04501                dahdi_train_ec(p);
04502                ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
04503                p->dop.op = DAHDI_DIAL_OP_REPLACE;
04504                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
04505                p->echobreak = 0;
04506             } else {
04507                p->dialing = 0;
04508                if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
04509                   /* if thru with dialing after offhook */
04510                   if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
04511                      ast_setstate(ast, AST_STATE_UP);
04512                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
04513                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04514                      break;
04515                   } else { /* if to state wait for offhook to dial rest */
04516                      /* we now wait for off hook */
04517                      ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
04518                   }
04519                }
04520                if (ast->_state == AST_STATE_DIALING) {
04521                   if ((p->callprogress & 1) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
04522                      ast_log(LOG_DEBUG, "Done dialing, but waiting for progress detection before doing more...\n");
04523                   } 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)))) {
04524                      ast_setstate(ast, AST_STATE_RINGING);
04525                   } else if (!p->answeronpolarityswitch) {
04526                      ast_setstate(ast, AST_STATE_UP);
04527                      p->subs[index].f.frametype = AST_FRAME_CONTROL;
04528                      p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04529                      /* If aops=0 and hops=1, this is necessary */
04530                      p->polarity = POLARITY_REV;
04531                   } else {
04532                      /* Start clean, so we can catch the change to REV polarity when party answers */
04533                      p->polarity = POLARITY_IDLE;
04534                   }
04535                }
04536             }
04537          }
04538          break;
04539       case DAHDI_EVENT_ALARM:
04540 #ifdef HAVE_PRI
04541          if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
04542             /* T309 is not enabled : destroy calls when alarm occurs */
04543             if (p->call) {
04544                if (p->pri && p->pri->pri) {
04545                   pri_grab(p, p->pri);
04546                   pri_destroycall(p->pri->pri, p->call);
04547                   p->call = NULL;
04548                   pri_rel(p->pri);
04549                } else
04550                   ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
04551             }
04552             if (p->owner)
04553                p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
04554          }
04555          if (p->bearer) {
04556             p->bearer->inalarm = 1;
04557             p->bearer->resetting = 0;
04558          } else
04559 #endif
04560          {
04561             p->inalarm = 1;
04562 #if defined(HAVE_PRI)
04563             p->resetting = 0;
04564 #endif   /* defined(HAVE_PRI) */
04565          }
04566          res = get_alarms(p);
04567          handle_alarms(p, res);
04568 #ifdef HAVE_PRI
04569          if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
04570             /* fall through intentionally */
04571          } else {
04572             break;
04573          }
04574 #endif
04575       case DAHDI_EVENT_ONHOOK:
04576          if (p->radio) {
04577             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04578             p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
04579             break;
04580          }
04581          if (p->oprmode < 0)
04582          {
04583             if (p->oprmode != -1) break;
04584             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04585             {
04586                /* Make sure it starts ringing */
04587                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
04588                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
04589                save_conference(p->oprpeer);
04590                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
04591             }
04592             break;
04593          }
04594          switch (p->sig) {
04595          case SIG_FXOLS:
04596          case SIG_FXOGS:
04597          case SIG_FXOKS:
04598             p->onhooktime = time(NULL);
04599             p->msgstate = -1;
04600             /* Check for some special conditions regarding call waiting */
04601             if (index == SUB_REAL) {
04602                /* The normal line was hung up */
04603                if (p->subs[SUB_CALLWAIT].owner) {
04604                   /* Need to hold the lock for real-call, private, and call-waiting call */
04605                   dahdi_lock_sub_owner(p, SUB_CALLWAIT);
04606                   if (!p->subs[SUB_CALLWAIT].owner) {
04607                      /*
04608                       * The call waiting call dissappeared.
04609                       * This is now a normal hangup.
04610                       */
04611                      dahdi_disable_ec(p);
04612                      return NULL;
04613                   }
04614 
04615                   /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
04616                   swap_subs(p, SUB_CALLWAIT, SUB_REAL);
04617                   if (option_verbose > 2) 
04618                      ast_verbose(VERBOSE_PREFIX_3 "Channel %d still has (callwait) call, ringing phone\n", p->channel);
04619                   unalloc_sub(p, SUB_CALLWAIT); 
04620 #if 0
04621                   p->subs[index].needanswer = 0;
04622                   p->subs[index].needringing = 0;
04623 #endif                  
04624                   p->callwaitingrepeat = 0;
04625                   p->cidcwexpire = 0;
04626                   p->cid_suppress_expire = 0;
04627                   p->owner = NULL;
04628                   /* Don't start streaming audio yet if the incoming call isn't up yet */
04629                   if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
04630                      p->dialing = 1;
04631                   /* Unlock the call-waiting call that we swapped to real-call. */
04632                   ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
04633                   dahdi_ring_phone(p);
04634                } else if (p->subs[SUB_THREEWAY].owner) {
04635                   unsigned int mssinceflash;
04636 
04637                   /* Need to hold the lock for real-call, private, and 3-way call */
04638                   dahdi_lock_sub_owner(p, SUB_THREEWAY);
04639                   if (!p->subs[SUB_THREEWAY].owner) {
04640                      ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
04641                      /* Just hangup */
04642                      return NULL;
04643                   }
04644                   if (p->owner != ast) {
04645                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04646                      ast_log(LOG_WARNING, "This isn't good...\n");
04647                      /* Just hangup */
04648                      return NULL;
04649                   }
04650 
04651                   mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
04652                   ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
04653                   if (mssinceflash < MIN_MS_SINCE_FLASH) {
04654                      /* It hasn't been long enough since the last flashook.  This is probably a bounce on 
04655                         hanging up.  Hangup both channels now */
04656                      ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
04657                      ast_queue_hangup(p->subs[SUB_THREEWAY].owner);
04658                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04659                      ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04660                   } else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
04661                      if (p->transfer) {
04662                         /* In any case this isn't a threeway call anymore */
04663                         p->subs[SUB_REAL].inthreeway = 0;
04664                         p->subs[SUB_THREEWAY].inthreeway = 0;
04665                         /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
04666                         if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
04667                            /* Swap subs and dis-own channel */
04668                            swap_subs(p, SUB_THREEWAY, SUB_REAL);
04669                            /* Unlock the 3-way call that we swapped to real-call. */
04670                            ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
04671                            p->owner = NULL;
04672                            /* Ring the phone */
04673                            dahdi_ring_phone(p);
04674                         } else {
04675                            res = attempt_transfer(p);
04676                            if (res < 0) {
04677                               /* Transfer attempt failed. */
04678                               p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04679                               ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04680                            } else if (res) {
04681                               /* Don't actually hang up at this point */
04682                               break;
04683                            }
04684                         }
04685                      } else {
04686                         p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
04687                         ast_mutex_unlock(&p->subs[SUB_THREEWAY].owner->lock);
04688                      }
04689                   } else {
04690                      /* Swap subs and dis-own channel */
04691                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
04692                      /* Unlock the 3-way call that we swapped to real-call. */
04693                      ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
04694                      p->owner = NULL;
04695                      /* Ring the phone */
04696                      dahdi_ring_phone(p);
04697                   }
04698                }
04699             } else {
04700                ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", index);
04701             }
04702             /* Fall through */
04703          default:
04704             dahdi_disable_ec(p);
04705             return NULL;
04706          }
04707          break;
04708       case DAHDI_EVENT_RINGOFFHOOK:
04709          if (p->inalarm) break;
04710          if (p->oprmode < 0)
04711          {
04712             if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
04713             {
04714                /* Make sure it stops ringing */
04715                dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
04716                tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
04717                restore_conference(p->oprpeer);
04718             }
04719             break;
04720          }
04721          if (p->radio)
04722          {
04723             p->subs[index].f.frametype = AST_FRAME_CONTROL;
04724             p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
04725             break;
04726          }
04727          /* for E911, its supposed to wait for offhook then dial
04728             the second half of the dial string */
04729          if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
04730             c = strchr(p->dialdest, '/');
04731             if (c)
04732                c++;
04733             else
04734                c = p->dialdest;
04735             if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
04736             else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
04737             if (strlen(p->dop.dialstr) > 4) {
04738                memset(p->echorest, 'w', sizeof(p->echorest) - 1);
04739                strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
04740                p->echorest[sizeof(p->echorest) - 1] = '\0';
04741                p->echobreak = 1;
04742                p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
04743             } else
04744                p->echobreak = 0;
04745             if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
04746                int saveerr = errno;
04747 
04748                x = DAHDI_ONHOOK;
04749                ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
04750                ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
04751                return NULL;
04752                }
04753             p->dialing = 1;
04754             return &p->subs[index].f;
04755          }
04756          switch (p->sig) {
04757          case SIG_FXOLS:
04758          case SIG_FXOGS:
04759          case SIG_FXOKS:
04760             switch (ast->_state) {
04761             case AST_STATE_RINGING:
04762                dahdi_enable_ec(p);
04763                dahdi_train_ec(p);
04764                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04765                p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04766                /* Make sure it stops ringing */
04767                dahdi_set_hook(p->subs[index].dfd, DAHDI_OFFHOOK);
04768                p->subs[SUB_REAL].needringing = 0;
04769                ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
04770 
04771                /* Cancel any running CallerID spill */
04772                free(p->cidspill);
04773                p->cidspill = NULL;
04774                restore_conference(p);
04775 
04776                p->dialing = 0;
04777                p->callwaitcas = 0;
04778                if (p->confirmanswer) {
04779                   /* Ignore answer if "confirm answer" is enabled */
04780                   p->subs[index].f.frametype = AST_FRAME_NULL;
04781                   p->subs[index].f.subclass = 0;
04782                } else if (!ast_strlen_zero(p->dop.dialstr)) {
04783                   /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
04784                   res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
04785                   if (res < 0) {
04786                      ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
04787                      p->dop.dialstr[0] = '\0';
04788                      return NULL;
04789                   } else {
04790                      ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
04791                      p->subs[index].f.frametype = AST_FRAME_NULL;
04792                      p->subs[index].f.subclass = 0;
04793                      p->dialing = 1;
04794                   }
04795                   p->dop.dialstr[0] = '\0';
04796                   ast_setstate(ast, AST_STATE_DIALING);
04797                } else
04798                   ast_setstate(ast, AST_STATE_UP);
04799                return &p->subs[index].f;
04800             case AST_STATE_DOWN:
04801                ast_setstate(ast, AST_STATE_RING);
04802                ast->rings = 1;
04803                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04804                p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
04805                ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
04806                return &p->subs[index].f;
04807             case AST_STATE_UP:
04808                /* Make sure it stops ringing */
04809                dahdi_set_hook(p->subs[index].dfd, DAHDI_OFFHOOK);
04810                /* Okay -- probably call waiting*/
04811                if (ast_bridged_channel(p->owner))
04812                   ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
04813                p->subs[index].needunhold = 1;
04814                break;
04815             case AST_STATE_RESERVED:
04816                /* Start up dialtone */
04817                if (has_voicemail(p))
04818                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
04819                else
04820                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
04821                break;
04822             default:
04823                ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
04824             }
04825             break;
04826          case SIG_FXSLS:
04827          case SIG_FXSGS:
04828          case SIG_FXSKS:
04829             if (ast->_state == AST_STATE_RING) {
04830                p->ringt = p->ringt_base;
04831             }
04832 
04833             /* Fall through */
04834          case SIG_EM:
04835          case SIG_EM_E1:
04836          case SIG_EMWINK:
04837          case SIG_FEATD:
04838          case SIG_FEATDMF:
04839          case SIG_FEATDMF_TA:
04840          case SIG_E911:
04841          case SIG_FGC_CAMA:
04842          case SIG_FGC_CAMAMF:
04843          case SIG_FEATB:
04844          case SIG_SF:
04845          case SIG_SFWINK:
04846          case SIG_SF_FEATD:
04847          case SIG_SF_FEATDMF:
04848          case SIG_SF_FEATB:
04849             if (ast->_state == AST_STATE_PRERING)
04850                ast_setstate(ast, AST_STATE_RING);
04851             if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
04852                if (option_debug)
04853                   ast_log(LOG_DEBUG, "Ring detected\n");
04854                p->subs[index].f.frametype = AST_FRAME_CONTROL;
04855                p->subs[index].f.subclass = AST_CONTROL_RING;
04856             } else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
04857                if (option_debug)
04858                   ast_log(LOG_DEBUG, "Line answered\n");
04859                if (p->confirmanswer) {
04860                   p->subs[index].f.frametype = AST_FRAME_NULL;
04861                   p->subs[index].f.subclass = 0;
04862                } else {
04863                   p->subs[index].f.frametype = AST_FRAME_CONTROL;
04864                   p->subs[index].f.subclass = AST_CONTROL_ANSWER;
04865                   ast_setstate(ast, AST_STATE_UP);
04866                }
04867             } else if (ast->_state != AST_STATE_RING)
04868                ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
04869             break;
04870          default:
04871             ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
04872          }
04873          break;
04874 #ifdef DAHDI_EVENT_RINGBEGIN
04875       case DAHDI_EVENT_RINGBEGIN:
04876          switch (p->sig) {
04877          case SIG_FXSLS:
04878          case SIG_FXSGS:
04879          case SIG_FXSKS:
04880             if (ast->_state == AST_STATE_RING) {
04881                p->ringt = p->ringt_base;
04882             }
04883             break;
04884          }
04885          break;
04886 #endif         
04887       case DAHDI_EVENT_RINGEROFF:
04888          if (p->inalarm) break;
04889          if ((p->radio || (p->oprmode < 0))) break;
04890          ast->rings++;
04891          if ((ast->rings > p->cidrings) && (p->cidspill)) {
04892             ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
04893             free(p->cidspill);
04894             p->cidspill = NULL;
04895             p->callwaitcas = 0;
04896          }
04897          p->subs[index].f.frametype = AST_FRAME_CONTROL;
04898          p->subs[index].f.subclass = AST_CONTROL_RINGING;
04899          break;
04900       case DAHDI_EVENT_RINGERON:
04901          break;
04902       case DAHDI_EVENT_NOALARM:
04903          p->inalarm = 0;
04904 #ifdef HAVE_PRI
04905          p->resetting = 0;
04906          /* Extremely unlikely but just in case */
04907          if (p->bearer) {
04908             p->bearer->inalarm = 0;
04909             p->bearer->resetting = 0;
04910          }
04911 #endif            
04912          if (!p->unknown_alarm) {
04913             ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
04914             manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
04915                "Channel: %d\r\n", p->channel);
04916          } else {
04917             p->unknown_alarm = 0;
04918          }
04919          break;
04920       case DAHDI_EVENT_WINKFLASH:
04921          if (p->inalarm) break;
04922          if (p->radio) break;
04923          if (p->oprmode < 0) break;
04924          if (p->oprmode > 1)
04925          {
04926             struct dahdi_params par;
04927 
04928             memset(&par, 0, sizeof(par));
04929             if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
04930             {
04931                if (!par.rxisoffhook)
04932                {
04933                   /* Make sure it stops ringing */
04934                   dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
04935                   dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
04936                   save_conference(p);
04937                   tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
04938                }
04939             }
04940             break;
04941          }
04942          /* Remember last time we got a flash-hook */
04943          gettimeofday(&p->flashtime, NULL);
04944          switch (mysig) {
04945          case SIG_FXOLS:
04946          case SIG_FXOGS:
04947          case SIG_FXOKS:
04948             ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
04949                index, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
04950 
04951             /* Cancel any running CallerID spill */
04952             free(p->cidspill);
04953             p->cidspill = NULL;
04954             restore_conference(p);
04955             p->callwaitcas = 0;
04956 
04957             if (index != SUB_REAL) {
04958                ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", index, p->channel);
04959                goto winkflashdone;
04960             }
04961             
04962             if (p->subs[SUB_CALLWAIT].owner) {
04963                /* Need to hold the lock for real-call, private, and call-waiting call */
04964                dahdi_lock_sub_owner(p, SUB_CALLWAIT);
04965                if (!p->subs[SUB_CALLWAIT].owner) {
04966                   /*
04967                    * The call waiting call dissappeared.
04968                    * Let's just ignore this flash-hook.
04969                    */
04970                   ast_log(LOG_NOTICE, "Whoa, the call-waiting call disappeared.\n");
04971                   goto winkflashdone;
04972                }
04973 
04974                /* Swap to call-wait */
04975                swap_subs(p, SUB_REAL, SUB_CALLWAIT);
04976                tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
04977                p->owner = p->subs[SUB_REAL].owner;
04978                ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
04979                if (p->owner->_state == AST_STATE_RINGING) {
04980                   ast_setstate(p->owner, AST_STATE_UP);
04981                   p->subs[SUB_REAL].needanswer = 1;
04982                }
04983                p->callwaitingrepeat = 0;
04984                p->cidcwexpire = 0;
04985                p->cid_suppress_expire = 0;
04986 
04987                /* Start music on hold if appropriate */
04988                if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
04989                   ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
04990                      S_OR(p->mohsuggest, NULL),
04991                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04992                }
04993                p->subs[SUB_CALLWAIT].needhold = 1;
04994                if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
04995                   ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
04996                      S_OR(p->mohsuggest, NULL),
04997                      !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
04998                }
04999                p->subs[SUB_REAL].needunhold = 1;
05000 
05001                /* Unlock the call-waiting call that we swapped to real-call. */
05002                ast_mutex_unlock(&p->subs[SUB_REAL].owner->lock);
05003             } else if (!p->subs[SUB_THREEWAY].owner) {
05004                if (!p->threewaycalling) {
05005                   /* Just send a flash if no 3-way calling */
05006                   p->subs[SUB_REAL].needflash = 1;
05007                   goto winkflashdone;
05008                } else if (!check_for_conference(p)) {
05009                   char cid_num[256];
05010                   char cid_name[256];
05011 
05012                   cid_num[0] = 0;
05013                   cid_name[0] = 0;
05014                   if (p->dahditrcallerid && p->owner) {
05015                      if (p->owner->cid.cid_num)
05016                         ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
05017                      if (p->owner->cid.cid_name)
05018                         ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
05019                   }
05020                   /* XXX This section needs much more error checking!!! XXX */
05021                   /* Start a 3-way call if feasible */
05022                   if (!((ast->pbx) ||
05023                         (ast->_state == AST_STATE_UP) ||
05024                         (ast->_state == AST_STATE_RING))) {
05025                      ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
05026                         goto winkflashdone;
05027                   }
05028                   if (alloc_sub(p, SUB_THREEWAY)) {
05029                      ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
05030                      goto winkflashdone;
05031                   }
05032                   /* Make new channel */
05033                   chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
05034                   if (!chan) {
05035                      ast_log(LOG_WARNING,
05036                         "Cannot allocate new call structure on channel %d\n",
05037                         p->channel);
05038                      unalloc_sub(p, SUB_THREEWAY);
05039                      goto winkflashdone;
05040                   }
05041                   if (p->dahditrcallerid) {
05042                      if (!p->origcid_num)
05043                         p->origcid_num = ast_strdup(p->cid_num);
05044                      if (!p->origcid_name)
05045                         p->origcid_name = ast_strdup(p->cid_name);
05046                      ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
05047                      ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
05048                   }
05049                   /* Swap things around between the three-way and real call */
05050                   swap_subs(p, SUB_THREEWAY, SUB_REAL);
05051                   /* Disable echo canceller for better dialing */
05052                   dahdi_disable_ec(p);
05053                   res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
05054                   if (res)
05055                      ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
05056                   p->owner = chan;
05057                   pthread_attr_init(&attr);
05058                   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05059                   if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
05060                      ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
05061                      res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
05062                      dahdi_enable_ec(p);
05063                      ast_hangup(chan);
05064                   } else {
05065                      if (option_verbose > 2) 
05066                         ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d\n", p->channel);
05067                      /* Start music on hold if appropriate */
05068                      if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
05069                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
05070                            S_OR(p->mohsuggest, NULL),
05071                            !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
05072                      }
05073                      p->subs[SUB_THREEWAY].needhold = 1;
05074                   }
05075                   pthread_attr_destroy(&attr);
05076                }
05077             } else {
05078                /* Already have a 3 way call */
05079                int orig_3way_sub;
05080 
05081                /* Need to hold the lock for real-call, private, and 3-way call */
05082                dahdi_lock_sub_owner(p, SUB_THREEWAY);
05083                if (!p->subs[SUB_THREEWAY].owner) {
05084                   /*
05085                    * The 3-way call dissappeared.
05086                    * Let's just ignore this flash-hook.
05087                    */
05088                   ast_log(LOG_NOTICE, "Whoa, the 3-way call disappeared.\n");
05089                   goto winkflashdone;
05090                }
05091                orig_3way_sub = SUB_THREEWAY;
05092 
05093                if (p->subs[SUB_THREEWAY].inthreeway) {
05094                   /* Call is already up, drop the last person */
05095                   if (option_debug)
05096                      ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
05097                   /* If the primary call isn't answered yet, use it */
05098                   if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
05099                      /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
05100                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
05101                      orig_3way_sub = SUB_REAL;
05102                      p->owner = p->subs[SUB_REAL].owner;
05103                   }
05104                   /* Drop the last call and stop the conference */
05105                   if (option_verbose > 2)
05106                      ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
05107                   p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05108                   p->subs[SUB_REAL].inthreeway = 0;
05109                   p->subs[SUB_THREEWAY].inthreeway = 0;
05110                } else {
05111                   /* Lets see what we're up to */
05112                   if (((ast->pbx) || (ast->_state == AST_STATE_UP)) && 
05113                       (p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
05114                      if (option_verbose > 2) {
05115                         ast_verbose(VERBOSE_PREFIX_3 "Building conference call with %s and %s\n",
05116                            p->subs[SUB_THREEWAY].owner->name,
05117                            p->subs[SUB_REAL].owner->name);
05118                      }
05119                      /* Put them in the threeway, and flip */
05120                      p->subs[SUB_THREEWAY].inthreeway = 1;
05121                      p->subs[SUB_REAL].inthreeway = 1;
05122                      if (ast->_state == AST_STATE_UP) {
05123                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
05124                         orig_3way_sub = SUB_REAL;
05125                      }
05126                      if (ast_bridged_channel(p->subs[orig_3way_sub].owner)) {
05127                         ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD);
05128                      }
05129                      p->subs[orig_3way_sub].needunhold = 1;
05130                      p->owner = p->subs[SUB_REAL].owner;
05131                   } else {
05132                      if (option_verbose > 2)
05133                         ast_verbose(VERBOSE_PREFIX_3 "Dumping incomplete call on %s\n", p->subs[SUB_THREEWAY].owner->name);
05134                      swap_subs(p, SUB_THREEWAY, SUB_REAL);
05135                      orig_3way_sub = SUB_REAL;
05136                      p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
05137                      p->owner = p->subs[SUB_REAL].owner;
05138                      if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
05139                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
05140                      }
05141                      p->subs[SUB_REAL].needunhold = 1;
05142                      dahdi_enable_ec(p);
05143                   }
05144                      
05145                }
05146                ast_mutex_unlock(&p->subs[orig_3way_sub].owner->lock);
05147             }
05148 winkflashdone:
05149             update_conf(p);
05150             break;
05151          case SIG_EM:
05152          case SIG_EM_E1:
05153          case SIG_FEATD:
05154          case SIG_SF:
05155          case SIG_SFWINK:
05156          case SIG_SF_FEATD:
05157          case SIG_FXSLS:
05158          case SIG_FXSGS:
05159             if (p->dialing)
05160                ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
05161             else
05162                ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
05163             break;
05164          case SIG_FEATDMF_TA:
05165             switch (p->whichwink) {
05166             case 0:
05167                ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
05168                snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
05169                break;
05170             case 1:
05171                ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
05172                break;
05173             case 2:
05174                ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
05175                return NULL;
05176             }
05177             p->whichwink++;
05178             /* Fall through */
05179          case SIG_FEATDMF:
05180          case SIG_E911:
05181          case SIG_FGC_CAMAMF:
05182          case SIG_FGC_CAMA:
05183          case SIG_FEATB:
05184          case SIG_SF_FEATDMF:
05185          case SIG_SF_FEATB:
05186          case SIG_EMWINK:
05187             /* FGD MF and EMWINK *Must* wait for wink */
05188             if (!ast_strlen_zero(p->dop.dialstr)) {
05189                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
05190                if (res < 0) {
05191                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
05192                   p->dop.dialstr[0] = '\0';
05193                   return NULL;
05194                } else 
05195                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
05196             }
05197             p->dop.dialstr[0] = '\0';
05198             break;
05199          default:
05200             ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
05201          }
05202          break;
05203       case DAHDI_EVENT_HOOKCOMPLETE:
05204          if (p->inalarm) break;
05205          if ((p->radio || (p->oprmode < 0))) break;
05206          switch (mysig) {
05207          case SIG_FXSLS:  /* only interesting for FXS */
05208          case SIG_FXSGS:
05209          case SIG_FXSKS:
05210          case SIG_EM:
05211          case SIG_EM_E1:
05212          case SIG_EMWINK:
05213          case SIG_FEATD:
05214          case SIG_SF:
05215          case SIG_SFWINK:
05216          case SIG_SF_FEATD:
05217             if (!ast_strlen_zero(p->dop.dialstr)) {
05218                res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
05219                if (res < 0) {
05220                   ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
05221                   p->dop.dialstr[0] = '\0';
05222                   return NULL;
05223                } else 
05224                   ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
05225             }
05226             p->dop.dialstr[0] = '\0';
05227             p->dop.op = DAHDI_DIAL_OP_REPLACE;
05228             break;
05229          case SIG_FEATDMF:
05230          case SIG_FEATDMF_TA:
05231          case SIG_E911:
05232          case SIG_FGC_CAMA:
05233          case SIG_FGC_CAMAMF:
05234          case SIG_FEATB:
05235          case SIG_SF_FEATDMF:
05236          case SIG_SF_FEATB:
05237             ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
05238             break;
05239          default:
05240             break;
05241          }
05242          break;
05243       case DAHDI_EVENT_POLARITY:
05244          /*
05245           * If we get a Polarity Switch event, check to see
05246           * if we should change the polarity state and
05247           * mark the channel as UP or if this is an indication
05248           * of remote end disconnect.
05249           */
05250          if (p->polarity == POLARITY_IDLE) {
05251             p->polarity = POLARITY_REV;
05252             if (p->answeronpolarityswitch &&
05253                 ((ast->_state == AST_STATE_DIALING) ||
05254                 (ast->_state == AST_STATE_RINGING))) {
05255                ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
05256                ast_setstate(p->owner, AST_STATE_UP);
05257                if (p->hanguponpolarityswitch) {
05258                   gettimeofday(&p->polaritydelaytv, NULL);
05259                }
05260             } else
05261                ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
05262          } 
05263          /* Removed else statement from here as it was preventing hangups from ever happening*/
05264          /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
05265          if (p->hanguponpolarityswitch &&
05266             (p->polarityonanswerdelay > 0) &&
05267                 (p->polarity == POLARITY_REV) &&
05268             ((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
05269                                 /* Added log_debug information below to provide a better indication of what is going on */
05270             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) );
05271          
05272             if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
05273                ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
05274                ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
05275                p->polarity = POLARITY_IDLE;
05276             } else {
05277                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);
05278             }
05279          } else {
05280             p->polarity = POLARITY_IDLE;
05281             ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
05282          }
05283                         /* Added more log_debug information below to provide a better indication of what is going on */
05284          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) );
05285          break;
05286       default:
05287          ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
05288    }
05289    return &p->subs[index].f;
05290 }
05291 
05292 static struct ast_frame *__dahdi_exception(struct ast_channel *ast)
05293 {
05294    struct dahdi_pvt *p = ast->tech_pvt;
05295    int res;
05296    int index;
05297    struct ast_frame *f;
05298 
05299 
05300    index = dahdi_get_index(ast, p, 1);
05301    if (index < 0) {
05302       index = SUB_REAL;
05303    }
05304    
05305    p->subs[index].f.frametype = AST_FRAME_NULL;
05306    p->subs[index].f.datalen = 0;
05307    p->subs[index].f.samples = 0;
05308    p->subs[index].f.mallocd = 0;
05309    p->subs[index].f.offset = 0;
05310    p->subs[index].f.subclass = 0;
05311    p->subs[index].f.delivery = ast_tv(0,0);
05312    p->subs[index].f.src = "dahdi_exception";
05313    p->subs[index].f.data = NULL;
05314    
05315    if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
05316       /* If nobody owns us, absorb the event appropriately, otherwise
05317          we loop indefinitely.  This occurs when, during call waiting, the
05318          other end hangs up our channel so that it no longer exists, but we
05319          have neither FLASH'd nor ONHOOK'd to signify our desire to
05320          change to the other channel. */
05321       if (p->fake_event) {
05322          res = p->fake_event;
05323          p->fake_event = 0;
05324       } else
05325          res = dahdi_get_event(p->subs[SUB_REAL].dfd);
05326       /* Switch to real if there is one and this isn't something really silly... */
05327       if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
05328          (res != DAHDI_EVENT_HOOKCOMPLETE)) {
05329          ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
05330          p->owner = p->subs[SUB_REAL].owner;
05331          if (p->owner && ast != p->owner) {
05332             /*
05333              * Could this even happen?
05334              * Possible deadlock because we do not have the real-call lock.
05335              */
05336             ast_log(LOG_WARNING, "Event %s on %s is not restored owner %s\n",
05337                event2str(res), ast->name, p->owner->name);
05338          }
05339          if (p->owner && ast_bridged_channel(p->owner))
05340             ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
05341          p->subs[SUB_REAL].needunhold = 1;
05342       }
05343       switch (res) {
05344       case DAHDI_EVENT_ONHOOK:
05345          dahdi_disable_ec(p);
05346          if (p->owner) {
05347             if (option_verbose > 2) 
05348                ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
05349             dahdi_ring_phone(p);
05350             p->callwaitingrepeat = 0;
05351             p->cidcwexpire = 0;
05352             p->cid_suppress_expire = 0;
05353          } else {
05354             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
05355                event2str(res));
05356          }
05357          update_conf(p);
05358          break;
05359       case DAHDI_EVENT_RINGOFFHOOK:
05360          dahdi_enable_ec(p);
05361          dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
05362          if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
05363             p->subs[SUB_REAL].needanswer = 1;
05364             p->dialing = 0;
05365          }
05366          break;
05367       case DAHDI_EVENT_HOOKCOMPLETE:
05368       case DAHDI_EVENT_RINGERON:
05369       case DAHDI_EVENT_RINGEROFF:
05370          /* Do nothing */
05371          break;
05372       case DAHDI_EVENT_WINKFLASH:
05373          gettimeofday(&p->flashtime, NULL);
05374          if (p->owner) {
05375             if (option_verbose > 2) 
05376                ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
05377             if (p->owner->_state != AST_STATE_UP) {
05378                /* Answer if necessary */
05379                p->subs[SUB_REAL].needanswer = 1;
05380                ast_setstate(p->owner, AST_STATE_UP);
05381             }
05382             p->callwaitingrepeat = 0;
05383             p->cidcwexpire = 0;
05384             p->cid_suppress_expire = 0;
05385             if (ast_bridged_channel(p->owner))
05386                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
05387             p->subs[SUB_REAL].needunhold = 1;
05388          } else {
05389             ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
05390                event2str(res));
05391          }
05392          update_conf(p);
05393          break;
05394       default:
05395          ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
05396          break;
05397       }
05398       f = &p->subs[index].f;
05399       return f;
05400    }
05401    if (!(p->radio || (p->oprmode < 0)) && option_debug) 
05402       ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
05403    /* If it's not us, return NULL immediately */
05404    if (ast != p->owner) {
05405       ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
05406       f = &p->subs[index].f;
05407       return f;
05408    }
05409    f = dahdi_handle_event(ast);
05410    return f;
05411 }
05412 
05413 static struct ast_frame *dahdi_exception(struct ast_channel *ast)
05414 {
05415    struct dahdi_pvt *p = ast->tech_pvt;
05416    struct ast_frame *f;
05417    ast_mutex_lock(&p->lock);
05418    f = __dahdi_exception(ast);
05419    ast_mutex_unlock(&p->lock);
05420    return f;
05421 }
05422 
05423 static struct ast_frame  *dahdi_read(struct ast_channel *ast)
05424 {
05425    struct dahdi_pvt *p;
05426    int res;
05427    int index;
05428    void *readbuf;
05429    struct ast_frame *f;
05430 
05431    /*
05432     * For analog channels, we must do deadlock avoidance because
05433     * analog ports can have more than one Asterisk channel using
05434     * the same private structure.
05435     */
05436    p = ast->tech_pvt;
05437    while (ast_mutex_trylock(&p->lock)) {
05438       DEADLOCK_AVOIDANCE(&ast->lock);
05439 
05440       /*
05441        * For PRI channels, we must refresh the private pointer because
05442        * the call could move to another B channel while the Asterisk
05443        * channel is unlocked.
05444        */
05445       p = ast->tech_pvt;
05446    }
05447 
05448    index = dahdi_get_index(ast, p, 0);
05449    
05450    /* Hang up if we don't really exist */
05451    if (index < 0) {
05452       ast_log(LOG_WARNING, "We don't exist?\n");
05453       ast_mutex_unlock(&p->lock);
05454       return NULL;
05455    }
05456    
05457    if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
05458       ast_mutex_unlock(&p->lock);
05459       return NULL;
05460    }
05461 
05462    p->subs[index].f.frametype = AST_FRAME_NULL;
05463    p->subs[index].f.datalen = 0;
05464    p->subs[index].f.samples = 0;
05465    p->subs[index].f.mallocd = 0;
05466    p->subs[index].f.offset = 0;
05467    p->subs[index].f.subclass = 0;
05468    p->subs[index].f.delivery = ast_tv(0,0);
05469    p->subs[index].f.src = "dahdi_read";
05470    p->subs[index].f.data = NULL;
05471    
05472    /* make sure it sends initial key state as first frame */
05473    if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
05474    {
05475       struct dahdi_params ps;
05476 
05477       memset(&ps, 0, sizeof(ps));
05478       ps.channo = p->channel;
05479       if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
05480          ast_mutex_unlock(&p->lock);
05481          return NULL;
05482       }
05483       p->firstradio = 1;
05484       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05485       if (ps.rxisoffhook)
05486       {
05487          p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
05488       }
05489       else
05490       {
05491          p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
05492       }
05493       ast_mutex_unlock(&p->lock);
05494       return &p->subs[index].f;
05495    }
05496    if (p->ringt == 1) {
05497       ast_mutex_unlock(&p->lock);
05498       return NULL;
05499    }
05500    else if (p->ringt > 0) 
05501       p->ringt--;
05502 
05503    if (p->subs[index].needringing) {
05504       /* Send ringing frame if requested */
05505       p->subs[index].needringing = 0;
05506       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05507       p->subs[index].f.subclass = AST_CONTROL_RINGING;
05508       ast_setstate(ast, AST_STATE_RINGING);
05509       ast_mutex_unlock(&p->lock);
05510       return &p->subs[index].f;
05511    }
05512 
05513    if (p->subs[index].needbusy) {
05514       /* Send busy frame if requested */
05515       p->subs[index].needbusy = 0;
05516       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05517       p->subs[index].f.subclass = AST_CONTROL_BUSY;
05518       ast_mutex_unlock(&p->lock);
05519       return &p->subs[index].f;
05520    }
05521 
05522    if (p->subs[index].needcongestion) {
05523       /* Send congestion frame if requested */
05524       p->subs[index].needcongestion = 0;
05525       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05526       p->subs[index].f.subclass = AST_CONTROL_CONGESTION;
05527       ast_mutex_unlock(&p->lock);
05528       return &p->subs[index].f;
05529    }
05530 
05531    if (p->subs[index].needcallerid && !ast->cid.cid_tns) {
05532       ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
05533                      S_OR(p->lastcid_name, NULL),
05534                      S_OR(p->lastcid_num, NULL)
05535                      );
05536       p->subs[index].needcallerid = 0;
05537    }
05538    
05539    if (p->subs[index].needanswer) {
05540       /* Send answer frame if requested */
05541       p->subs[index].needanswer = 0;
05542       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05543       p->subs[index].f.subclass = AST_CONTROL_ANSWER;
05544       ast_mutex_unlock(&p->lock);
05545       return &p->subs[index].f;
05546    }  
05547    
05548    if (p->subs[index].needflash) {
05549       /* Send answer frame if requested */
05550       p->subs[index].needflash = 0;
05551       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05552       p->subs[index].f.subclass = AST_CONTROL_FLASH;
05553       ast_mutex_unlock(&p->lock);
05554       return &p->subs[index].f;
05555    }  
05556    
05557    if (p->subs[index].needhold) {
05558       /* Send answer frame if requested */
05559       p->subs[index].needhold = 0;
05560       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05561       p->subs[index].f.subclass = AST_CONTROL_HOLD;
05562       ast_mutex_unlock(&p->lock);
05563       ast_log(LOG_DEBUG, "Sending hold on '%s'\n", ast->name);
05564       return &p->subs[index].f;
05565    }  
05566    
05567    if (p->subs[index].needunhold) {
05568       /* Send answer frame if requested */
05569       p->subs[index].needunhold = 0;
05570       p->subs[index].f.frametype = AST_FRAME_CONTROL;
05571       p->subs[index].f.subclass = AST_CONTROL_UNHOLD;
05572       ast_mutex_unlock(&p->lock);
05573       ast_log(LOG_DEBUG, "Sending unhold on '%s'\n", ast->name);
05574       return &p->subs[index].f;
05575    }  
05576    
05577    if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
05578       if (!p->subs[index].linear) {
05579          p->subs[index].linear = 1;
05580          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
05581          if (res) 
05582             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
05583       }
05584    } else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
05585          (ast->rawreadformat == AST_FORMAT_ALAW)) {
05586       if (p->subs[index].linear) {
05587          p->subs[index].linear = 0;
05588          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
05589          if (res) 
05590             ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, index);
05591       }
05592    } else {
05593       ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
05594       ast_mutex_unlock(&p->lock);
05595       return NULL;
05596    }
05597    readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
05598    CHECK_BLOCKING(ast);
05599    res = read(p->subs[index].dfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
05600    ast_clear_flag(ast, AST_FLAG_BLOCKING);
05601    /* Check for hangup */
05602    if (res < 0) {
05603       f = NULL;
05604       if (res == -1)  {
05605          if (errno == EAGAIN) {
05606             /* Return "NULL" frame if there is nobody there */
05607             ast_mutex_unlock(&p->lock);
05608             return &p->subs[index].f;
05609          } else if (errno == ELAST) {
05610             f = __dahdi_exception(ast);
05611          } else
05612             ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
05613       }
05614       ast_mutex_unlock(&p->lock);
05615       return f;
05616    }
05617    if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
05618       ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
05619       f = __dahdi_exception(ast);
05620       ast_mutex_unlock(&p->lock);
05621       return f;
05622    }
05623    if (p->tdd) { /* if in TDD mode, see if we receive that */
05624       int c;
05625 
05626       c = tdd_feed(p->tdd,readbuf,READ_SIZE);
05627       if (c < 0) {
05628          ast_log(LOG_DEBUG,"tdd_feed failed\n");
05629          ast_mutex_unlock(&p->lock);
05630          return NULL;
05631       }
05632       if (c) { /* if a char to return */
05633          p->subs[index].f.subclass = 0;
05634          p->subs[index].f.frametype = AST_FRAME_TEXT;
05635          p->subs[index].f.mallocd = 0;
05636          p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05637          p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET;
05638          p->subs[index].f.datalen = 1;
05639          *((char *) p->subs[index].f.data) = c;
05640          ast_mutex_unlock(&p->lock);
05641          return &p->subs[index].f;
05642       }
05643    }
05644    if (index == SUB_REAL) {
05645       /* Ensure the CW timers decrement only on a single subchannel */
05646       if (p->cidcwexpire) {
05647          if (!--p->cidcwexpire) {
05648             /* Expired CID/CW */
05649             if (option_verbose > 2)
05650                ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
05651             restore_conference(p);
05652          }
05653       }
05654       if (p->cid_suppress_expire) {
05655          --p->cid_suppress_expire;
05656       }
05657       if (p->callwaitingrepeat) {
05658          if (!--p->callwaitingrepeat) {
05659             /* Expired, Repeat callwaiting tone */
05660             ++p->callwaitrings;
05661             dahdi_callwait(ast);
05662          }
05663       }
05664    }
05665    if (p->subs[index].linear) {
05666       p->subs[index].f.datalen = READ_SIZE * 2;
05667    } else 
05668       p->subs[index].f.datalen = READ_SIZE;
05669 
05670    /* Handle CallerID Transmission */
05671    if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
05672       send_callerid(p);
05673    }
05674 
05675    p->subs[index].f.frametype = AST_FRAME_VOICE;
05676    p->subs[index].f.subclass = ast->rawreadformat;
05677    p->subs[index].f.samples = READ_SIZE;
05678    p->subs[index].f.mallocd = 0;
05679    p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
05680    p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[index].buffer[0]);
05681 #if 0
05682    ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->subs[index].f.datalen, ast->name);
05683 #endif   
05684    if (p->dialing || /* Transmitting something */
05685       (index && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
05686       ((index == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
05687       ) {
05688       /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
05689          don't send anything */
05690       p->subs[index].f.frametype = AST_FRAME_NULL;
05691       p->subs[index].f.subclass = 0;
05692       p->subs[index].f.samples = 0;
05693       p->subs[index].f.mallocd = 0;
05694       p->subs[index].f.offset = 0;
05695       p->subs[index].f.data = NULL;
05696       p->subs[index].f.datalen= 0;
05697    }
05698    if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
05699       /* Perform busy detection. etc on the dahdi line */
05700       f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
05701       if (f) {
05702          if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
05703             if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
05704                /* Treat this as a "hangup" instead of a "busy" on the assumption that
05705                   a busy  */
05706                f = NULL;
05707             }
05708          } else if (f->frametype == AST_FRAME_DTMF_BEGIN
05709             || f->frametype == AST_FRAME_DTMF_END) {
05710 #ifdef HAVE_PRI
05711             if (p->sig == SIG_PRI
05712                && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING
05713                && p->pri
05714                && ((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING))
05715                   || (p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
05716                /* Don't accept in-band DTMF when in overlap dial mode */
05717                ast_log(LOG_DEBUG,
05718                   "Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
05719                   f->frametype == AST_FRAME_DTMF_BEGIN ? "begin" : "end",
05720                   f->subclass, f->subclass, ast->name);
05721 
05722                f->frametype = AST_FRAME_NULL;
05723                f->subclass = 0;
05724             }
05725 #endif            
05726             /* DSP clears us of being pulse */
05727             p->pulsedial = 0;
05728          }
05729       }
05730    } else 
05731       f = &p->subs[index].f; 
05732 
05733    if (f) {
05734       switch (f->frametype) {
05735       case AST_FRAME_DTMF_BEGIN:
05736       case AST_FRAME_DTMF_END:
05737          dahdi_handle_dtmf(ast, index, &f);
05738          break;
05739       case AST_FRAME_VOICE:
05740          if (p->cidspill || p->cid_suppress_expire) {
05741             /* We are/were sending a caller id spill.  Suppress any echo. */
05742             p->subs[index].f.frametype = AST_FRAME_NULL;
05743             p->subs[index].f.subclass = 0;
05744             p->subs[index].f.samples = 0;
05745             p->subs[index].f.mallocd = 0;
05746             p->subs[index].f.offset = 0;
05747             p->subs[index].f.data = NULL;
05748             p->subs[index].f.datalen= 0;
05749          }
05750          break;
05751       default:
05752          break;
05753       }
05754    }
05755 
05756    /* If we have a fake_event, trigger exception to handle it */
05757    if (p->fake_event)
05758       ast_set_flag(ast, AST_FLAG_EXCEPTION);
05759 
05760    ast_mutex_unlock(&p->lock);
05761    return f;
05762 }
05763 
05764 static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int index, int linear)
05765 {
05766    int sent=0;
05767    int size;
05768    int res;
05769    int fd;
05770    fd = p->subs[index].dfd;
05771    while (len) {
05772       size = len;
05773       if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
05774          size = (linear ? READ_SIZE * 2 : READ_SIZE);
05775       res = write(fd, buf, size);
05776       if (res != size) {
05777          if (option_debug)
05778             ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
05779          return sent;
05780       }
05781       len -= size;
05782       buf += size;
05783    }
05784    return sent;
05785 }
05786 
05787 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
05788 {
05789    struct dahdi_pvt *p = ast->tech_pvt;
05790    int res;
05791    int index;
05792    index = dahdi_get_index(ast, p, 0);
05793    if (index < 0) {
05794       ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
05795       return -1;
05796    }
05797 
05798    /* Write a frame of (presumably voice) data */
05799    if (frame->frametype != AST_FRAME_VOICE) {
05800       if (frame->frametype != AST_FRAME_IMAGE)
05801          ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
05802       return 0;
05803    }
05804    if ((frame->subclass != AST_FORMAT_SLINEAR) && 
05805        (frame->subclass != AST_FORMAT_ULAW) &&
05806        (frame->subclass != AST_FORMAT_ALAW)) {
05807       ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
05808       return -1;
05809    }
05810    if (p->dialing) {
05811       if (option_debug)
05812          ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing on %s...\n",ast->name);
05813       return 0;
05814    }
05815    if (!p->owner) {
05816       if (option_debug)
05817          ast_log(LOG_DEBUG, "Dropping frame since there is no active owner on %s...\n",ast->name);
05818       return 0;
05819    }
05820    if (p->cidspill) {
05821       if (option_debug) {
05822          ast_log(LOG_DEBUG,
05823             "Dropping frame since I've still got a callerid spill on %s...\n",
05824             ast->name);
05825       }
05826       return 0;
05827    }
05828    /* Return if it's not valid data */
05829    if (!frame->data || !frame->datalen)
05830       return 0;
05831 
05832    if (frame->subclass == AST_FORMAT_SLINEAR) {
05833       if (!p->subs[index].linear) {
05834          p->subs[index].linear = 1;
05835          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
05836          if (res)
05837             ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
05838       }
05839       res = my_dahdi_write(p, (unsigned char *)frame->data, frame->datalen, index, 1);
05840    } else {
05841       /* x-law already */
05842       if (p->subs[index].linear) {
05843          p->subs[index].linear = 0;
05844          res = dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
05845          if (res)
05846             ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
05847       }
05848       res = my_dahdi_write(p, (unsigned char *)frame->data, frame->datalen, index, 0);
05849    }
05850    if (res < 0) {
05851       ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
05852       return -1;
05853    } 
05854    return 0;
05855 }
05856 
05857 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
05858 {
05859    struct dahdi_pvt *p = chan->tech_pvt;
05860    int res=-1;
05861    int index;
05862    int func = DAHDI_FLASH;
05863    ast_mutex_lock(&p->lock);
05864    index = dahdi_get_index(chan, p, 0);
05865    if (option_debug)
05866       ast_log(LOG_DEBUG, "Requested indication %d on channel %s\n", condition, chan->name);
05867    if (index == SUB_REAL) {
05868       switch (condition) {
05869       case AST_CONTROL_BUSY:
05870 #ifdef HAVE_PRI
05871          if (p->sig == SIG_PRI) {
05872             if (p->priindication_oob) {
05873                chan->hangupcause = AST_CAUSE_USER_BUSY;
05874                chan->_softhangup |= AST_SOFTHANGUP_DEV;
05875                res = 0;
05876                break;
05877             }
05878             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_BUSY);
05879             if (p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
05880                chan->hangupcause = AST_CAUSE_USER_BUSY;
05881                p->progress = 1;/* No need to send plain PROGRESS after this. */
05882                if (p->pri && p->pri->pri) {
05883                   if (!pri_grab(p, p->pri)) {
05884                      pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05885                      pri_rel(p->pri);
05886                   } else {
05887                      ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05888                   }
05889                }
05890             }
05891             break;
05892          }
05893 #endif
05894          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_BUSY);
05895          break;
05896       case AST_CONTROL_RINGING:
05897 #ifdef HAVE_PRI
05898          if (p->sig == SIG_PRI
05899             && p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
05900             p->call_level = DAHDI_CALL_LEVEL_ALERTING;
05901             if (p->pri && p->pri->pri) {
05902                if (!pri_grab(p, p->pri)) {
05903                   pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05904                   pri_rel(p->pri);
05905                } else {
05906                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05907                }
05908             }
05909          }
05910 #endif
05911          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_RINGTONE);
05912          if (chan->_state != AST_STATE_UP) {
05913             if ((chan->_state != AST_STATE_RING) ||
05914                ((p->sig != SIG_FXSKS) &&
05915                 (p->sig != SIG_FXSLS) &&
05916                 (p->sig != SIG_FXSGS)))
05917                ast_setstate(chan, AST_STATE_RINGING);
05918          }
05919          break;
05920       case AST_CONTROL_PROCEEDING:
05921          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
05922 #ifdef HAVE_PRI
05923          if (p->sig == SIG_PRI
05924             && p->call_level < DAHDI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
05925             p->call_level = DAHDI_CALL_LEVEL_PROCEEDING;
05926             if (p->pri && p->pri->pri) {
05927                if (!pri_grab(p, p->pri)) {
05928                   pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
05929                   pri_rel(p->pri);
05930                } else {
05931                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05932                }
05933             }
05934             p->dialing = 0;
05935          }
05936 #endif
05937          /* don't continue in ast_indicate */
05938          res = 0;
05939          break;
05940       case AST_CONTROL_PROGRESS:
05941          ast_log(LOG_DEBUG,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
05942 #ifdef HAVE_PRI
05943          p->digital = 0;   /* Digital-only calls isn't allows any inband progress messages */
05944          if (p->sig == SIG_PRI
05945             && !p->progress && p->call_level < DAHDI_CALL_LEVEL_ALERTING
05946             && !p->outgoing) {
05947             p->progress = 1;/* No need to send plain PROGRESS again. */
05948             if (p->pri && p->pri->pri) {
05949                if (!pri_grab(p, p->pri)) {
05950                   pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05951                   pri_rel(p->pri);
05952                } else {
05953                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
05954                }
05955             }
05956          }
05957 #endif
05958          /* don't continue in ast_indicate */
05959          res = 0;
05960          break;
05961       case AST_CONTROL_CONGESTION:
05962 #ifdef HAVE_PRI
05963          if (p->sig == SIG_PRI) {
05964             if (p->priindication_oob) {
05965                /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
05966                switch (chan->hangupcause) {
05967                case AST_CAUSE_USER_BUSY:
05968                case AST_CAUSE_NORMAL_CLEARING:
05969                case 0:/* Cause has not been set. */
05970                   /* Supply a more appropriate cause. */
05971                   chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05972                   break;
05973                default:
05974                   break;
05975                }
05976                chan->_softhangup |= AST_SOFTHANGUP_DEV;
05977                res = 0;
05978                break;
05979             }
05980             res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
05981             if (p->call_level < DAHDI_CALL_LEVEL_ALERTING && !p->outgoing) {
05982                /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
05983                switch (chan->hangupcause) {
05984                case AST_CAUSE_USER_BUSY:
05985                case AST_CAUSE_NORMAL_CLEARING:
05986                case 0:/* Cause has not been set. */
05987                   /* Supply a more appropriate cause. */
05988                   chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
05989                   break;
05990                default:
05991                   break;
05992                }
05993                p->progress = 1;/* No need to send plain PROGRESS after this. */
05994                if (p->pri && p->pri->pri) {
05995                   if (!pri_grab(p, p->pri)) {
05996                      pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
05997                      pri_rel(p->pri);
05998                   } else {
05999                      ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
06000                   }
06001                }
06002             }
06003             break;
06004          }
06005 #endif
06006          /* There are many cause codes that generate an AST_CONTROL_CONGESTION. */
06007          switch (chan->hangupcause) {
06008          case AST_CAUSE_USER_BUSY:
06009          case AST_CAUSE_NORMAL_CLEARING:
06010          case 0:/* Cause has not been set. */
06011             /* Supply a more appropriate cause. */
06012             chan->hangupcause = AST_CAUSE_CONGESTION;
06013             break;
06014          default:
06015             break;
06016          }
06017          res = tone_zone_play_tone(p->subs[index].dfd, DAHDI_TONE_CONGESTION);
06018          break;
06019       case AST_CONTROL_HOLD:
06020 #ifdef HAVE_PRI
06021          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06022             if (!pri_grab(p, p->pri)) {
06023                res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
06024                pri_rel(p->pri);
06025             } else
06026                   ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);       
06027          } else
06028 #endif
06029             ast_moh_start(chan, data, p->mohinterpret);
06030          break;
06031       case AST_CONTROL_UNHOLD:
06032 #ifdef HAVE_PRI
06033          if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
06034             if (!pri_grab(p, p->pri)) {
06035                res = pri_notify(p