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