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