Fix compilation warnings (found with dev-mode)
[asterisk/asterisk.git] / channels / chan_dahdi.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief DAHDI for Pseudo TDM
22  *
23  * \author Mark Spencer <markster@digium.com>
24  * 
25  * Connects to the DAHDI telephony library as well as 
26  * libpri. Libpri is optional and needed only if you are
27  * going to use ISDN connections.
28  *
29  * You need to install libraries before you attempt to compile
30  * and install the DAHDI channel.
31  *
32  * \par See also
33  * \arg \ref Config_dahdi
34  *
35  * \ingroup channel_drivers
36  *
37  * \todo Deprecate the "musiconhold" configuration option post 1.4
38  */
39
40 /*** MODULEINFO
41         <depend>res_smdi</depend>
42         <depend>dahdi</depend>
43         <depend>tonezone</depend>
44         <use>pri</use>
45         <use>ss7</use>
46  ***/
47
48 #include "asterisk.h"
49
50 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
51
52 #ifdef __NetBSD__
53 #include <pthread.h>
54 #include <signal.h>
55 #else
56 #include <sys/signal.h>
57 #endif
58 #include <sys/ioctl.h>
59 #include <math.h>
60 #include <ctype.h>
61
62 #include <dahdi/user.h>
63 #include <dahdi/tonezone.h>
64
65 #ifdef HAVE_PRI
66 #include <libpri.h>
67 #endif
68
69 #ifdef HAVE_SS7
70 #include <libss7.h>
71 #endif
72
73 #include "asterisk/lock.h"
74 #include "asterisk/channel.h"
75 #include "asterisk/config.h"
76 #include "asterisk/module.h"
77 #include "asterisk/pbx.h"
78 #include "asterisk/file.h"
79 #include "asterisk/ulaw.h"
80 #include "asterisk/alaw.h"
81 #include "asterisk/callerid.h"
82 #include "asterisk/adsi.h"
83 #include "asterisk/cli.h"
84 #include "asterisk/cdr.h"
85 #include "asterisk/features.h"
86 #include "asterisk/musiconhold.h"
87 #include "asterisk/say.h"
88 #include "asterisk/tdd.h"
89 #include "asterisk/app.h"
90 #include "asterisk/dsp.h"
91 #include "asterisk/astdb.h"
92 #include "asterisk/manager.h"
93 #include "asterisk/causes.h"
94 #include "asterisk/term.h"
95 #include "asterisk/utils.h"
96 #include "asterisk/transcap.h"
97 #include "asterisk/stringfields.h"
98 #include "asterisk/abstract_jb.h"
99 #include "asterisk/smdi.h"
100 #include "asterisk/astobj.h"
101 #include "asterisk/event.h"
102 #include "asterisk/devicestate.h"
103
104 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
105
106 static const char *lbostr[] = {
107 "0 db (CSU)/0-133 feet (DSX-1)",
108 "133-266 feet (DSX-1)",
109 "266-399 feet (DSX-1)",
110 "399-533 feet (DSX-1)",
111 "533-655 feet (DSX-1)",
112 "-7.5db (CSU)",
113 "-15db (CSU)",
114 "-22.5db (CSU)"
115 };
116
117 /*! Global jitterbuffer configuration - by default, jb is disabled */
118 static struct ast_jb_conf default_jbconf =
119 {
120         .flags = 0,
121         .max_size = -1,
122         .resync_threshold = -1,
123         .impl = ""
124 };
125 static struct ast_jb_conf global_jbconf;
126
127 /* define this to send PRI user-user information elements */
128 #undef SUPPORT_USERUSER
129
130 /*! 
131  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
132  * the user hangs up to reset the state machine so ring works properly.
133  * This is used to be able to support kewlstart by putting the zhone in
134  * groundstart mode since their forward disconnect supervision is entirely
135  * broken even though their documentation says it isn't and their support
136  * is entirely unwilling to provide any assistance with their channel banks
137  * even though their web site says they support their products for life.
138  */
139 /* #define ZHONE_HACK */
140
141 /*! \note
142  * Define if you want to check the hook state for an FXO (FXS signalled) interface
143  * before dialing on it.  Certain FXO interfaces always think they're out of
144  * service with this method however.
145  */
146 /* #define DAHDI_CHECK_HOOKSTATE */
147
148 /*! \brief Typically, how many rings before we should send Caller*ID */
149 #define DEFAULT_CIDRINGS 1
150
151 #define CHANNEL_PSEUDO -12
152
153 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
154
155
156 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
157 #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)) 
158
159 static const char tdesc[] = "DAHDI Telephony Driver"
160 #ifdef HAVE_PRI
161                " w/PRI"
162 #endif
163 #ifdef HAVE_SS7
164                " w/SS7"
165 #endif
166 ;
167
168 static const char config[] = "chan_dahdi.conf";
169
170 #define SIG_EM          DAHDI_SIG_EM
171 #define SIG_EMWINK      (0x0100000 | DAHDI_SIG_EM)
172 #define SIG_FEATD       (0x0200000 | DAHDI_SIG_EM)
173 #define SIG_FEATDMF     (0x0400000 | DAHDI_SIG_EM)
174 #define SIG_FEATB       (0x0800000 | DAHDI_SIG_EM)
175 #define SIG_E911        (0x1000000 | DAHDI_SIG_EM)
176 #define SIG_FEATDMF_TA  (0x2000000 | DAHDI_SIG_EM)
177 #define SIG_FGC_CAMA    (0x4000000 | DAHDI_SIG_EM)
178 #define SIG_FGC_CAMAMF  (0x8000000 | DAHDI_SIG_EM)
179 #define SIG_FXSLS       DAHDI_SIG_FXSLS
180 #define SIG_FXSGS       DAHDI_SIG_FXSGS
181 #define SIG_FXSKS       DAHDI_SIG_FXSKS
182 #define SIG_FXOLS       DAHDI_SIG_FXOLS
183 #define SIG_FXOGS       DAHDI_SIG_FXOGS
184 #define SIG_FXOKS       DAHDI_SIG_FXOKS
185 #define SIG_PRI         DAHDI_SIG_CLEAR
186 #define SIG_BRI         (0x2000000 | DAHDI_SIG_CLEAR)
187 #define SIG_BRI_PTMP    (0X4000000 | DAHDI_SIG_CLEAR)
188 #define SIG_SS7         (0x1000000 | DAHDI_SIG_CLEAR)
189 #define SIG_SF          DAHDI_SIG_SF
190 #define SIG_SFWINK      (0x0100000 | DAHDI_SIG_SF)
191 #define SIG_SF_FEATD    (0x0200000 | DAHDI_SIG_SF)
192 #define SIG_SF_FEATDMF  (0x0400000 | DAHDI_SIG_SF)
193 #define SIG_SF_FEATB    (0x0800000 | DAHDI_SIG_SF)
194 #define SIG_EM_E1       DAHDI_SIG_EM_E1
195 #define SIG_GR303FXOKS  (0x0100000 | DAHDI_SIG_FXOKS)
196 #define SIG_GR303FXSKS  (0x0100000 | DAHDI_SIG_FXSKS)
197
198 #ifdef LOTS_OF_SPANS
199 #define NUM_SPANS       DAHDI_MAX_SPANS
200 #else
201 #define NUM_SPANS               32
202 #endif
203 #define NUM_DCHANS              4       /*!< No more than 4 d-channels */
204 #define MAX_CHANNELS    672             /*!< No more than a DS3 per trunk group */
205
206 #define CHAN_PSEUDO     -2
207
208 #define DCHAN_PROVISIONED (1 << 0)
209 #define DCHAN_NOTINALARM  (1 << 1)
210 #define DCHAN_UP          (1 << 2)
211
212 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
213
214 /* Overlap dialing option types */
215 #define DAHDI_OVERLAPDIAL_NONE 0
216 #define DAHDI_OVERLAPDIAL_OUTGOING 1
217 #define DAHDI_OVERLAPDIAL_INCOMING 2
218 #define DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
219
220
221 #define CALLPROGRESS_PROGRESS           1
222 #define CALLPROGRESS_FAX_OUTGOING       2
223 #define CALLPROGRESS_FAX_INCOMING       4
224 #define CALLPROGRESS_FAX                (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
225
226 static char defaultcic[64] = "";
227 static char defaultozz[64] = "";
228
229 static char parkinglot[AST_MAX_EXTENSION] = "";         /*!< Default parking lot for this channel */
230
231 /*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
232 static char mwimonitornotify[PATH_MAX] = "";
233 static int  mwisend_rpas = 0;
234
235 static char progzone[10] = "";
236
237 static int usedistinctiveringdetection = 0;
238 static int distinctiveringaftercid = 0;
239
240 static int numbufs = 4;
241
242 static int mwilevel = 512;
243
244 #ifdef HAVE_PRI
245 static struct ast_channel inuse;
246 #ifdef PRI_GETSET_TIMERS
247 static int pritimers[PRI_MAX_TIMERS];
248 #endif
249 static int pridebugfd = -1;
250 static char pridebugfilename[1024] = "";
251 #endif
252
253 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
254 static int firstdigittimeout = 16000;
255
256 /*! \brief How long to wait for following digits (FXO logic) */
257 static int gendigittimeout = 8000;
258
259 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
260 static int matchdigittimeout = 3000;
261
262 /*! \brief Protect the interface list (of dahdi_pvt's) */
263 AST_MUTEX_DEFINE_STATIC(iflock);
264
265
266 static int ifcount = 0;
267
268 #ifdef HAVE_PRI
269 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
270 #endif
271
272 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
273    when it's doing something critical. */
274 AST_MUTEX_DEFINE_STATIC(monlock);
275
276 /*! \brief This is the thread for the monitor which checks for input on the channels
277    which are not currently in use. */
278 static pthread_t monitor_thread = AST_PTHREADT_NULL;
279 static ast_cond_t mwi_thread_complete;
280 static ast_cond_t ss_thread_complete;
281 AST_MUTEX_DEFINE_STATIC(mwi_thread_lock);
282 AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
283 AST_MUTEX_DEFINE_STATIC(restart_lock);
284 static int mwi_thread_count = 0;
285 static int ss_thread_count = 0;
286 static int num_restart_pending = 0;
287
288 static int restart_monitor(void);
289
290 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);
291
292 static int dahdi_sendtext(struct ast_channel *c, const char *text);
293
294 static void mwi_event_cb(const struct ast_event *event, void *userdata)
295 {
296         /* This module does not handle MWI in an event-based manner.  However, it
297          * subscribes to MWI for each mailbox that is configured so that the core
298          * knows that we care about it.  Then, chan_dahdi will get the MWI from the
299          * event cache instead of checking the mailbox directly. */
300 }
301
302 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
303 static inline int dahdi_get_event(int fd)
304 {
305         int j;
306         if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
307                 return -1;
308         return j;
309 }
310
311 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
312 static inline int dahdi_wait_event(int fd)
313 {
314         int i, j = 0;
315         i = DAHDI_IOMUX_SIGEVENT;
316         if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
317                 return -1;
318         if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
319                 return -1;
320         return j;
321 }
322
323 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
324 #define READ_SIZE 160
325
326 #define MASK_AVAIL              (1 << 0)        /*!< Channel available for PRI use */
327 #define MASK_INUSE              (1 << 1)        /*!< Channel currently in use */
328
329 #define CALLWAITING_SILENT_SAMPLES      ( (300 * 8) / READ_SIZE) /*!< 300 ms */
330 #define CALLWAITING_REPEAT_SAMPLES      ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
331 #define CIDCW_EXPIRE_SAMPLES            ( (500 * 8) / READ_SIZE) /*!< 500 ms */
332 #define MIN_MS_SINCE_FLASH                      ( (2000) )      /*!< 2000 ms */
333 #define DEFAULT_RINGT                           ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
334
335 struct dahdi_pvt;
336
337 static int ringt_base = DEFAULT_RINGT;
338
339 #ifdef HAVE_SS7
340
341 #define LINKSTATE_INALARM       (1 << 0)
342 #define LINKSTATE_STARTING      (1 << 1)
343 #define LINKSTATE_UP            (1 << 2)
344 #define LINKSTATE_DOWN          (1 << 3)
345
346 #define SS7_NAI_DYNAMIC         -1
347
348 #define LINKSET_FLAG_EXPLICITACM (1 << 0)
349
350 struct dahdi_ss7 {
351         pthread_t master;                                               /*!< Thread of master */
352         ast_mutex_t lock;
353         int fds[NUM_DCHANS];
354         int numsigchans;
355         int linkstate[NUM_DCHANS];
356         int numchans;
357         int type;
358         enum {
359                 LINKSET_STATE_DOWN = 0,
360                 LINKSET_STATE_UP
361         } state;
362         char called_nai;                                                /*!< Called Nature of Address Indicator */
363         char calling_nai;                                               /*!< Calling Nature of Address Indicator */
364         char internationalprefix[10];                                   /*!< country access code ('00' for european dialplans) */
365         char nationalprefix[10];                                        /*!< area access code ('0' for european dialplans) */
366         char subscriberprefix[20];                                      /*!< area access code + area code ('0'+area code for european dialplans) */
367         char unknownprefix[20];                                         /*!< for unknown dialplans */
368         struct ss7 *ss7;
369         struct dahdi_pvt *pvts[MAX_CHANNELS];                           /*!< Member channel pvt structs */
370         int flags;                                                      /*!< Linkset flags */
371 };
372
373 static struct dahdi_ss7 linksets[NUM_SPANS];
374
375 static int cur_ss7type = -1;
376 static int cur_linkset = -1;
377 static int cur_pointcode = -1;
378 static int cur_cicbeginswith = -1;
379 static int cur_adjpointcode = -1;
380 static int cur_networkindicator = -1;
381 static int cur_defaultdpc = -1;
382 #endif /* HAVE_SS7 */
383
384 #ifdef HAVE_PRI
385
386 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
387 #define PRI_CHANNEL(p) ((p) & 0xff)
388 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
389 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
390
391 struct dahdi_pri {
392         pthread_t master;                                               /*!< Thread of master */
393         ast_mutex_t lock;                                               /*!< Mutex */
394         char idleext[AST_MAX_EXTENSION];                                /*!< Where to idle extra calls */
395         char idlecontext[AST_MAX_CONTEXT];                              /*!< What context to use for idle */
396         char idledial[AST_MAX_EXTENSION];                               /*!< What to dial before dumping */
397         int minunused;                                                  /*!< Min # of channels to keep empty */
398         int minidle;                                                    /*!< Min # of "idling" calls to keep active */
399         int nodetype;                                                   /*!< Node type */
400         int switchtype;                                                 /*!< Type of switch to emulate */
401         int nsf;                                                        /*!< Network-Specific Facilities */
402         int dialplan;                                                   /*!< Dialing plan */
403         int localdialplan;                                              /*!< Local dialing plan */
404         char internationalprefix[10];                                   /*!< country access code ('00' for european dialplans) */
405         char nationalprefix[10];                                        /*!< area access code ('0' for european dialplans) */
406         char localprefix[20];                                           /*!< area access code + area code ('0'+area code for european dialplans) */
407         char privateprefix[20];                                         /*!< for private dialplans */
408         char unknownprefix[20];                                         /*!< for unknown dialplans */
409         int dchannels[NUM_DCHANS];                                      /*!< What channel are the dchannels on */
410         int trunkgroup;                                                 /*!< What our trunkgroup is */
411         int mastertrunkgroup;                                           /*!< What trunk group is our master */
412         int prilogicalspan;                                             /*!< Logical span number within trunk group */
413         int numchans;                                                   /*!< Num of channels we represent */
414         int overlapdial;                                                /*!< In overlap dialing mode */
415         int facilityenable;                                             /*!< Enable facility IEs */
416         struct pri *dchans[NUM_DCHANS];                                 /*!< Actual d-channels */
417         int dchanavail[NUM_DCHANS];                                     /*!< Whether each channel is available */
418         struct pri *pri;                                                /*!< Currently active D-channel */
419         int debug;
420         int fds[NUM_DCHANS];                                            /*!< FD's for d-channels */
421         int offset;
422         int span;
423         int resetting;
424         int resetpos;
425 #ifdef HAVE_PRI_INBANDDISCONNECT
426         unsigned int inbanddisconnect:1;                                /*!< Should we support inband audio after receiving DISCONNECT? */
427 #endif
428         time_t lastreset;                                               /*!< time when unused channels were last reset */
429         long resetinterval;                                             /*!< Interval (in seconds) for resetting unused channels */
430         int sig;
431         struct dahdi_pvt *pvts[MAX_CHANNELS];                           /*!< Member channel pvt structs */
432         struct dahdi_pvt *crvs;                                         /*!< Member CRV structs */
433         struct dahdi_pvt *crvend;                                               /*!< Pointer to end of CRV structs */
434 };
435
436
437 static struct dahdi_pri pris[NUM_SPANS];
438
439 #if 0
440 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
441 #else
442 #define DEFAULT_PRI_DEBUG 0
443 #endif
444
445 static inline void pri_rel(struct dahdi_pri *pri)
446 {
447         ast_mutex_unlock(&pri->lock);
448 }
449
450 #else
451 /*! Shut up the compiler */
452 struct dahdi_pri;
453 #endif
454
455 #define SUB_REAL        0                       /*!< Active call */
456 #define SUB_CALLWAIT    1                       /*!< Call-Waiting call on hold */
457 #define SUB_THREEWAY    2                       /*!< Three-way call */
458
459 /* Polarity states */
460 #define POLARITY_IDLE   0
461 #define POLARITY_REV    1
462
463
464 struct distRingData {
465         int ring[3];
466         int range;
467 };
468 struct ringContextData {
469         char contextData[AST_MAX_CONTEXT];
470 };
471 struct dahdi_distRings {
472         struct distRingData ringnum[3];
473         struct ringContextData ringContext[3];
474 };
475
476 static char *subnames[] = {
477         "Real",
478         "Callwait",
479         "Threeway"
480 };
481
482 struct dahdi_subchannel {
483         int dfd;
484         struct ast_channel *owner;
485         int chan;
486         short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
487         struct ast_frame f;             /*!< One frame for each channel.  How did this ever work before? */
488         unsigned int needringing:1;
489         unsigned int needbusy:1;
490         unsigned int needcongestion:1;
491         unsigned int needcallerid:1;
492         unsigned int needanswer:1;
493         unsigned int needflash:1;
494         unsigned int needhold:1;
495         unsigned int needunhold:1;
496         unsigned int linear:1;
497         unsigned int inthreeway:1;
498         struct dahdi_confinfo curconf;
499 };
500
501 #define CONF_USER_REAL          (1 << 0)
502 #define CONF_USER_THIRDCALL     (1 << 1)
503
504 #define MAX_SLAVES      4
505
506 static struct dahdi_pvt {
507         ast_mutex_t lock;
508         struct ast_channel *owner;                      /*!< Our current active owner (if applicable) */
509                                                         /*!< Up to three channels can be associated with this call */
510                 
511         struct dahdi_subchannel sub_unused;             /*!< Just a safety precaution */
512         struct dahdi_subchannel subs[3];                        /*!< Sub-channels */
513         struct dahdi_confinfo saveconf;                 /*!< Saved conference info */
514
515         struct dahdi_pvt *slaves[MAX_SLAVES];           /*!< Slave to us (follows our conferencing) */
516         struct dahdi_pvt *master;                               /*!< Master to us (we follow their conferencing) */
517         int inconference;                               /*!< If our real should be in the conference */
518         
519         int buf_no;                                     /*!< Number of buffers */
520         int buf_policy;                         /*!< Buffer policy */
521         int sig;                                        /*!< Signalling style */
522         int radio;                                      /*!< radio type */
523         int outsigmod;                                  /*!< Outbound Signalling style (modifier) */
524         int oprmode;                                    /*!< "Operator Services" mode */
525         struct dahdi_pvt *oprpeer;                              /*!< "Operator Services" peer tech_pvt ptr */
526         float cid_rxgain;                                       /*!< "Gain to apply during caller id */
527         float rxgain;
528         float txgain;
529         int tonezone;                                   /*!< tone zone for this chan, or -1 for default */
530         struct dahdi_pvt *next;                         /*!< Next channel in list */
531         struct dahdi_pvt *prev;                         /*!< Prev channel in list */
532
533         /* flags */
534         unsigned int adsi:1;
535         unsigned int answeronpolarityswitch:1;
536         unsigned int busydetect:1;
537         unsigned int callreturn:1;
538         unsigned int callwaiting:1;
539         unsigned int callwaitingcallerid:1;
540         unsigned int cancallforward:1;
541         unsigned int canpark:1;
542         unsigned int confirmanswer:1;                   /*!< Wait for '#' to confirm answer */
543         unsigned int destroy:1;
544         unsigned int didtdd:1;                          /*!< flag to say its done it once */
545         unsigned int dialednone:1;
546         unsigned int dialing:1;
547         unsigned int digital:1;
548         unsigned int dnd:1;
549         unsigned int echobreak:1;
550         unsigned int echocanbridged:1;
551         unsigned int echocanon:1;
552         unsigned int faxhandled:1;                      /*!< Has a fax tone already been handled? */
553         unsigned int firstradio:1;
554         unsigned int hanguponpolarityswitch:1;
555         unsigned int hardwaredtmf:1;
556         unsigned int hidecallerid:1;
557         unsigned int hidecalleridname:1;      /*!< Hide just the name not the number for legacy PBX use */
558         unsigned int ignoredtmf:1;
559         unsigned int immediate:1;                       /*!< Answer before getting digits? */
560         unsigned int inalarm:1;
561         unsigned int mate:1;                            /*!< flag to say its in MATE mode */
562         unsigned int outgoing:1;
563         /* unsigned int overlapdial:1;                  unused and potentially confusing */
564         unsigned int permcallwaiting:1;
565         unsigned int permhidecallerid:1;                /*!< Whether to hide our outgoing caller ID or not */
566         unsigned int priindication_oob:1;
567         unsigned int priexclusive:1;
568         unsigned int pulse:1;
569         unsigned int pulsedial:1;                       /*!< whether a pulse dial phone is detected */
570         unsigned int restartpending:1;          /*!< flag to ensure counted only once for restart */
571         unsigned int restrictcid:1;                     /*!< Whether restrict the callerid -> only send ANI */
572         unsigned int threewaycalling:1;
573         unsigned int transfer:1;
574         unsigned int use_callerid:1;                    /*!< Whether or not to use caller id on this channel */
575         unsigned int use_callingpres:1;                 /*!< Whether to use the callingpres the calling switch sends */
576         unsigned int usedistinctiveringdetection:1;
577         unsigned int dahditrcallerid:1;                 /*!< should we use the callerid from incoming call on dahdi transfer or not */
578         unsigned int transfertobusy:1;                  /*!< allow flash-transfers to busy channels */
579         unsigned int mwimonitor_neon:1;                 /*!< monitor this FXO port for neon type MWI indication from other end */
580         unsigned int mwimonitor_fsk:1;                  /*!< monitor this FXO port for fsk MWI indication from other end */
581         unsigned int mwimonitoractive:1;                /*!< an MWI monitor thread is currently active */
582         unsigned int mwisendactive:1;                   /*!< a MWI message sending thread is active */
583         /* Channel state or unavilability flags */
584         unsigned int inservice:1;
585         unsigned int locallyblocked:1;
586         unsigned int remotelyblocked:1;
587 #if defined(HAVE_PRI) || defined(HAVE_SS7)
588         unsigned int rlt:1;     
589         unsigned int alerting:1;
590         unsigned int alreadyhungup:1;
591         unsigned int isidlecall:1;
592         unsigned int proceeding:1;
593         unsigned int progress:1;
594         unsigned int resetting:1;
595         unsigned int setup_ack:1;
596 #endif
597         unsigned int use_smdi:1;                /* Whether to use SMDI on this channel */
598         struct ast_smdi_interface *smdi_iface;  /* The serial port to listen for SMDI data on */
599
600         struct dahdi_distRings drings;
601
602         char context[AST_MAX_CONTEXT];
603         char defcontext[AST_MAX_CONTEXT];
604         char exten[AST_MAX_EXTENSION];
605         char language[MAX_LANGUAGE];
606         char mohinterpret[MAX_MUSICCLASS];
607         char mohsuggest[MAX_MUSICCLASS];
608         char parkinglot[AST_MAX_EXTENSION]; /*!< Parking lot for this channel */
609 #if defined(PRI_ANI) || defined(HAVE_SS7)
610         char cid_ani[AST_MAX_EXTENSION];
611 #endif
612         int cid_ani2;
613         char cid_num[AST_MAX_EXTENSION];
614         int cid_ton;                                    /*!< Type Of Number (TON) */
615         char cid_name[AST_MAX_EXTENSION];
616         char lastcid_num[AST_MAX_EXTENSION];
617         char lastcid_name[AST_MAX_EXTENSION];
618         char *origcid_num;                              /*!< malloced original callerid */
619         char *origcid_name;                             /*!< malloced original callerid */
620         char callwait_num[AST_MAX_EXTENSION];
621         char callwait_name[AST_MAX_EXTENSION];
622         char rdnis[AST_MAX_EXTENSION];
623         char dnid[AST_MAX_EXTENSION];
624         ast_group_t group;
625         int law;
626         int confno;                                     /*!< Our conference */
627         int confusers;                                  /*!< Who is using our conference */
628         int propconfno;                                 /*!< Propagated conference number */
629         ast_group_t callgroup;
630         ast_group_t pickupgroup;
631         struct ast_variable *vars;
632         int channel;                                    /*!< Channel Number or CRV */
633         int span;                                       /*!< Span number */
634         time_t guardtime;                               /*!< Must wait this much time before using for new call */
635         int cid_signalling;                             /*!< CID signalling type bell202 or v23 */
636         int cid_start;                                  /*!< CID start indicator, polarity or ring */
637         int callingpres;                                /*!< The value of callling presentation that we're going to use when placing a PRI call */
638         int callwaitingrepeat;                          /*!< How many samples to wait before repeating call waiting */
639         int cidcwexpire;                                /*!< When to expire our muting for CID/CW */
640         unsigned char *cidspill;
641         int cidpos;
642         int cidlen;
643         int ringt;
644         int ringt_base;
645         int stripmsd;
646         int callwaitcas;
647         int callwaitrings;
648         struct {
649                 struct dahdi_echocanparams head;
650                 struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS];
651         } echocancel;
652         int echotraining;
653         char echorest[20];
654         int busycount;
655         int busy_tonelength;
656         int busy_quietlength;
657         int callprogress;
658         struct timeval flashtime;                       /*!< Last flash-hook time */
659         struct ast_dsp *dsp;
660         int cref;                                       /*!< Call reference number */
661         struct dahdi_dialoperation dop;
662         int whichwink;                                  /*!< SIG_FEATDMF_TA Which wink are we on? */
663         char finaldial[64];
664         char accountcode[AST_MAX_ACCOUNT_CODE];         /*!< Account code */
665         int amaflags;                                   /*!< AMA Flags */
666         struct tdd_state *tdd;                          /*!< TDD flag */
667         char call_forward[AST_MAX_EXTENSION];
668         char mailbox[AST_MAX_EXTENSION];
669         struct ast_event_sub *mwi_event_sub;
670         char dialdest[256];
671         int onhooktime;
672         int msgstate;
673         int distinctivering;                            /*!< Which distinctivering to use */
674         int cidrings;                                   /*!< Which ring to deliver CID on */
675         int dtmfrelax;                                  /*!< whether to run in relaxed DTMF mode */
676         int fake_event;
677         int polarityonanswerdelay;
678         struct timeval polaritydelaytv;
679         int sendcalleridafter;
680 #ifdef HAVE_PRI
681         struct dahdi_pri *pri;
682         struct dahdi_pvt *bearer;
683         struct dahdi_pvt *realcall;
684         q931_call *call;
685         int prioffset;
686         int logicalspan;
687 #endif  
688         int polarity;
689         int dsp_features;
690 #ifdef HAVE_SS7
691         struct dahdi_ss7 *ss7;
692         struct isup_call *ss7call;
693         char charge_number[50];
694         char gen_add_number[50];
695         char gen_dig_number[50];
696         char orig_called_num[50];
697         char redirecting_num[50];
698         char generic_name[50];
699         unsigned char gen_add_num_plan;
700         unsigned char gen_add_nai;
701         unsigned char gen_add_pres_ind;
702         unsigned char gen_add_type;
703         unsigned char gen_dig_type;
704         unsigned char gen_dig_scheme;
705         char jip_number[50];
706         unsigned char lspi_type;
707         unsigned char lspi_scheme;
708         unsigned char lspi_context;
709         char lspi_ident[50];
710         unsigned int call_ref_ident;
711         unsigned int call_ref_pc;
712         unsigned char calling_party_cat;
713         int transcap;
714         int cic;                                                        /*!< CIC associated with channel */
715         unsigned int dpc;                                               /*!< CIC's DPC */
716         unsigned int loopedback:1;
717 #endif
718         char begindigit;
719         int muting;
720 } *iflist = NULL, *ifend = NULL;
721
722 /*! \brief Channel configuration from chan_dahdi.conf .
723  * This struct is used for parsing the [channels] section of chan_dahdi.conf.
724  * Generally there is a field here for every possible configuration item.
725  *
726  * The state of fields is saved along the parsing and whenever a 'channel'
727  * statement is reached, the current dahdi_chan_conf is used to configure the 
728  * channel (struct dahdi_pvt)
729  *
730  * \see dahdi_chan_init for the default values.
731  */
732 struct dahdi_chan_conf {
733         struct dahdi_pvt chan;
734 #ifdef HAVE_PRI
735         struct dahdi_pri pri;
736 #endif
737
738 #ifdef HAVE_SS7
739         struct dahdi_ss7 ss7;
740 #endif
741         struct dahdi_params timing;
742         int is_sig_auto; /*!< Use channel signalling from DAHDI? */
743
744         char smdi_port[SMDI_MAX_FILENAME_LEN];
745 };
746
747 /*! returns a new dahdi_chan_conf with default values (by-value) */
748 static struct dahdi_chan_conf dahdi_chan_conf_default(void) {
749         /* recall that if a field is not included here it is initialized
750          * to 0 or equivalent
751          */
752         struct dahdi_chan_conf conf = {
753 #ifdef HAVE_PRI
754                 .pri = {
755                         .nsf = PRI_NSF_NONE,
756                         .switchtype = PRI_SWITCH_NI2,
757                         .dialplan = PRI_UNKNOWN + 1,
758                         .localdialplan = PRI_NATIONAL_ISDN + 1,
759                         .nodetype = PRI_CPE,
760
761                         .minunused = 2,
762                         .idleext = "",
763                         .idledial = "",
764                         .internationalprefix = "",
765                         .nationalprefix = "",
766                         .localprefix = "",
767                         .privateprefix = "",
768                         .unknownprefix = "",
769                         .resetinterval = -1,
770                 },
771 #endif
772 #ifdef HAVE_SS7
773                 .ss7 = {
774                         .called_nai = SS7_NAI_NATIONAL,
775                         .calling_nai = SS7_NAI_NATIONAL,
776                         .internationalprefix = "",
777                         .nationalprefix = "",
778                         .subscriberprefix = "",
779                         .unknownprefix = ""
780                 },
781 #endif
782                 .chan = {
783                         .context = "default",
784                         .cid_num = "",
785                         .cid_name = "",
786                         .mohinterpret = "default",
787                         .mohsuggest = "",
788                         .parkinglot = "",
789                         .transfertobusy = 1,
790
791                         .cid_signalling = CID_SIG_BELL,
792                         .cid_start = CID_START_RING,
793                         .dahditrcallerid = 0,
794                         .use_callerid = 1,
795                         .sig = -1,
796                         .outsigmod = -1,
797
798                         .cid_rxgain = +5.0,
799
800                         .tonezone = -1,
801
802                         .echocancel.head.tap_length = 1,
803
804                         .busycount = 3,
805
806                         .accountcode = "",
807
808                         .mailbox = "",
809
810
811                         .polarityonanswerdelay = 600,
812
813                         .sendcalleridafter = DEFAULT_CIDRINGS,
814                 
815                         .buf_policy = DAHDI_POLICY_IMMEDIATE,
816                         .buf_no = numbufs
817                 },
818                 .timing = {
819                         .prewinktime = -1,
820                         .preflashtime = -1,
821                         .winktime = -1,
822                         .flashtime = -1,
823                         .starttime = -1,
824                         .rxwinktime = -1,
825                         .rxflashtime = -1,
826                         .debouncetime = -1
827                 },
828                 .is_sig_auto = 1,
829                 .smdi_port = "/dev/ttyS0",
830         };
831
832         return conf;
833 }
834
835
836 static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
837 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
838 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
839 static int dahdi_sendtext(struct ast_channel *c, const char *text);
840 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
841 static int dahdi_hangup(struct ast_channel *ast);
842 static int dahdi_answer(struct ast_channel *ast);
843 static struct ast_frame *dahdi_read(struct ast_channel *ast);
844 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
845 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
846 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
847 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
848 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
849 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
850 static int handle_init_event(struct dahdi_pvt *i, int event);
851
852 static const struct ast_channel_tech dahdi_tech = {
853         .type = "DAHDI",
854         .description = tdesc,
855         .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
856         .requester = dahdi_request,
857         .send_digit_begin = dahdi_digit_begin,
858         .send_digit_end = dahdi_digit_end,
859         .send_text = dahdi_sendtext,
860         .call = dahdi_call,
861         .hangup = dahdi_hangup,
862         .answer = dahdi_answer,
863         .read = dahdi_read,
864         .write = dahdi_write,
865         .bridge = dahdi_bridge,
866         .exception = dahdi_exception,
867         .indicate = dahdi_indicate,
868         .fixup = dahdi_fixup,
869         .setoption = dahdi_setoption,
870         .func_channel_read = dahdi_func_read,
871 };
872
873 #ifdef HAVE_PRI
874 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
875 #else
876 #define GET_CHANNEL(p) ((p)->channel)
877 #endif
878
879 struct dahdi_pvt *round_robin[32];
880
881 #ifdef HAVE_PRI
882 static inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri)
883 {
884         int res;
885         /* Grab the lock first */
886         do {
887                 res = ast_mutex_trylock(&pri->lock);
888                 if (res) {
889                         DEADLOCK_AVOIDANCE(&pvt->lock);
890                 }
891         } while (res);
892         /* Then break the poll */
893         if (pri->master != AST_PTHREADT_NULL)
894                 pthread_kill(pri->master, SIGURG);
895         return 0;
896 }
897 #endif
898
899 #ifdef HAVE_SS7
900 static inline void ss7_rel(struct dahdi_ss7 *ss7)
901 {
902         ast_mutex_unlock(&ss7->lock);
903 }
904
905 static inline int ss7_grab(struct dahdi_pvt *pvt, struct dahdi_ss7 *pri)
906 {
907         int res;
908         /* Grab the lock first */
909         do {
910                 res = ast_mutex_trylock(&pri->lock);
911                 if (res) {
912                         DEADLOCK_AVOIDANCE(&pvt->lock);
913                 }
914         } while (res);
915         /* Then break the poll */
916         if (pri->master != AST_PTHREADT_NULL)
917                 pthread_kill(pri->master, SIGURG);
918         return 0;
919 }
920 #endif
921 #define NUM_CADENCE_MAX 25
922 static int num_cadence = 4;
923 static int user_has_defined_cadences = 0;
924
925 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
926         { { 125, 125, 2000, 4000 } },                   /*!< Quick chirp followed by normal ring */
927         { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
928         { { 125, 125, 125, 125, 125, 4000 } },  /*!< Three short bursts */
929         { { 1000, 500, 2500, 5000 } },  /*!< Long ring */
930 };
931
932 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
933  * is 1, the second pause is 2 and so on.
934  */
935
936 static int cidrings[NUM_CADENCE_MAX] = {
937         2,                                                                              /*!< Right after first long ring */
938         4,                                                                              /*!< Right after long part */
939         3,                                                                              /*!< After third chirp */
940         2,                                                                              /*!< Second spell */
941 };
942
943 /* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
944 static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
945
946 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
947                         (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
948
949 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
950 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
951
952 static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok)
953 {
954         int res;
955         if (p->subs[SUB_REAL].owner == ast)
956                 res = 0;
957         else if (p->subs[SUB_CALLWAIT].owner == ast)
958                 res = 1;
959         else if (p->subs[SUB_THREEWAY].owner == ast)
960                 res = 2;
961         else {
962                 res = -1;
963                 if (!nullok)
964                         ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
965         }
966         return res;
967 }
968
969 #ifdef HAVE_PRI
970 static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri)
971 #else
972 static void wakeup_sub(struct dahdi_pvt *p, int a, void *pri)
973 #endif
974 {
975 #ifdef HAVE_PRI
976         if (pri)
977                 ast_mutex_unlock(&pri->lock);
978 #endif                  
979         for (;;) {
980                 if (p->subs[a].owner) {
981                         if (ast_channel_trylock(p->subs[a].owner)) {
982                                 DEADLOCK_AVOIDANCE(&p->lock);
983                         } else {
984                                 ast_queue_frame(p->subs[a].owner, &ast_null_frame);
985                                 ast_channel_unlock(p->subs[a].owner);
986                                 break;
987                         }
988                 } else
989                         break;
990         }
991 #ifdef HAVE_PRI
992         if (pri)
993                 ast_mutex_lock(&pri->lock);
994 #endif                  
995 }
996
997 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *data)
998 {
999 #ifdef HAVE_PRI
1000         struct dahdi_pri *pri = (struct dahdi_pri*) data;
1001 #endif
1002 #ifdef HAVE_SS7
1003         struct dahdi_ss7 *ss7 = (struct dahdi_ss7*) data;
1004 #endif
1005         /* We must unlock the PRI to avoid the possibility of a deadlock */
1006 #if defined(HAVE_PRI) || defined(HAVE_SS7)
1007         if (data) {
1008                 switch (p->sig) {
1009 #ifdef HAVE_PRI
1010                 case SIG_BRI:
1011                 case SIG_BRI_PTMP:
1012                 case SIG_PRI:
1013                         ast_mutex_unlock(&pri->lock);
1014                         break;
1015 #endif
1016 #ifdef HAVE_SS7
1017                 case SIG_SS7:
1018                         ast_mutex_unlock(&ss7->lock);
1019                         break;
1020 #endif
1021                 default:
1022                         break;
1023                 }
1024         }
1025 #endif          
1026         for (;;) {
1027                 if (p->owner) {
1028                         if (ast_channel_trylock(p->owner)) {
1029                                 DEADLOCK_AVOIDANCE(&p->lock);
1030                         } else {
1031                                 ast_queue_frame(p->owner, f);
1032                                 ast_channel_unlock(p->owner);
1033                                 break;
1034                         }
1035                 } else
1036                         break;
1037         }
1038 #if defined(HAVE_PRI) || defined(HAVE_SS7)
1039         if (data) {
1040                 switch (p->sig) {
1041 #ifdef HAVE_PRI
1042                 case SIG_BRI:
1043                 case SIG_BRI_PTMP:
1044                 case SIG_PRI:
1045                         ast_mutex_lock(&pri->lock);
1046                         break;
1047 #endif
1048 #ifdef HAVE_SS7
1049                 case SIG_SS7:
1050                         ast_mutex_lock(&ss7->lock);
1051                         break;
1052 #endif
1053                 default:
1054                         break;
1055                 }
1056         }
1057
1058 #endif          
1059 }
1060
1061 static int restore_gains(struct dahdi_pvt *p);
1062
1063 static void swap_subs(struct dahdi_pvt *p, int a, int b)
1064 {
1065         int tchan;
1066         int tinthreeway;
1067         struct ast_channel *towner;
1068
1069         ast_debug(1, "Swapping %d and %d\n", a, b);
1070
1071         tchan = p->subs[a].chan;
1072         towner = p->subs[a].owner;
1073         tinthreeway = p->subs[a].inthreeway;
1074
1075         p->subs[a].chan = p->subs[b].chan;
1076         p->subs[a].owner = p->subs[b].owner;
1077         p->subs[a].inthreeway = p->subs[b].inthreeway;
1078
1079         p->subs[b].chan = tchan;
1080         p->subs[b].owner = towner;
1081         p->subs[b].inthreeway = tinthreeway;
1082
1083         if (p->subs[a].owner) 
1084                 ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
1085         if (p->subs[b].owner) 
1086                 ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
1087         wakeup_sub(p, a, NULL);
1088         wakeup_sub(p, b, NULL);
1089 }
1090
1091 static int dahdi_open(char *fn)
1092 {
1093         int fd;
1094         int isnum;
1095         int chan = 0;
1096         int bs;
1097         int x;
1098         isnum = 1;
1099         for (x = 0; x < strlen(fn); x++) {
1100                 if (!isdigit(fn[x])) {
1101                         isnum = 0;
1102                         break;
1103                 }
1104         }
1105         if (isnum) {
1106                 chan = atoi(fn);
1107                 if (chan < 1) {
1108                         ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
1109                         return -1;
1110                 }
1111                 fn = "/dev/dahdi/channel";
1112         }
1113         fd = open(fn, O_RDWR | O_NONBLOCK);
1114         if (fd < 0) {
1115                 ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
1116                 return -1;
1117         }
1118         if (chan) {
1119                 if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
1120                         x = errno;
1121                         close(fd);
1122                         errno = x;
1123                         ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
1124                         return -1;
1125                 }
1126         }
1127         bs = READ_SIZE;
1128         if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
1129                 ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs,  strerror(errno));
1130                 x = errno;
1131                 close(fd);
1132                 errno = x;
1133                 return -1;
1134         }
1135         return fd;
1136 }
1137
1138 static void dahdi_close(int fd)
1139 {
1140         if (fd > 0)
1141                 close(fd);
1142 }
1143
1144 static int dahdi_setlinear(int dfd, int linear)
1145 {
1146         int res;
1147         res = ioctl(dfd, DAHDI_SETLINEAR, &linear);
1148         if (res)
1149                 return res;
1150         return 0;
1151 }
1152
1153
1154 static int alloc_sub(struct dahdi_pvt *p, int x)
1155 {
1156         struct dahdi_bufferinfo bi;
1157         int res;
1158         if (p->subs[x].dfd >= 0) {
1159                 ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
1160                 return -1;
1161         }
1162
1163         p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
1164         if (p->subs[x].dfd <= -1) {
1165                 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
1166                 return -1;
1167         }
1168
1169         res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
1170         if (!res) {
1171                 bi.txbufpolicy = p->buf_policy;
1172                 bi.rxbufpolicy = p->buf_policy;
1173                 bi.numbufs = p->buf_no;
1174                 res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
1175                 if (res < 0) {
1176                         ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
1177                 }
1178         } else 
1179                 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
1180
1181         if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
1182                 ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
1183                 dahdi_close(p->subs[x].dfd);
1184                 p->subs[x].dfd = -1;
1185                 return -1;
1186         }
1187         ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
1188         return 0;
1189 }
1190
1191 static int unalloc_sub(struct dahdi_pvt *p, int x)
1192 {
1193         if (!x) {
1194                 ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
1195                 return -1;
1196         }
1197         ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
1198         if (p->subs[x].dfd > -1) {
1199                 dahdi_close(p->subs[x].dfd);
1200         }
1201         p->subs[x].dfd = -1;
1202         p->subs[x].linear = 0;
1203         p->subs[x].chan = 0;
1204         p->subs[x].owner = NULL;
1205         p->subs[x].inthreeway = 0;
1206         p->polarity = POLARITY_IDLE;
1207         memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
1208         return 0;
1209 }
1210
1211 static int digit_to_dtmfindex(char digit)
1212 {
1213         if (isdigit(digit))
1214                 return DAHDI_TONE_DTMF_BASE + (digit - '0');
1215         else if (digit >= 'A' && digit <= 'D')
1216                 return DAHDI_TONE_DTMF_A + (digit - 'A');
1217         else if (digit >= 'a' && digit <= 'd')
1218                 return DAHDI_TONE_DTMF_A + (digit - 'a');
1219         else if (digit == '*')
1220                 return DAHDI_TONE_DTMF_s;
1221         else if (digit == '#')
1222                 return DAHDI_TONE_DTMF_p;
1223         else
1224                 return -1;
1225 }
1226
1227 static int dahdi_digit_begin(struct ast_channel *chan, char digit)
1228 {
1229         struct dahdi_pvt *pvt;
1230         int idx;
1231         int dtmf = -1;
1232         
1233         pvt = chan->tech_pvt;
1234
1235         ast_mutex_lock(&pvt->lock);
1236
1237         idx = dahdi_get_index(chan, pvt, 0);
1238
1239         if ((idx != SUB_REAL) || !pvt->owner)
1240                 goto out;
1241
1242 #ifdef HAVE_PRI
1243         if (((pvt->sig == SIG_PRI) || (pvt->sig == SIG_BRI) || (pvt->sig == SIG_BRI_PTMP)) 
1244                         && (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
1245                 if (pvt->setup_ack) {
1246                         if (!pri_grab(pvt, pvt->pri)) {
1247                                 pri_information(pvt->pri->pri, pvt->call, digit);
1248                                 pri_rel(pvt->pri);
1249                         } else
1250                                 ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
1251                 } else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
1252                         int res;
1253                         ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit);
1254                         res = strlen(pvt->dialdest);
1255                         pvt->dialdest[res++] = digit;
1256                         pvt->dialdest[res] = '\0';
1257                 }
1258                 goto out;
1259         }
1260 #endif
1261         if ((dtmf = digit_to_dtmfindex(digit)) == -1)
1262                 goto out;
1263
1264         if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
1265                 int res;
1266                 struct dahdi_dialoperation zo = {
1267                         .op = DAHDI_DIAL_OP_APPEND,
1268                 };
1269
1270                 zo.dialstr[0] = 'T';
1271                 zo.dialstr[1] = digit;
1272                 zo.dialstr[2] = '\0';
1273                 if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo)))
1274                         ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno));
1275                 else
1276                         pvt->dialing = 1;
1277         } else {
1278                 ast_debug(1, "Started VLDTMF digit '%c'\n", digit);
1279                 pvt->dialing = 1;
1280                 pvt->begindigit = digit;
1281         }
1282
1283 out:
1284         ast_mutex_unlock(&pvt->lock);
1285
1286         return 0;
1287 }
1288
1289 static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
1290 {
1291         struct dahdi_pvt *pvt;
1292         int res = 0;
1293         int idx;
1294         int x;
1295         
1296         pvt = chan->tech_pvt;
1297
1298         ast_mutex_lock(&pvt->lock);
1299         
1300         idx = dahdi_get_index(chan, pvt, 0);
1301
1302         if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
1303                 goto out;
1304
1305 #ifdef HAVE_PRI
1306         /* This means that the digit was already sent via PRI signalling */
1307         if (((pvt->sig == SIG_PRI) || (pvt->sig == SIG_BRI) || (pvt->sig == SIG_BRI_PTMP))
1308                         && !pvt->begindigit)
1309                 goto out;
1310 #endif
1311
1312         if (pvt->begindigit) {
1313                 x = -1;
1314                 ast_debug(1, "Ending VLDTMF digit '%c'\n", digit);
1315                 res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
1316                 pvt->dialing = 0;
1317                 pvt->begindigit = 0;
1318         }
1319
1320 out:
1321         ast_mutex_unlock(&pvt->lock);
1322
1323         return res;
1324 }
1325
1326 static char *events[] = {
1327         "No event",
1328         "On hook",
1329         "Ring/Answered",
1330         "Wink/Flash",
1331         "Alarm",
1332         "No more alarm",
1333         "HDLC Abort",
1334         "HDLC Overrun",
1335         "HDLC Bad FCS",
1336         "Dial Complete",
1337         "Ringer On",
1338         "Ringer Off",
1339         "Hook Transition Complete",
1340         "Bits Changed",
1341         "Pulse Start",
1342         "Timer Expired",
1343         "Timer Ping",
1344         "Polarity Reversal",
1345         "Ring Begin",
1346 };
1347
1348 static struct {
1349         int alarm;
1350         char *name;
1351 } alarms[] = {
1352         { DAHDI_ALARM_RED, "Red Alarm" },
1353         { DAHDI_ALARM_YELLOW, "Yellow Alarm" },
1354         { DAHDI_ALARM_BLUE, "Blue Alarm" },
1355         { DAHDI_ALARM_RECOVER, "Recovering" },
1356         { DAHDI_ALARM_LOOPBACK, "Loopback" },
1357         { DAHDI_ALARM_NOTOPEN, "Not Open" },
1358         { DAHDI_ALARM_NONE, "None" },
1359 };
1360
1361 static char *alarm2str(int alm)
1362 {
1363         int x;
1364         for (x = 0; x < ARRAY_LEN(alarms); x++) {
1365                 if (alarms[x].alarm & alm)
1366                         return alarms[x].name;
1367         }
1368         return alm ? "Unknown Alarm" : "No Alarm";
1369 }
1370
1371 static char *event2str(int event)
1372 {
1373         static char buf[256];
1374         if ((event < (ARRAY_LEN(events))) && (event > -1))
1375                 return events[event];
1376         sprintf(buf, "Event %d", event); /* safe */
1377         return buf;
1378 }
1379
1380 #ifdef HAVE_PRI
1381 static char *dialplan2str(int dialplan)
1382 {
1383         if (dialplan == -1 || dialplan == -2) {
1384                 return("Dynamically set dialplan in ISDN");
1385         }
1386         return (pri_plan2str(dialplan));
1387 }
1388 #endif
1389
1390 static char *dahdi_sig2str(int sig)
1391 {
1392         static char buf[256];
1393         switch (sig) {
1394         case SIG_EM:
1395                 return "E & M Immediate";
1396         case SIG_EMWINK:
1397                 return "E & M Wink";
1398         case SIG_EM_E1:
1399                 return "E & M E1";
1400         case SIG_FEATD:
1401                 return "Feature Group D (DTMF)";
1402         case SIG_FEATDMF:
1403                 return "Feature Group D (MF)";
1404         case SIG_FEATDMF_TA:
1405                 return "Feature Groud D (MF) Tandem Access";
1406         case SIG_FEATB:
1407                 return "Feature Group B (MF)";
1408         case SIG_E911:
1409                 return "E911 (MF)";
1410         case SIG_FGC_CAMA:
1411                 return "FGC/CAMA (Dialpulse)";
1412         case SIG_FGC_CAMAMF:
1413                 return "FGC/CAMA (MF)";
1414         case SIG_FXSLS:
1415                 return "FXS Loopstart";
1416         case SIG_FXSGS:
1417                 return "FXS Groundstart";
1418         case SIG_FXSKS:
1419                 return "FXS Kewlstart";
1420         case SIG_FXOLS:
1421                 return "FXO Loopstart";
1422         case SIG_FXOGS:
1423                 return "FXO Groundstart";
1424         case SIG_FXOKS:
1425                 return "FXO Kewlstart";
1426         case SIG_PRI:
1427                 return "ISDN PRI";
1428         case SIG_BRI:
1429                 return "ISDN BRI Point to Point";
1430         case SIG_BRI_PTMP:
1431                 return "ISDN BRI Point to MultiPoint";
1432         case SIG_SS7:
1433                 return "SS7";
1434         case SIG_SF:
1435                 return "SF (Tone) Immediate";
1436         case SIG_SFWINK:
1437                 return "SF (Tone) Wink";
1438         case SIG_SF_FEATD:
1439                 return "SF (Tone) with Feature Group D (DTMF)";
1440         case SIG_SF_FEATDMF:
1441                 return "SF (Tone) with Feature Group D (MF)";
1442         case SIG_SF_FEATB:
1443                 return "SF (Tone) with Feature Group B (MF)";
1444         case SIG_GR303FXOKS:
1445                 return "GR-303 with FXOKS";
1446         case SIG_GR303FXSKS:
1447                 return "GR-303 with FXSKS";
1448         case 0:
1449                 return "Pseudo";
1450         default:
1451                 snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
1452                 return buf;
1453         }
1454 }
1455
1456 #define sig2str dahdi_sig2str
1457
1458 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx, int slavechannel)
1459 {
1460         /* If the conference already exists, and we're already in it
1461            don't bother doing anything */
1462         struct dahdi_confinfo zi;
1463         
1464         memset(&zi, 0, sizeof(zi));
1465         zi.chan = 0;
1466
1467         if (slavechannel > 0) {
1468                 /* If we have only one slave, do a digital mon */
1469                 zi.confmode = DAHDI_CONF_DIGITALMON;
1470                 zi.confno = slavechannel;
1471         } else {
1472                 if (!idx) {
1473                         /* Real-side and pseudo-side both participate in conference */
1474                         zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
1475                                 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
1476                 } else
1477                         zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
1478                 zi.confno = p->confno;
1479         }
1480         if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
1481                 return 0;
1482         if (c->dfd < 0)
1483                 return 0;
1484         if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
1485                 ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
1486                 return -1;
1487         }
1488         if (slavechannel < 1) {
1489                 p->confno = zi.confno;
1490         }
1491         memcpy(&c->curconf, &zi, sizeof(c->curconf));
1492         ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
1493         return 0;
1494 }
1495
1496 static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
1497 {
1498         /* If they're listening to our channel, they're ours */ 
1499         if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
1500                 return 1;
1501         /* If they're a talker on our (allocated) conference, they're ours */
1502         if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
1503                 return 1;
1504         return 0;
1505 }
1506
1507 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx)
1508 {
1509         struct dahdi_confinfo zi;
1510         if (/* Can't delete if there's no dfd */
1511                 (c->dfd < 0) ||
1512                 /* Don't delete from the conference if it's not our conference */
1513                 !isourconf(p, c)
1514                 /* Don't delete if we don't think it's conferenced at all (implied) */
1515                 ) return 0;
1516         memset(&zi, 0, sizeof(zi));
1517         zi.chan = 0;
1518         zi.confno = 0;
1519         zi.confmode = 0;
1520         if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
1521                 ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
1522                 return -1;
1523         }
1524         ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
1525         memcpy(&c->curconf, &zi, sizeof(c->curconf));
1526         return 0;
1527 }
1528
1529 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
1530 {
1531         int x;
1532         int useslavenative;
1533         struct dahdi_pvt *slave = NULL;
1534         /* Start out optimistic */
1535         useslavenative = 1;
1536         /* Update conference state in a stateless fashion */
1537         for (x = 0; x < 3; x++) {
1538                 /* Any three-way calling makes slave native mode *definitely* out
1539                    of the question */
1540                 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
1541                         useslavenative = 0;
1542         }
1543         /* If we don't have any 3-way calls, check to see if we have
1544            precisely one slave */
1545         if (useslavenative) {
1546                 for (x = 0; x < MAX_SLAVES; x++) {
1547                         if (p->slaves[x]) {
1548                                 if (slave) {
1549                                         /* Whoops already have a slave!  No 
1550                                            slave native and stop right away */
1551                                         slave = NULL;
1552                                         useslavenative = 0;
1553                                         break;
1554                                 } else {
1555                                         /* We have one slave so far */
1556                                         slave = p->slaves[x];
1557                                 }
1558                         }
1559                 }
1560         }
1561         /* If no slave, slave native definitely out */
1562         if (!slave)
1563                 useslavenative = 0;
1564         else if (slave->law != p->law) {
1565                 useslavenative = 0;
1566                 slave = NULL;
1567         }
1568         if (out)
1569                 *out = slave;
1570         return useslavenative;
1571 }
1572
1573 static int reset_conf(struct dahdi_pvt *p)
1574 {
1575         struct dahdi_confinfo zi;
1576         memset(&zi, 0, sizeof(zi));
1577         p->confno = -1;
1578         memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
1579         if (p->subs[SUB_REAL].dfd > -1) {
1580                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
1581                         ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
1582         }
1583         return 0;
1584 }
1585
1586 static int update_conf(struct dahdi_pvt *p)
1587 {
1588         int needconf = 0;
1589         int x;
1590         int useslavenative;
1591         struct dahdi_pvt *slave = NULL;
1592
1593         useslavenative = isslavenative(p, &slave);
1594         /* Start with the obvious, general stuff */
1595         for (x = 0; x < 3; x++) {
1596                 /* Look for three way calls */
1597                 if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
1598                         conf_add(p, &p->subs[x], x, 0);
1599                         needconf++;
1600                 } else {
1601                         conf_del(p, &p->subs[x], x);
1602                 }
1603         }
1604         /* If we have a slave, add him to our conference now. or DAX
1605            if this is slave native */
1606         for (x = 0; x < MAX_SLAVES; x++) {
1607                 if (p->slaves[x]) {
1608                         if (useslavenative)
1609                                 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
1610                         else {
1611                                 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
1612                                 needconf++;
1613                         }
1614                 }
1615         }
1616         /* If we're supposed to be in there, do so now */
1617         if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
1618                 if (useslavenative)
1619                         conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
1620                 else {
1621                         conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
1622                         needconf++;
1623                 }
1624         }
1625         /* If we have a master, add ourselves to his conference */
1626         if (p->master) {
1627                 if (isslavenative(p->master, NULL)) {
1628                         conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
1629                 } else {
1630                         conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
1631                 }
1632         }
1633         if (!needconf) {
1634                 /* Nobody is left (or should be left) in our conference.
1635                    Kill it. */
1636                 p->confno = -1;
1637         }
1638         ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
1639         return 0;
1640 }
1641
1642 static void dahdi_enable_ec(struct dahdi_pvt *p)
1643 {
1644         int x;
1645         int res;
1646         if (!p)
1647                 return;
1648         if (p->echocanon) {
1649                 ast_debug(1, "Echo cancellation already on\n");
1650                 return;
1651         }
1652         if (p->digital) {
1653                 ast_debug(1, "Echo cancellation isn't required on digital connection\n");
1654                 return;
1655         }
1656         if (p->echocancel.head.tap_length) {
1657                 if ((p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP) || (p->sig == SIG_PRI) || (p->sig == SIG_SS7)) {
1658                         x = 1;
1659                         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
1660                         if (res)
1661                                 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
1662                 }
1663                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
1664                 if (res)  {
1665                         ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
1666                 } else {
1667                         p->echocanon = 1;
1668                         ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
1669                 }
1670         } else
1671                 ast_debug(1, "No echo cancellation requested\n");
1672 }
1673
1674 static void dahdi_train_ec(struct dahdi_pvt *p)
1675 {
1676         int x;
1677         int res;
1678         
1679         if (p && p->echocanon && p->echotraining) {
1680                 x = p->echotraining;
1681                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
1682                 if (res)
1683                         ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
1684                 else
1685                         ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
1686         } else {
1687                 ast_debug(1, "No echo training requested\n");
1688         }
1689 }
1690
1691 static void dahdi_disable_ec(struct dahdi_pvt *p)
1692 {
1693         int res;
1694
1695         if (p->echocanon) {
1696                 struct dahdi_echocanparams ecp = { .tap_length = 0 };
1697
1698                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
1699
1700                 if (res)
1701                         ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
1702                 else
1703                         ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
1704         }
1705
1706         p->echocanon = 0;
1707 }
1708
1709 static void fill_txgain(struct dahdi_gains *g, float gain, int law)
1710 {
1711         int j;
1712         int k;
1713         float linear_gain = pow(10.0, gain / 20.0);
1714
1715         switch (law) {
1716         case DAHDI_LAW_ALAW:
1717                 for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
1718                         if (gain) {
1719                                 k = (int) (((float) AST_ALAW(j)) * linear_gain);
1720                                 if (k > 32767) k = 32767;
1721                                 if (k < -32767) k = -32767;
1722                                 g->txgain[j] = AST_LIN2A(k);
1723                         } else {
1724                                 g->txgain[j] = j;
1725                         }
1726                 }
1727                 break;
1728         case DAHDI_LAW_MULAW:
1729                 for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
1730                         if (gain) {
1731                                 k = (int) (((float) AST_MULAW(j)) * linear_gain);
1732                                 if (k > 32767) k = 32767;
1733                                 if (k < -32767) k = -32767;
1734                                 g->txgain[j] = AST_LIN2MU(k);
1735                         } else {
1736                                 g->txgain[j] = j;
1737                         }
1738                 }
1739                 break;
1740         }
1741 }
1742
1743 static void fill_rxgain(struct dahdi_gains *g, float gain, int law)
1744 {
1745         int j;
1746         int k;
1747         float linear_gain = pow(10.0, gain / 20.0);
1748
1749         switch (law) {
1750         case DAHDI_LAW_ALAW:
1751                 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
1752                         if (gain) {
1753                                 k = (int) (((float) AST_ALAW(j)) * linear_gain);
1754                                 if (k > 32767) k = 32767;
1755                                 if (k < -32767) k = -32767;
1756                                 g->rxgain[j] = AST_LIN2A(k);
1757                         } else {
1758                                 g->rxgain[j] = j;
1759                         }
1760                 }
1761                 break;
1762         case DAHDI_LAW_MULAW:
1763                 for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
1764                         if (gain) {
1765                                 k = (int) (((float) AST_MULAW(j)) * linear_gain);
1766                                 if (k > 32767) k = 32767;
1767                                 if (k < -32767) k = -32767;
1768                                 g->rxgain[j] = AST_LIN2MU(k);
1769                         } else {
1770                                 g->rxgain[j] = j;
1771                         }
1772                 }
1773                 break;
1774         }
1775 }
1776
1777 static int set_actual_txgain(int fd, int chan, float gain, int law)
1778 {
1779         struct dahdi_gains g;
1780         int res;
1781
1782         memset(&g, 0, sizeof(g));
1783         g.chan = chan;
1784         res = ioctl(fd, DAHDI_GETGAINS, &g);
1785         if (res) {
1786                 ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
1787                 return res;
1788         }
1789
1790         fill_txgain(&g, gain, law);
1791
1792         return ioctl(fd, DAHDI_SETGAINS, &g);
1793 }
1794
1795 static int set_actual_rxgain(int fd, int chan, float gain, int law)
1796 {
1797         struct dahdi_gains g;
1798         int res;
1799
1800         memset(&g, 0, sizeof(g));
1801         g.chan = chan;
1802         res = ioctl(fd, DAHDI_GETGAINS, &g);
1803         if (res) {
1804                 ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
1805                 return res;
1806         }
1807
1808         fill_rxgain(&g, gain, law);
1809
1810         return ioctl(fd, DAHDI_SETGAINS, &g);
1811 }
1812
1813 static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
1814 {
1815         return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
1816 }
1817
1818 static int bump_gains(struct dahdi_pvt *p)
1819 {
1820         int res;
1821
1822         /* Bump receive gain by value stored in cid_rxgain */
1823         res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain + p->cid_rxgain, p->txgain, p->law);
1824         if (res) {
1825                 ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
1826                 return -1;
1827         }
1828
1829         return 0;
1830 }
1831
1832 static int restore_gains(struct dahdi_pvt *p)
1833 {
1834         int res;
1835
1836         res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
1837         if (res) {
1838                 ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
1839                 return -1;
1840         }
1841
1842         return 0;
1843 }
1844
1845 static inline int dahdi_set_hook(int fd, int hs)
1846 {
1847         int x, res;
1848
1849         x = hs;
1850         res = ioctl(fd, DAHDI_HOOK, &x);
1851
1852         if (res < 0) {
1853                 if (errno == EINPROGRESS)
1854                         return 0;
1855                 ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
1856                 /* will expectedly fail if phone is off hook during operation, such as during a restart */
1857         }
1858
1859         return res;
1860 }
1861
1862 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
1863 {
1864         int x, y, res;
1865         x = muted;
1866         if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
1867                 y = 1;
1868                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
1869                 if (res)
1870                         ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", p->channel, strerror(errno));
1871         }
1872         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
1873         if (res < 0)
1874                 ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
1875         return res;
1876 }
1877
1878 static int save_conference(struct dahdi_pvt *p)
1879 {
1880         struct dahdi_confinfo c;
1881         int res;
1882         if (p->saveconf.confmode) {
1883                 ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
1884                 return -1;
1885         }
1886         p->saveconf.chan = 0;
1887         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
1888         if (res) {
1889                 ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
1890                 p->saveconf.confmode = 0;
1891                 return -1;
1892         }
1893         c.chan = 0;
1894         c.confno = 0;
1895         c.confmode = DAHDI_CONF_NORMAL;
1896         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
1897         if (res) {
1898                 ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
1899                 return -1;
1900         }
1901         ast_debug(1, "Disabled conferencing\n");
1902         return 0;
1903 }
1904
1905 /*!
1906  * \brief Send MWI state change
1907  *
1908  * \arg mailbox_full This is the mailbox associated with the FXO line that the
1909  *      MWI state has changed on.
1910  * \arg thereornot This argument should simply be set to 1 or 0, to indicate
1911  *      whether there are messages waiting or not.
1912  *
1913  *  \return nothing
1914  *
1915  * This function does two things:
1916  *
1917  * 1) It generates an internal Asterisk event notifying any other module that
1918  *    cares about MWI that the state of a mailbox has changed.
1919  *
1920  * 2) It runs the script specified by the mwimonitornotify option to allow
1921  *    some custom handling of the state change.
1922  */
1923 static void notify_message(char *mailbox_full, int thereornot)
1924 {
1925         char s[sizeof(mwimonitornotify) + 80];
1926         struct ast_event *event;
1927         char *mailbox, *context;
1928
1929         /* Strip off @default */
1930         context = mailbox = ast_strdupa(mailbox_full);
1931         strsep(&context, "@");
1932         if (ast_strlen_zero(context))
1933                 context = "default";
1934
1935         if (!(event = ast_event_new(AST_EVENT_MWI,
1936                         AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
1937                         AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
1938                         AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
1939                         AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
1940                         AST_EVENT_IE_END))) {
1941                 return;
1942         }
1943
1944         ast_event_queue_and_cache(event,
1945                 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
1946                 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
1947                 AST_EVENT_IE_END);
1948
1949         if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
1950                 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
1951                 ast_safe_system(s);
1952         }
1953 }
1954
1955 static int restore_conference(struct dahdi_pvt *p)
1956 {
1957         int res;
1958         if (p->saveconf.confmode) {
1959                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
1960                 p->saveconf.confmode = 0;
1961                 if (res) {
1962                         ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
1963                         return -1;
1964                 }
1965         }
1966         ast_debug(1, "Restored conferencing\n");
1967         return 0;
1968 }
1969
1970 static int send_callerid(struct dahdi_pvt *p);
1971
1972 static int send_cwcidspill(struct dahdi_pvt *p)
1973 {
1974         p->callwaitcas = 0;
1975         p->cidcwexpire = 0;
1976         if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
1977                 return -1;
1978         p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
1979         /* Make sure we account for the end */
1980         p->cidlen += READ_SIZE * 4;
1981         p->cidpos = 0;
1982         send_callerid(p);
1983         ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
1984         return 0;
1985 }
1986
1987 static int has_voicemail(struct dahdi_pvt *p)
1988 {
1989         int new_msgs;
1990         struct ast_event *event;
1991         char *mailbox, *context;
1992
1993         mailbox = context = ast_strdupa(p->mailbox);
1994         strsep(&context, "@");
1995         if (ast_strlen_zero(context))
1996                 context = "default";
1997
1998         event = ast_event_get_cached(AST_EVENT_MWI,
1999                 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
2000                 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
2001                 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
2002                 AST_EVENT_IE_END);
2003
2004         if (event) {
2005                 new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
2006                 ast_event_destroy(event);
2007         } else
2008                 new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
2009
2010         return new_msgs;
2011 }
2012
2013 static int send_callerid(struct dahdi_pvt *p)
2014 {
2015         /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
2016         int res;
2017         /* Take out of linear mode if necessary */
2018         if (p->subs[SUB_REAL].linear) {
2019                 p->subs[SUB_REAL].linear = 0;
2020                 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2021         }
2022         while (p->cidpos < p->cidlen) {
2023                 res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
2024                 if (res < 0) {
2025                         if (errno == EAGAIN)
2026                                 return 0;
2027                         else {
2028                                 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
2029                                 return -1;
2030                         }
2031                 }
2032                 if (!res)
2033                         return 0;
2034                 p->cidpos += res;
2035         }
2036         ast_free(p->cidspill);
2037         p->cidspill = NULL;
2038         if (p->callwaitcas) {
2039                 /* Wait for CID/CW to expire */
2040                 p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
2041         } else
2042                 restore_conference(p);
2043         return 0;
2044 }
2045
2046 static int dahdi_callwait(struct ast_channel *ast)
2047 {
2048         struct dahdi_pvt *p = ast->tech_pvt;
2049         p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
2050         if (p->cidspill) {
2051                 ast_log(LOG_WARNING, "Spill already exists?!?\n");
2052                 ast_free(p->cidspill);
2053         }
2054         if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
2055                 return -1;
2056         save_conference(p);
2057         /* Silence */
2058         memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
2059         if (!p->callwaitrings && p->callwaitingcallerid) {
2060                 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
2061                 p->callwaitcas = 1;
2062                 p->cidlen = 2400 + 680 + READ_SIZE * 4;
2063         } else {
2064                 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
2065                 p->callwaitcas = 0;
2066                 p->cidlen = 2400 + READ_SIZE * 4;
2067         }
2068         p->cidpos = 0;
2069         send_callerid(p);
2070         
2071         return 0;
2072 }
2073
2074 #ifdef HAVE_SS7
2075 static unsigned char cid_pres2ss7pres(int cid_pres)
2076 {
2077          return (cid_pres >> 5) & 0x03;
2078 }
2079
2080 static unsigned char cid_pres2ss7screen(int cid_pres)
2081 {
2082         return cid_pres & 0x03;
2083 }
2084 #endif
2085
2086 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
2087 {
2088         struct dahdi_pvt *p = ast->tech_pvt;
2089         int x, res, idx,mysig;
2090         char *c, *n, *l;
2091 #ifdef HAVE_PRI
2092         char *s = NULL;
2093 #endif
2094         char dest[256]; /* must be same length as p->dialdest */
2095         ast_mutex_lock(&p->lock);
2096         ast_copy_string(dest, rdest, sizeof(dest));
2097         ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
2098         if ((ast->_state == AST_STATE_BUSY)) {
2099                 p->subs[SUB_REAL].needbusy = 1;
2100                 ast_mutex_unlock(&p->lock);
2101                 return 0;
2102         }
2103         if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
2104                 ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name);
2105                 ast_mutex_unlock(&p->lock);
2106                 return -1;
2107         }
2108         p->dialednone = 0;
2109         if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
2110         {
2111                 /* Special pseudo -- automatically up */
2112                 ast_setstate(ast, AST_STATE_UP); 
2113                 ast_mutex_unlock(&p->lock);
2114                 return 0;
2115         }
2116         x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
2117         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
2118         if (res)
2119                 ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
2120         p->outgoing = 1;
2121
2122         set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
2123
2124         mysig = p->sig;
2125         if (p->outsigmod > -1)
2126                 mysig = p->outsigmod;
2127
2128         switch (mysig) {
2129         case SIG_FXOLS:
2130         case SIG_FXOGS:
2131         case SIG_FXOKS:
2132                 if (p->owner == ast) {
2133                         /* Normal ring, on hook */
2134                         
2135                         /* Don't send audio while on hook, until the call is answered */
2136                         p->dialing = 1;
2137                         if (p->use_callerid) {
2138                                 /* Generate the Caller-ID spill if desired */
2139                                 if (p->cidspill) {
2140                                         ast_log(LOG_WARNING, "cidspill already exists??\n");
2141                                         ast_free(p->cidspill);
2142                                 }
2143                                 p->callwaitcas = 0;
2144                                 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
2145                                         p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
2146                                         p->cidpos = 0;
2147                                         send_callerid(p);
2148                                 }
2149                         }
2150                         /* Choose proper cadence */
2151                         if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
2152                                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
2153                                         ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
2154                                 p->cidrings = cidrings[p->distinctivering - 1];
2155                         } else {
2156                                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
2157                                         ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
2158                                 p->cidrings = p->sendcalleridafter;
2159                         }
2160
2161                         /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
2162                         c = strchr(dest, '/');
2163                         if (c)
2164                                 c++;
2165                         if (c && (strlen(c) < p->stripmsd)) {
2166                                 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
2167                                 c = NULL;
2168                         }
2169                         if (c) {
2170                                 p->dop.op = DAHDI_DIAL_OP_REPLACE;
2171                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
2172                                 ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
2173                         } else {
2174                                 p->dop.dialstr[0] = '\0';
2175                         }
2176                         x = DAHDI_RING;
2177                         if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x) && (errno != EINPROGRESS)) {
2178                                 ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
2179                                 ast_mutex_unlock(&p->lock);
2180                                 return -1;
2181                         }
2182                         p->dialing = 1;
2183                 } else {
2184                         /* Call waiting call */
2185                         p->callwaitrings = 0;
2186                         if (ast->cid.cid_num)
2187                                 ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
2188                         else
2189                                 p->callwait_num[0] = '\0';
2190                         if (ast->cid.cid_name)
2191                                 ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
2192                         else
2193                                 p->callwait_name[0] = '\0';
2194                         /* Call waiting tone instead */
2195                         if (dahdi_callwait(ast)) {
2196                                 ast_mutex_unlock(&p->lock);
2197                                 return -1;
2198                         }
2199                         /* Make ring-back */
2200                         if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].dfd, DAHDI_TONE_RINGTONE))
2201                                 ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
2202                                 
2203                 }
2204                 n = ast->cid.cid_name;
2205                 l = ast->cid.cid_num;
2206                 if (l)
2207                         ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
2208                 else
2209                         p->lastcid_num[0] = '\0';
2210                 if (n)
2211                         ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
2212                 else
2213                         p->lastcid_name[0] = '\0';
2214                 ast_setstate(ast, AST_STATE_RINGING);
2215                 idx = dahdi_get_index(ast, p, 0);
2216                 if (idx > -1) {
2217                         p->subs[idx].needringing = 1;
2218                 }
2219                 break;
2220         case SIG_FXSLS:
2221         case SIG_FXSGS:
2222         case SIG_FXSKS:
2223         case SIG_EMWINK:
2224         case SIG_EM:
2225         case SIG_EM_E1:
2226         case SIG_FEATD:
2227         case SIG_FEATDMF:
2228         case SIG_E911:
2229         case SIG_FGC_CAMA:
2230         case SIG_FGC_CAMAMF:
2231         case SIG_FEATB:
2232         case SIG_SFWINK:
2233         case SIG_SF:
2234         case SIG_SF_FEATD:
2235         case SIG_SF_FEATDMF:
2236         case SIG_FEATDMF_TA:
2237         case SIG_SF_FEATB:
2238                 c = strchr(dest, '/');
2239                 if (c)
2240                         c++;
2241                 else
2242                         c = "";
2243                 if (strlen(c) < p->stripmsd) {
2244                         ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
2245                         ast_mutex_unlock(&p->lock);
2246                         return -1;
2247                 }
2248 #ifdef HAVE_PRI
2249                 /* Start the trunk, if not GR-303 */
2250                 if (!p->pri) {
2251 #endif
2252                         x = DAHDI_START;
2253                         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2254                         if (res < 0) {
2255                                 if (errno != EINPROGRESS) {
2256                                         ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
2257                                         ast_mutex_unlock(&p->lock);
2258                                         return -1;
2259                                 }
2260                         }
2261 #ifdef HAVE_PRI
2262                 }
2263 #endif
2264                 ast_debug(1, "Dialing '%s'\n", c);
2265                 p->dop.op = DAHDI_DIAL_OP_REPLACE;
2266
2267                 c += p->stripmsd;
2268
2269                 switch (mysig) {
2270                 case SIG_FEATD:
2271                         l = ast->cid.cid_num;
2272                         if (l) 
2273                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
2274                         else
2275                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
2276                         break;
2277                 case SIG_FEATDMF:
2278                         l = ast->cid.cid_num;
2279                         if (l) 
2280                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
2281                         else
2282                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
2283                         break;
2284                 case SIG_FEATDMF_TA:
2285                 {
2286                         const char *cic, *ozz;
2287
2288                         /* If you have to go through a Tandem Access point you need to use this */
2289                         ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
2290                         if (!ozz)
2291                                 ozz = defaultozz;
2292                         cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
2293                         if (!cic)
2294                                 cic = defaultcic;
2295                         if (!ozz || !cic) {
2296                                 ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
2297                                 ast_mutex_unlock(&p->lock);
2298                                 return -1;
2299                         }
2300                         snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
2301                         snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
2302                         p->whichwink = 0;
2303                 }
2304                         break;
2305                 case SIG_E911:
2306                         ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
2307                         break;
2308                 case SIG_FGC_CAMA:
2309                         snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
2310                         break;
2311                 case SIG_FGC_CAMAMF:
2312                 case SIG_FEATB:
2313                         snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
2314                         break;
2315                 default:
2316                         if (p->pulse)
2317                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
2318                         else
2319                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
2320                         break;
2321                 }
2322
2323                 if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
2324                         memset(p->echorest, 'w', sizeof(p->echorest) - 1);
2325                         strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
2326                         p->echorest[sizeof(p->echorest) - 1] = '\0';
2327                         p->echobreak = 1;
2328                         p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
2329                 } else
2330                         p->echobreak = 0;
2331                 if (!res) {
2332                         if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
2333                                 int saveerr = errno;
2334
2335                                 x = DAHDI_ONHOOK;
2336                                 ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2337                                 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
2338                                 ast_mutex_unlock(&p->lock);
2339                                 return -1;
2340                         }
2341                 } else
2342                         ast_debug(1, "Deferring dialing...\n");
2343
2344                 p->dialing = 1;
2345                 if (ast_strlen_zero(c))
2346                         p->dialednone = 1;
2347                 ast_setstate(ast, AST_STATE_DIALING);
2348                 break;
2349         case 0:
2350                 /* Special pseudo -- automatically up*/
2351                 ast_setstate(ast, AST_STATE_UP);
2352                 break;          
2353         case SIG_PRI:
2354         case SIG_BRI:
2355         case SIG_BRI_PTMP:
2356         case SIG_SS7:
2357                 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
2358                 p->dialdest[0] = '\0';
2359                 break;
2360         default:
2361                 ast_debug(1, "not yet implemented\n");
2362                 ast_mutex_unlock(&p->lock);
2363                 return -1;
2364         }
2365 #ifdef HAVE_SS7
2366         if (p->ss7) {
2367                 char ss7_called_nai;
2368                 int called_nai_strip;
2369                 char ss7_calling_nai;
2370                 int calling_nai_strip;
2371                 const char *charge_str = NULL;
2372                 const char *gen_address = NULL;
2373                 const char *gen_digits = NULL;
2374                 const char *gen_dig_type = NULL;
2375                 const char *gen_dig_scheme = NULL;
2376                 const char *gen_name = NULL;
2377                 const char *jip_digits = NULL;
2378                 const char *lspi_ident = NULL;
2379                 const char *rlt_flag = NULL;
2380                 const char *call_ref_id = NULL;
2381                 const char *call_ref_pc = NULL;
2382                 const char *send_far = NULL;
2383
2384                 c = strchr(dest, '/');
2385                 if (c)
2386                         c++;
2387                 else
2388                         c = dest;
2389
2390                 if (!p->hidecallerid) {
2391                         l = ast->cid.cid_num;
2392                 } else {
2393                         l = NULL;
2394                 }
2395
2396                 if (ss7_grab(p, p->ss7)) {
2397                         ast_log(LOG_WARNING, "Failed to grab SS7!\n");
2398                         ast_mutex_unlock(&p->lock);
2399                         return -1;
2400                 }
2401                 p->digital = IS_DIGITAL(ast->transfercapability);
2402                 p->ss7call = isup_new_call(p->ss7->ss7);
2403
2404                 if (!p->ss7call) {
2405                         ss7_rel(p->ss7);
2406                         ast_mutex_unlock(&p->lock);
2407                         ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n");
2408                         return -1;
2409                 }
2410
2411                 called_nai_strip = 0;
2412                 ss7_called_nai = p->ss7->called_nai;
2413                 if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */
2414                         if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
2415                                 called_nai_strip = strlen(p->ss7->internationalprefix);
2416                                 ss7_called_nai = SS7_NAI_INTERNATIONAL;
2417                         } else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
2418                                 called_nai_strip = strlen(p->ss7->nationalprefix);
2419                                 ss7_called_nai = SS7_NAI_NATIONAL;
2420                         } else {
2421                                 ss7_called_nai = SS7_NAI_SUBSCRIBER;
2422                         }
2423                 }
2424                 isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7);
2425
2426                 calling_nai_strip = 0;
2427                 ss7_calling_nai = p->ss7->calling_nai;
2428                 if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */
2429                         if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
2430                                 calling_nai_strip = strlen(p->ss7->internationalprefix);
2431                                 ss7_calling_nai = SS7_NAI_INTERNATIONAL;
2432                         } else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
2433                                 calling_nai_strip = strlen(p->ss7->nationalprefix);
2434                                 ss7_calling_nai = SS7_NAI_NATIONAL;
2435                         } else {
2436                                 ss7_calling_nai = SS7_NAI_SUBSCRIBER;
2437                         }
2438                 }
2439                 isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
2440                         p->use_callingpres ? cid_pres2ss7pres(ast->cid.cid_pres) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
2441                         p->use_callingpres ? cid_pres2ss7screen(ast->cid.cid_pres) : SS7_SCREENING_USER_PROVIDED );
2442
2443                 isup_set_oli(p->ss7call, ast->cid.cid_ani2);
2444                 isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
2445
2446                 ast_channel_lock(ast);
2447                 /* Set the charge number if it is set */
2448                 charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
2449                 if (charge_str)
2450                         isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
2451                 
2452                 gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
2453                 if (gen_address)
2454                         isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
2455                 
2456                 gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
2457                 gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
2458                 gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
2459                 if (gen_digits)
2460                         isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme)); 
2461                 
2462                 gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
2463                 if (gen_name)
2464                         isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
2465
2466                 jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
2467                 if (jip_digits)
2468                         isup_set_jip_digits(p->ss7call, jip_digits);
2469                 
2470                 lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
2471                 if (lspi_ident)
2472                         isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00); 
2473                 
2474                 rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
2475                 if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
2476                         isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
2477                 }
2478                 
2479                 call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
2480                 call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
2481                 if (call_ref_id && call_ref_pc) {
2482                         isup_set_callref(p->ss7call, atoi(call_ref_id),
2483                                          call_ref_pc ? atoi(call_ref_pc) : 0);
2484                 }
2485                 
2486                 send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR");
2487                 if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 ))
2488                         (isup_far(p->ss7->ss7, p->ss7call));
2489                 
2490                 ast_channel_unlock(ast);
2491
2492                 isup_iam(p->ss7->ss7, p->ss7call);
2493                 ast_setstate(ast, AST_STATE_DIALING);
2494                 ss7_rel(p->ss7);
2495         }
2496 #endif /* HAVE_SS7 */
2497 #ifdef HAVE_PRI
2498         if (p->pri) {
2499                 struct pri_sr *sr;
2500 #ifdef SUPPORT_USERUSER
2501                 const char *useruser;
2502 #endif
2503                 int pridialplan;
2504                 int dp_strip;
2505                 int prilocaldialplan;
2506                 int ldp_strip;
2507                 int exclusive;
2508                 const char *rr_str;
2509                 int redirect_reason;
2510
2511                 c = strchr(dest, '/');
2512                 if (c)
2513                         c++;
2514                 else
2515                         c = dest;
2516
2517                 l = NULL;
2518                 n = NULL;
2519
2520                 if (!p->hidecallerid) {
2521                         l = ast->cid.cid_num;
2522                         if (!p->hidecalleridname) {
2523                                 n = ast->cid.cid_name;
2524                         }
2525                 }
2526
2527                 if (strlen(c) < p->stripmsd) {
2528                         ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
2529                         ast_mutex_unlock(&p->lock);
2530                         return -1;
2531                 }
2532                 if (mysig != SIG_FXSKS) {
2533                         p->dop.op = DAHDI_DIAL_OP_REPLACE;
2534                         s = strchr(c + p->stripmsd, 'w');
2535                         if (s) {
2536                                 if (strlen(s) > 1)
2537                                         snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
2538                                 else
2539                                         p->dop.dialstr[0] = '\0';
2540                                 *s = '\0';
2541                         } else {
2542                                 p->dop.dialstr[0] = '\0';
2543                         }
2544                 }
2545                 if (pri_grab(p, p->pri)) {
2546                         ast_log(LOG_WARNING, "Failed to grab PRI!\n");
2547                         ast_mutex_unlock(&p->lock);
2548                         return -1;
2549                 }
2550                 if (!(p->call = pri_new_call(p->pri->pri))) {
2551                         ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
2552                         pri_rel(p->pri);
2553                         ast_mutex_unlock(&p->lock);
2554                         return -1;
2555                 }
2556                 if (!(sr = pri_sr_new())) {
2557                         ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
2558                         pri_rel(p->pri);
2559                         ast_mutex_unlock(&p->lock);
2560                 }
2561                 if (p->bearer || (mysig == SIG_FXSKS)) {
2562                         if (p->bearer) {
2563                                 ast_debug(1, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
2564                                 p->bearer->call = p->call;
2565                         } else
2566                                 ast_debug(1, "I'm being setup with no bearer right now...\n");
2567
2568                         pri_set_crv(p->pri->pri, p->call, p->channel, 0);
2569                 }
2570                 p->digital = IS_DIGITAL(ast->transfercapability);
2571                 /* Add support for exclusive override */
2572                 if (p->priexclusive)
2573                         exclusive = 1;
2574                 else {
2575                 /* otherwise, traditional behavior */
2576                         if (p->pri->nodetype == PRI_NETWORK)
2577                                 exclusive = 0;
2578                         else
2579                                 exclusive = 1;
2580                 }
2581                 
2582                 pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
2583                 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
2584                                         (p->digital ? -1 : 
2585                                                 ((p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
2586                 if (p->pri->facilityenable)
2587                         pri_facility_enable(p->pri->pri);
2588
2589                 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
2590                 dp_strip = 0;
2591                 pridialplan = p->pri->dialplan - 1;
2592                 if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
2593                         if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
2594                                 if (pridialplan == -2) {
2595                                         dp_strip = strlen(p->pri->internationalprefix);
2596                                 }
2597                                 pridialplan = PRI_INTERNATIONAL_ISDN;
2598                         } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
2599                                 if (pridialplan == -2) {
2600                                         dp_strip = strlen(p->pri->nationalprefix);
2601                                 }
2602                                 pridialplan = PRI_NATIONAL_ISDN;
2603                         } else {
2604                                 pridialplan = PRI_LOCAL_ISDN;
2605                         }
2606                 }
2607                 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
2608                         switch (c[p->stripmsd]) {
2609                         case 'U':
2610                                 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
2611                                 break;
2612                         case 'I':
2613                                 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
2614                                 break;
2615                         case 'N':
2616                                 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
2617                                 break;
2618                         case 'L':
2619                                 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
2620                                 break;
2621                         case 'S':
2622                                 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
2623                                 break;
2624                         case 'V':
2625                                 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
2626                                 break;
2627                         case 'R':
2628                                 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
2629                                 break;
2630                         case 'u':
2631                                 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
2632                                 break;
2633                         case 'e':
2634                                 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
2635                                 break;
2636                         case 'x':
2637                                 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
2638                                 break;
2639                         case 'f':
2640                                 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
2641                                 break;
2642                         case 'n':
2643                                 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
2644                                 break;
2645                         case 'p':
2646                                 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
2647                                 break;
2648                         case 'r':
2649                                 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
2650                                 break;
2651                         default:
2652                                 if (isalpha(*c))
2653                                         ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
2654                         }
2655                         c++;
2656                 }
2657                 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
2658
2659                 ldp_strip = 0;
2660                 prilocaldialplan = p->pri->localdialplan - 1;
2661                 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
2662                         if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
2663                                 if (prilocaldialplan == -2) {
2664                                         ldp_strip = strlen(p->pri->internationalprefix);
2665                                 }
2666                                 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
2667                         } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
2668                                 if (prilocaldialplan == -2) {
2669                                         ldp_strip = strlen(p->pri->nationalprefix);
2670                                 }
2671                                 prilocaldialplan = PRI_NATIONAL_ISDN;
2672                         } else {
2673                                 prilocaldialplan = PRI_LOCAL_ISDN;
2674                         }
2675                 }
2676                 if (l != NULL) {
2677                         while (*l > '9' && *l != '*' && *l != '#') {
2678                                 switch (*l) {
2679                                 case 'U':
2680                                         prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
2681                                         break;
2682                                 case 'I':
2683                                         prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
2684                                         break;
2685                                 case 'N':
2686                                         prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
2687                                         break;
2688                                 case 'L':
2689                                         prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
2690                                         break;
2691                                 case 'S':
2692                                         prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
2693                                         break;
2694                                 case 'V':
2695                                         prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
2696                                         break;
2697                                 case 'R':
2698                                         prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
2699                                         break;
2700                                 case 'u':
2701                                         prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
2702                                         break;
2703                                 case 'e':
2704                                         prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
2705                                         break;
2706                                 case 'x':
2707                                         prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
2708                                         break;
2709                                 case 'f':
2710                                         prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
2711                                         break;
2712                                 case 'n':
2713                                         prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
2714                                         break;
2715                                 case 'p':
2716                                         prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
2717                                         break;
2718                                 case 'r':
2719                                         prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
2720                                         break;
2721                                 default:
2722                                         if (isalpha(*l))
2723                                                 ast_log(LOG_WARNING, "Unrecognized prilocaldialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c);
2724                                 }
2725                                 l++;
2726                         }
2727                 }
2728                 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
2729                         p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
2730                 if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
2731                         if (!strcasecmp(rr_str, "UNKNOWN"))
2732                                 redirect_reason = 0;
2733                         else if (!strcasecmp(rr_str, "BUSY"))
2734                                 redirect_reason = 1;
2735                         else if (!strcasecmp(rr_str, "NO_REPLY"))
2736                                 redirect_reason = 2;
2737                         else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
2738                                 redirect_reason = 15;
2739                         else
2740                                 redirect_reason = PRI_REDIR_UNCONDITIONAL;
2741                 } else
2742                         redirect_reason = PRI_REDIR_UNCONDITIONAL;
2743                 pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
2744
2745 #ifdef SUPPORT_USERUSER
2746                 /* User-user info */
2747                 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
2748
2749                 if (useruser)
2750                         pri_sr_set_useruser(sr, useruser);
2751 #endif
2752
2753                 if (pri_setup(p->pri->pri, p->call, sr)) {
2754                         ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", 
2755                                 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
2756                         pri_rel(p->pri);
2757                         ast_mutex_unlock(&p->lock);
2758                         pri_sr_free(sr);
2759                         return -1;
2760                 }
2761                 pri_sr_free(sr);
2762                 ast_setstate(ast, AST_STATE_DIALING);
2763                 pri_rel(p->pri);
2764         }
2765 #endif          
2766         ast_mutex_unlock(&p->lock);
2767         return 0;
2768 }
2769
2770 static void destroy_dahdi_pvt(struct dahdi_pvt **pvt)
2771 {
2772         struct dahdi_pvt *p = *pvt;
2773         /* Remove channel from the list */
2774         if (p->prev)
2775                 p->prev->next = p->next;
2776         if (p->next)
2777                 p->next->prev = p->prev;
2778         if (p->use_smdi)
2779                 ast_smdi_interface_unref(p->smdi_iface);
2780         if (p->mwi_event_sub)
2781                 ast_event_unsubscribe(p->mwi_event_sub);
2782         if (p->vars)
2783                 ast_variables_destroy(p->vars);
2784         ast_mutex_destroy(&p->lock);
2785         if (p->owner)
2786                 p->owner->tech_pvt = NULL;
2787         free(p);
2788         *pvt = NULL;
2789 }
2790
2791 static int destroy_channel(struct dahdi_pvt *prev, struct dahdi_pvt *cur, int now)
2792 {
2793         int owned = 0;
2794         int i = 0;
2795
2796         if (!now) {
2797                 if (cur->owner) {
2798                         owned = 1;
2799                 }
2800
2801                 for (i = 0; i < 3; i++) {
2802                         if (cur->subs[i].owner) {
2803                                 owned = 1;
2804                         }
2805                 }
2806                 if (!owned) {
2807                         if (prev) {
2808                                 prev->next = cur->next;
2809                                 if (prev->next)
2810                                         prev->next->prev = prev;
2811                                 else
2812                                         ifend = prev;
2813                         } else {
2814                                 iflist = cur->next;
2815                                 if (iflist)
2816                                         iflist->prev = NULL;
2817                                 else
2818                                         ifend = NULL;
2819                         }
2820                         if (cur->subs[SUB_REAL].dfd > -1) {
2821                                 dahdi_close(cur->subs[SUB_REAL].dfd);
2822                         }
2823                         destroy_dahdi_pvt(&cur);
2824                 }
2825         } else {
2826                 if (prev) {
2827                         prev->next = cur->next;
2828                         if (prev->next)
2829                                 prev->next->prev = prev;
2830                         else
2831                                 ifend = prev;
2832                 } else {
2833                         iflist = cur->next;
2834                         if (iflist)
2835                                 iflist->prev = NULL;
2836                         else
2837                                 ifend = NULL;
2838                 }
2839                 if (cur->subs[SUB_REAL].dfd > -1) {
2840                         dahdi_close(cur->subs[SUB_REAL].dfd);
2841                 }
2842                 destroy_dahdi_pvt(&cur);
2843         }
2844         return 0;
2845 }
2846
2847 static void destroy_all_channels(void)
2848 {
2849         int x;
2850         struct dahdi_pvt *p, *pl;
2851
2852         while (num_restart_pending) {
2853                 usleep(1);
2854         }
2855
2856         ast_mutex_lock(&iflock);
2857         /* Destroy all the interfaces and free their memory */
2858         p = iflist;
2859         while (p) {
2860                 /* Free any callerid */
2861                 if (p->cidspill)
2862                         ast_free(p->cidspill);
2863                 /* Close the DAHDI thingy */
2864                 if (p->subs[SUB_REAL].dfd > -1)
2865                         dahdi_close(p->subs[SUB_REAL].dfd);
2866                 pl = p;
2867                 p = p->next;
2868                 x = pl->channel;
2869                 /* Free associated memory */
2870                 if (pl)
2871                         destroy_dahdi_pvt(&pl);
2872                 if (option_verbose > 2) 
2873                         ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x);
2874         }
2875         iflist = NULL;
2876         ifcount = 0;
2877         ast_mutex_unlock(&iflock);
2878 }
2879
2880 #ifdef HAVE_PRI
2881 static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
2882
2883 static char *dahdi_send_keypad_facility_synopsis = "Send digits out of band over a PRI";
2884
2885 static char *dahdi_send_keypad_facility_descrip = 
2886 "  DAHDISendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
2887 "  IE over the current channel.\n";
2888
2889 static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, void *data)
2890 {
2891         /* Data will be our digit string */
2892         struct dahdi_pvt *p;
2893         char *digits = (char *) data;
2894
2895         if (ast_strlen_zero(digits)) {
2896                 ast_debug(1, "No digit string sent to application!\n");
2897                 return -1;
2898         }
2899
2900         p = (struct dahdi_pvt *)chan->tech_pvt;
2901
2902         if (!p) {
2903                 ast_debug(1, "Unable to find technology private\n");
2904                 return -1;
2905         }
2906
2907         ast_mutex_lock(&p->lock);
2908
2909         if (!p->pri || !p->call) {
2910                 ast_debug(1, "Unable to find pri or call on channel!\n");
2911                 ast_mutex_unlock(&p->lock);
2912                 return -1;
2913         }
2914
2915         if (!pri_grab(p, p->pri)) {
2916                 pri_keypad_facility(p->pri->pri, p->call, digits);
2917                 pri_rel(p->pri);
2918         } else {
2919                 ast_debug(1, "Unable to grab pri to send keypad facility!\n");
2920                 ast_mutex_unlock(&p->lock);
2921                 return -1;
2922         }
2923
2924         ast_mutex_unlock(&p->lock);
2925
2926         return 0;
2927 }
2928
2929 static int pri_is_up(struct dahdi_pri *pri)
2930 {
2931         int x;
2932         for (x = 0; x < NUM_DCHANS; x++) {
2933                 if (pri->dchanavail[x] == DCHAN_AVAILABLE)
2934                         return 1;
2935         }
2936         return 0;
2937 }
2938
2939 static int pri_assign_bearer(struct dahdi_pvt *crv, struct dahdi_pri *pri, struct dahdi_pvt *bearer)
2940 {
2941         bearer->owner = &inuse;
2942         bearer->realcall = crv;
2943         crv->subs[SUB_REAL].dfd = bearer->subs[SUB_REAL].dfd;
2944         if (crv->subs[SUB_REAL].owner)
2945                 ast_channel_set_fd(crv->subs[SUB_REAL].owner, 0, crv->subs[SUB_REAL].dfd);
2946         crv->bearer = bearer;
2947         crv->call = bearer->call;
2948         crv->pri = pri;
2949         return 0;
2950 }
2951
2952 static char *pri_order(int level)
2953 {
2954         switch (level) {
2955         case 0:
2956                 return "Primary";
2957         case 1:
2958                 return "Secondary";
2959         case 2:
2960                 return "Tertiary";
2961         case 3:
2962                 return "Quaternary";
2963         default:
2964                 return "<Unknown>";
2965         }               
2966 }
2967
2968 /* Returns fd of the active dchan */
2969 static int pri_active_dchan_fd(struct dahdi_pri *pri)
2970 {
2971         int x = -1;
2972
2973         for (x = 0; x < NUM_DCHANS; x++) {
2974                 if ((pri->dchans[x] == pri->pri))
2975                         break;
2976         }
2977
2978         return pri->fds[x];
2979 }
2980
2981 static int pri_find_dchan(struct dahdi_pri *pri)
2982 {
2983         int oldslot = -1;
2984         struct pri *old;
2985         int newslot = -1;
2986         int x;
2987         old = pri->pri;
2988         for (x = 0; x < NUM_DCHANS; x++) {
2989                 if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
2990                         newslot = x;
2991                 if (pri->dchans[x] == old) {
2992                         oldslot = x;
2993                 }
2994         }
2995         if (newslot < 0) {
2996                 newslot = 0;
2997                 ast_log(LOG_WARNING, "No D-channels available!  Using Primary channel %d as D-channel anyway!\n",
2998                         pri->dchannels[newslot]);
2999         }
3000         if (old && (oldslot != newslot))
3001                 ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
3002                         pri->dchannels[oldslot], pri->dchannels[newslot]);
3003         pri->pri = pri->dchans[newslot];
3004         return 0;
3005 }
3006 #endif
3007
3008 static int dahdi_hangup(struct ast_channel *ast)
3009 {
3010         int res;
3011         int idx,x, law;
3012         /*static int restore_gains(struct dahdi_pvt *p);*/
3013         struct dahdi_pvt *p = ast->tech_pvt;
3014         struct dahdi_pvt *tmp = NULL;
3015         struct dahdi_pvt *prev = NULL;
3016         struct dahdi_params par;
3017
3018         ast_debug(1, "dahdi_hangup(%s)\n", ast->name);
3019         if (!ast->tech_pvt) {
3020                 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
3021                 return 0;
3022         }
3023         
3024         ast_mutex_lock(&p->lock);
3025         
3026         idx = dahdi_get_index(ast, p, 1);
3027
3028         if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
3029                 x = 1;
3030                 ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
3031         }
3032
3033         x = 0;
3034         dahdi_confmute(p, 0);
3035         p->muting = 0;
3036         restore_gains(p);
3037         if (p->origcid_num) {
3038                 ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
3039                 ast_free(p->origcid_num);
3040                 p->origcid_num = NULL;
3041         }       
3042         if (p->origcid_name) {
3043                 ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
3044                 ast_free(p->origcid_name);
3045                 p->origcid_name = NULL;
3046         }       
3047         if (p->dsp)
3048                 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
3049         if (p->exten)
3050                 p->exten[0] = '\0';
3051
3052         ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
3053                 p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
3054         p->ignoredtmf = 0;
3055         
3056         if (idx > -1) {
3057                 /* Real channel, do some fixup */
3058                 p->subs[idx].owner = NULL;
3059                 p->subs[idx].needanswer = 0;
3060                 p->subs[idx].needflash = 0;
3061                 p->subs[idx].needringing = 0;
3062                 p->subs[idx].needbusy = 0;
3063                 p->subs[idx].needcongestion = 0;
3064                 p->subs[idx].linear = 0;
3065                 p->subs[idx].needcallerid = 0;
3066                 p->polarity = POLARITY_IDLE;
3067                 dahdi_setlinear(p->subs[idx].dfd, 0);
3068                 if (idx == SUB_REAL) {
3069                         if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
3070                                 ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
3071                                 if (p->subs[SUB_CALLWAIT].inthreeway) {
3072                                         /* We had flipped over to answer a callwait and now it's gone */
3073                                         ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
3074                                         /* Move to the call-wait, but un-own us until they flip back. */
3075                                         swap_subs(p, SUB_CALLWAIT, SUB_REAL);
3076                                         unalloc_sub(p, SUB_CALLWAIT);
3077                                         p->owner = NULL;
3078                                 } else {
3079                                         /* The three way hung up, but we still have a call wait */
3080                                         ast_debug(1, "We were in the threeway and have a callwait still.  Ditching the threeway.\n");
3081                                         swap_subs(p, SUB_THREEWAY, SUB_REAL);
3082                                         unalloc_sub(p, SUB_THREEWAY);
3083                                         if (p->subs[SUB_REAL].inthreeway) {
3084                                                 /* This was part of a three way call.  Immediately make way for
3085                                                    another call */
3086                                                 ast_debug(1, "Call was complete, setting owner to former third call\n");
3087                                                 p->owner = p->subs[SUB_REAL].owner;
3088                                         } else {
3089                                                 /* This call hasn't been completed yet...  Set owner to NULL */
3090                                                 ast_debug(1, "Call was incomplete, setting owner to NULL\n");
3091                                                 p->owner = NULL;
3092                                         }
3093                                         p->subs[SUB_REAL].inthreeway = 0;
3094                                 }
3095                         } else if (p->subs[SUB_CALLWAIT].dfd > -1) {
3096                                 /* Move to the call-wait and switch back to them. */
3097                                 swap_subs(p, SUB_CALLWAIT, SUB_REAL);
3098                                 unalloc_sub(p, SUB_CALLWAIT);
3099                                 p->owner = p->subs[SUB_REAL].owner;
3100                                 if (p->owner->_state != AST_STATE_UP)
3101                                         p->subs[SUB_REAL].needanswer = 1;
3102                                 if (ast_bridged_channel(p->subs[SUB_REAL].owner))
3103                                         ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
3104                         } else if (p->subs[SUB_THREEWAY].dfd > -1) {
3105                                 swap_subs(p, SUB_THREEWAY, SUB_REAL);
3106                                 unalloc_sub(p, SUB_THREEWAY);
3107                                 if (p->subs[SUB_REAL].inthreeway) {
3108                                         /* This was part of a three way call.  Immediately make way for
3109                                            another call */
3110                                         ast_debug(1, "Call was complete, setting owner to former third call\n");
3111                                         p->owner = p->subs[SUB_REAL].owner;
3112                                 } else {
3113                                         /* This call hasn't been completed yet...  Set owner to NULL */
3114                                         ast_debug(1, "Call was incomplete, setting owner to NULL\n");
3115                                         p->owner = NULL;
3116                                 }
3117                                 p->subs[SUB_REAL].inthreeway = 0;
3118                         }
3119                 } else if (idx == SUB_CALLWAIT) {
3120                         /* Ditch the holding callwait call, and immediately make it availabe */
3121                         if (p->subs[SUB_CALLWAIT].inthreeway) {
3122                                 /* This is actually part of a three way, placed on hold.  Place the third part
3123                                    on music on hold now */
3124                                 if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
3125                                         ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD, 
3126                                                 S_OR(p->mohsuggest, NULL),
3127                                                 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
3128                                 }
3129                                 p->subs[SUB_THREEWAY].inthreeway = 0;
3130                                 /* Make it the call wait now */
3131                                 swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
3132                                 unalloc_sub(p, SUB_THREEWAY);
3133                         } else
3134                                 unalloc_sub(p, SUB_CALLWAIT);
3135                 } else if (idx == SUB_THREEWAY) {
3136                         if (p->subs[SUB_CALLWAIT].inthreeway) {
3137                                 /* The other party of the three way call is currently in a call-wait state.
3138                                    Start music on hold for them, and take the main guy out of the third call */
3139                                 if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
3140                                         ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD, 
3141                                                 S_OR(p->mohsuggest, NULL),
3142                                                 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
3143                                 }
3144                                 p->subs[SUB_CALLWAIT].inthreeway = 0;
3145                         }
3146                         p->subs[SUB_REAL].inthreeway = 0;
3147                         /* If this was part of a three way call index, let us make
3148                            another three way call */
3149                         unalloc_sub(p, SUB_THREEWAY);
3150                 } else {
3151                         /* This wasn't any sort of call, but how are we an index? */
3152                         ast_log(LOG_WARNING, "Index found but not any type of call?\n");
3153                 }
3154         }
3155
3156         if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
3157                 p->owner = NULL;
3158                 p->ringt = 0;
3159                 p->distinctivering = 0;
3160                 p->confirmanswer = 0;
3161                 p->cidrings = 1;
3162                 p->outgoing = 0;
3163                 p->digital = 0;
3164                 p->faxhandled = 0;
3165                 p->pulsedial = 0;
3166                 p->onhooktime = time(NULL);
3167 #if defined(HAVE_PRI) || defined(HAVE_SS7)
3168                 p->proceeding = 0;
3169                 p->progress = 0;
3170                 p->alerting = 0;
3171                 p->setup_ack = 0;
3172                 p->rlt = 0;
3173 #endif          
3174                 if (p->dsp) {
3175                         ast_dsp_free(p->dsp);
3176                         p->dsp = NULL;
3177                 }
3178
3179                 law = DAHDI_LAW_DEFAULT;
3180                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
3181                 if (res < 0) 
3182                         ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
3183                 /* Perform low level hangup if no owner left */
3184 #ifdef HAVE_SS7
3185                 if (p->ss7) {
3186                         if (p->ss7call) {
3187                                 if (!ss7_grab(p, p->ss7)) {
3188                                         if (!p->alreadyhungup) {
3189                                                 const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
3190                                                 int icause = ast->hangupcause ? ast->hangupcause : -1;
3191
3192                                                 if (cause) {
3193                                                         if (atoi(cause))
3194                                                                 icause = atoi(cause);
3195                                                 }
3196                                                 isup_rel(p->ss7->ss7, p->ss7call, icause);
3197                                                 ss7_rel(p->ss7);
3198                                                 p->alreadyhungup = 1;
3199                                         } else
3200                                                 ast_log(LOG_WARNING, "Trying to hangup twice!\n");
3201                                 } else {
3202                                         ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic);
3203                                         res = -1;
3204                                 }
3205                         }
3206                 }
3207 #endif
3208 #ifdef HAVE_PRI
3209                 if (p->pri) {
3210 #ifdef SUPPORT_USERUSER
3211                         const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
3212 #endif
3213
3214                         /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
3215                         if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
3216                                 if (!pri_grab(p, p->pri)) {
3217                                         if (p->alreadyhungup) {
3218                                                 ast_debug(1, "Already hungup...  Calling hangup once, and clearing call\n");
3219
3220 #ifdef SUPPORT_USERUSER
3221                                                 pri_call_set_useruser(p->call, useruser);
3222 #endif
3223
3224                                                 pri_hangup(p->pri->pri, p->call, -1);
3225                                                 p->call = NULL;
3226                                                 if (p->bearer) 
3227                                                         p->bearer->call = NULL;
3228                                         } else {
3229                                                 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
3230                                                 int icause = ast->hangupcause ? ast->hangupcause : -1;
3231                                                 ast_debug(1, "Not yet hungup...  Calling hangup once with icause, and clearing call\n");
3232
3233 #ifdef SUPPORT_USERUSER
3234                                                 pri_call_set_useruser(p->call, useruser);
3235 #endif
3236
3237                                                 p->alreadyhungup = 1;
3238                                                 if (p->bearer)
3239                                                         p->bearer->alreadyhungup = 1;
3240                                                 if (cause) {
3241                                                         if (atoi(cause))
3242                                                                 icause = atoi(cause);
3243                                                 }
3244                                                 pri_hangup(p->pri->pri, p->call, icause);
3245                                         }
3246                                         if (res < 0) 
3247                                                 ast_log(LOG_WARNING, "pri_disconnect failed\n");
3248                                         pri_rel(p->pri);                        
3249                                 } else {
3250                                         ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
3251                                         res = -1;
3252                                 }
3253                         } else {
3254                                 if (p->bearer)
3255                                         ast_debug(1, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
3256                                 p->call = NULL;
3257                                 res = 0;
3258                         }
3259                 }
3260 #endif
3261                 if (p->sig && ((p->sig != SIG_PRI) && (p->sig != SIG_SS7) && (p->sig != SIG_BRI) && (p->sig != SIG_BRI_PTMP)))
3262                         res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
3263                 if (res < 0) {
3264                         ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
3265                 }
3266                 switch (p->sig) {
3267                 case SIG_FXOGS:
3268                 case SIG_FXOLS:
3269                 case SIG_FXOKS:
3270                         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
3271                         if (!res) {
3272 #if 0
3273                                 ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
3274 #endif
3275                                 /* If they're off hook, try playing congestion */
3276                                 if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
3277                                         tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
3278                                 else
3279                                         tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
3280                         }
3281                         break;
3282                 case SIG_FXSGS:
3283                 case SIG_FXSLS:
3284                 case SIG_FXSKS:
3285                         /* Make sure we're not made available for at least two seconds assuming
3286                            we were actually used for an inbound or outbound call. */
3287                         if (ast->_state != AST_STATE_RESERVED) {
3288                                 time(&p->guardtime);
3289                                 p->guardtime += 2;
3290                         }
3291                         break;
3292                 default:
3293                         tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
3294                 }
3295                 if (p->cidspill)
3296                         ast_free(p->cidspill);
3297                 if (p->sig)
3298                         dahdi_disable_ec(p);
3299                 x = 0;
3300                 ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
3301                 ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
3302                 p->didtdd = 0;
3303                 p->cidspill = NULL;
3304                 p->callwaitcas = 0;
3305                 p->callwaiting = p->permcallwaiting;
3306                 p->hidecallerid = p->permhidecallerid;
3307                 p->dialing = 0;
3308                 p->rdnis[0] = '\0';
3309                 update_conf(p);
3310                 reset_conf(p);
3311                 /* Restore data mode */
3312                 if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
3313                         x = 0;
3314                         ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
3315                 }
3316 #ifdef HAVE_PRI
3317                 if (p->bearer) {
3318                         ast_debug(1, "Freeing up bearer channel %d\n", p->bearer->channel);
3319                         /* Free up the bearer channel as well, and
3320                            don't use its file descriptor anymore */
3321                         update_conf(p->bearer);
3322                         reset_conf(p->bearer);
3323                         p->bearer->owner = NULL;
3324                         p->bearer->realcall = NULL;
3325                         p->bearer = NULL;
3326                         p->subs[SUB_REAL].dfd = -1;
3327                         p->pri = NULL;
3328                 }
3329 #endif
3330                 if (num_restart_pending == 0)
3331                         restart_monitor();
3332         }
3333
3334         p->callwaitingrepeat = 0;
3335         p->cidcwexpire = 0;
3336         p->oprmode = 0;
3337         ast->tech_pvt = NULL;
3338         ast_mutex_unlock(&p->lock);
3339         ast_module_unref(ast_module_info->self);
3340         ast_verb(3, "Hungup '%s'\n", ast->name);
3341
3342         ast_mutex_lock(&iflock);
3343
3344         if (p->restartpending) {
3345                 num_restart_pending--;
3346         }
3347
3348         tmp = iflist;
3349         prev = NULL;
3350         if (p->destroy) {
3351                 while (tmp) {
3352                         if (tmp == p) {
3353                                 destroy_channel(prev, tmp, 0);
3354                                 break;
3355                         } else {
3356                                 prev = tmp;
3357                                 tmp = tmp->next;
3358                         }
3359                 }
3360         }
3361         ast_mutex_unlock(&iflock);
3362         return 0;
3363 }
3364
3365 static int dahdi_answer(struct ast_channel *ast)
3366 {
3367         struct dahdi_pvt *p = ast->tech_pvt;
3368         int res = 0;
3369         int idx;
3370         int oldstate = ast->_state;
3371         ast_setstate(ast, AST_STATE_UP);
3372         ast_mutex_lock(&p->lock);
3373         idx = dahdi_get_index(ast, p, 0);
3374         if (idx < 0)
3375                 idx = SUB_REAL;
3376         /* nothing to do if a radio channel */
3377         if ((p->radio || (p->oprmode < 0))) {
3378                 ast_mutex_unlock(&p->lock);
3379                 return 0;
3380         }
3381         switch (p->sig) {
3382         case SIG_FXSLS:
3383         case SIG_FXSGS:
3384         case SIG_FXSKS:
3385                 p->ringt = 0;
3386                 /* Fall through */
3387         case SIG_EM:
3388         case SIG_EM_E1:
3389         case SIG_EMWINK:
3390         case SIG_FEATD:
3391         case SIG_FEATDMF:
3392         case SIG_FEATDMF_TA:
3393         case SIG_E911:
3394         case SIG_FGC_CAMA:
3395         case SIG_FGC_CAMAMF:
3396         case SIG_FEATB:
3397         case SIG_SF:
3398         case SIG_SFWINK:
3399         case SIG_SF_FEATD:
3400         case SIG_SF_FEATDMF:
3401         case SIG_SF_FEATB:
3402         case SIG_FXOLS:
3403         case SIG_FXOGS:
3404         case SIG_FXOKS:
3405                 /* Pick up the line */
3406                 ast_debug(1, "Took %s off hook\n", ast->name);
3407                 if (p->hanguponpolarityswitch) {
3408                         p->polaritydelaytv = ast_tvnow();
3409                 }
3410                 res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
3411                 tone_zone_play_tone(p->subs[idx].dfd, -1);
3412                 p->dialing = 0;