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