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