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