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