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