Some chan_dahdi protected function renaming.
[asterisk/asterisk.git] / channels / chan_dahdi.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, 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  * \ingroup channel_drivers
33  *
34  * \todo Deprecate the "musiconhold" configuration option post 1.4
35  */
36
37 /*! \li \ref chan_dahdi.c uses the configuration file \ref chan_dahdi.conf
38  * \addtogroup configuration_file
39  */
40
41 /*! \page chan_dahdi.conf chan_dahdi.conf
42  * \verbinclude chan_dahdi.conf.sample
43  */
44
45 /*** MODULEINFO
46         <use type="module">res_smdi</use>
47         <depend>dahdi</depend>
48         <depend>tonezone</depend>
49         <use type="external">pri</use>
50         <use type="external">ss7</use>
51         <use type="external">openr2</use>
52         <support_level>core</support_level>
53  ***/
54
55 #include "asterisk.h"
56
57 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
58
59 #if defined(__NetBSD__) || defined(__FreeBSD__)
60 #include <pthread.h>
61 #include <signal.h>
62 #else
63 #include <sys/signal.h>
64 #endif
65 #include <math.h>
66
67 #include "sig_analog.h"
68 /* Analog signaling is currently still present in chan_dahdi for use with
69  * radio. Sig_analog does not currently handle any radio operations. If
70  * radio only uses analog signaling, then the radio handling logic could
71  * be placed in sig_analog and the duplicated code could be removed.
72  */
73
74 #if defined(HAVE_PRI)
75 #include "sig_pri.h"
76 #ifndef PRI_RESTART
77 #error "Upgrade your libpri"
78 #endif
79 #endif  /* defined(HAVE_PRI) */
80
81 #if defined(HAVE_SS7)
82 #include "sig_ss7.h"
83 #if defined(LIBSS7_ABI_COMPATIBILITY)
84 #error "Your installed libss7 is not compatible"
85 #endif
86 #endif  /* defined(HAVE_SS7) */
87
88 #if defined(HAVE_OPENR2)
89 /* put this here until sig_mfcr2 comes along */
90 #define SIG_MFCR2_MAX_CHANNELS  672             /*!< No more than a DS3 per trunk group */
91 #endif  /* defined(HAVE_OPENR2) */
92
93 #include "asterisk/lock.h"
94 #include "asterisk/channel.h"
95 #include "asterisk/config.h"
96 #include "asterisk/module.h"
97 #include "asterisk/pbx.h"
98 #include "asterisk/file.h"
99 #include "asterisk/ulaw.h"
100 #include "asterisk/alaw.h"
101 #include "asterisk/callerid.h"
102 #include "asterisk/adsi.h"
103 #include "asterisk/cli.h"
104 #include "asterisk/features.h"
105 #include "asterisk/musiconhold.h"
106 #include "asterisk/say.h"
107 #include "asterisk/tdd.h"
108 #include "asterisk/app.h"
109 #include "asterisk/dsp.h"
110 #include "asterisk/astdb.h"
111 #include "asterisk/manager.h"
112 #include "asterisk/causes.h"
113 #include "asterisk/term.h"
114 #include "asterisk/utils.h"
115 #include "asterisk/transcap.h"
116 #include "asterisk/stringfields.h"
117 #include "asterisk/abstract_jb.h"
118 #include "asterisk/smdi.h"
119 #include "asterisk/astobj.h"
120 #include "asterisk/event.h"
121 #include "asterisk/devicestate.h"
122 #include "asterisk/paths.h"
123 #include "asterisk/ccss.h"
124 #include "asterisk/data.h"
125 #include "asterisk/features_config.h"
126 #include "asterisk/bridging.h"
127 #include "asterisk/stasis_channels.h"
128 #include "chan_dahdi.h"
129 #include "dahdi/bridge_native_dahdi.h"
130
131 /*** DOCUMENTATION
132         <application name="DAHDISendKeypadFacility" language="en_US">
133                 <synopsis>
134                         Send digits out of band over a PRI.
135                 </synopsis>
136                 <syntax>
137                         <parameter name="digits" required="true" />
138                 </syntax>
139                 <description>
140                         <para>This application will send the given string of digits in a Keypad
141                         Facility IE over the current channel.</para>
142                 </description>
143         </application>
144         <application name="DAHDISendCallreroutingFacility" language="en_US">
145                 <synopsis>
146                         Send an ISDN call rerouting/deflection facility message.
147                 </synopsis>
148                 <syntax argsep=",">
149                         <parameter name="destination" required="true">
150                                 <para>Destination number.</para>
151                         </parameter>
152                         <parameter name="original">
153                                 <para>Original called number.</para>
154                         </parameter>
155                         <parameter name="reason">
156                                 <para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
157                         </parameter>
158                 </syntax>
159                 <description>
160                         <para>This application will send an ISDN switch specific call
161                         rerouting/deflection facility message over the current channel.
162                         Supported switches depend upon the version of libpri in use.</para>
163                 </description>
164         </application>
165         <application name="DAHDIAcceptR2Call" language="en_US">
166                 <synopsis>
167                         Accept an R2 call if its not already accepted (you still need to answer it)
168                 </synopsis>
169                 <syntax>
170                         <parameter name="charge" required="true">
171                                 <para>Yes or No.</para>
172                                 <para>Whether you want to accept the call with charge or without charge.</para>
173                         </parameter>
174                 </syntax>
175                 <description>
176                         <para>This application will Accept the R2 call either with charge or no charge.</para>
177                 </description>
178         </application>
179         <manager name="DAHDITransfer" language="en_US">
180                 <synopsis>
181                         Transfer DAHDI Channel.
182                 </synopsis>
183                 <syntax>
184                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
185                         <parameter name="DAHDIChannel" required="true">
186                                 <para>DAHDI channel number to transfer.</para>
187                         </parameter>
188                 </syntax>
189                 <description>
190                         <para>Simulate a flash hook event by the user connected to the channel.</para>
191                         <note><para>Valid only for analog channels.</para></note>
192                 </description>
193         </manager>
194         <manager name="DAHDIHangup" language="en_US">
195                 <synopsis>
196                         Hangup DAHDI Channel.
197                 </synopsis>
198                 <syntax>
199                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
200                         <parameter name="DAHDIChannel" required="true">
201                                 <para>DAHDI channel number to hangup.</para>
202                         </parameter>
203                 </syntax>
204                 <description>
205                         <para>Simulate an on-hook event by the user connected to the channel.</para>
206                         <note><para>Valid only for analog channels.</para></note>
207                 </description>
208         </manager>
209         <manager name="DAHDIDialOffhook" language="en_US">
210                 <synopsis>
211                         Dial over DAHDI channel while offhook.
212                 </synopsis>
213                 <syntax>
214                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
215                         <parameter name="DAHDIChannel" required="true">
216                                 <para>DAHDI channel number to dial digits.</para>
217                         </parameter>
218                         <parameter name="Number" required="true">
219                                 <para>Digits to dial.</para>
220                         </parameter>
221                 </syntax>
222                 <description>
223                         <para>Generate DTMF control frames to the bridged peer.</para>
224                 </description>
225         </manager>
226         <manager name="DAHDIDNDon" language="en_US">
227                 <synopsis>
228                         Toggle DAHDI channel Do Not Disturb status ON.
229                 </synopsis>
230                 <syntax>
231                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
232                         <parameter name="DAHDIChannel" required="true">
233                                 <para>DAHDI channel number to set DND on.</para>
234                         </parameter>
235                 </syntax>
236                 <description>
237                         <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
238                         <note><para>Feature only supported by analog channels.</para></note>
239                 </description>
240         </manager>
241         <manager name="DAHDIDNDoff" language="en_US">
242                 <synopsis>
243                         Toggle DAHDI channel Do Not Disturb status OFF.
244                 </synopsis>
245                 <syntax>
246                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
247                         <parameter name="DAHDIChannel" required="true">
248                                 <para>DAHDI channel number to set DND off.</para>
249                         </parameter>
250                 </syntax>
251                 <description>
252                         <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
253                         <note><para>Feature only supported by analog channels.</para></note>
254                 </description>
255         </manager>
256         <manager name="DAHDIShowChannels" language="en_US">
257                 <synopsis>
258                         Show status of DAHDI channels.
259                 </synopsis>
260                 <syntax>
261                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
262                         <parameter name="DAHDIChannel">
263                                 <para>Specify the specific channel number to show.  Show all channels if zero or not present.</para>
264                         </parameter>
265                 </syntax>
266                 <description>
267                         <para>Similar to the CLI command "dahdi show channels".</para>
268                 </description>
269         </manager>
270         <manager name="DAHDIRestart" language="en_US">
271                 <synopsis>
272                         Fully Restart DAHDI channels (terminates calls).
273                 </synopsis>
274                 <syntax>
275                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
276                 </syntax>
277                 <description>
278                         <para>Equivalent to the CLI command "dahdi restart".</para>
279                 </description>
280         </manager>
281         <manager name="PRIShowSpans" language="en_US">
282                 <synopsis>
283                         Show status of PRI spans.
284                 </synopsis>
285                 <syntax>
286                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
287                         <parameter name="Span">
288                                 <para>Specify the specific span to show.  Show all spans if zero or not present.</para>
289                         </parameter>
290                 </syntax>
291                 <description>
292                         <para>Similar to the CLI command "pri show spans".</para>
293                 </description>
294         </manager>
295         <managerEvent language="en_US" name="AlarmClear">
296                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
297                         <synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
298                         <syntax>
299                                 <parameter name="DAHDIChannel">
300                                         <para>The DAHDI channel on which the alarm was cleared.</para>
301                                         <note><para>This is not an Asterisk channel identifier.</para></note>
302                                 </parameter>
303                         </syntax>
304                 </managerEventInstance>
305         </managerEvent>
306         <managerEvent language="en_US" name="SpanAlarmClear">
307                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
308                         <synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
309                         <syntax>
310                                 <parameter name="Span">
311                                         <para>The span on which the alarm was cleared.</para>
312                                 </parameter>
313                         </syntax>
314                 </managerEventInstance>
315         </managerEvent>
316         <managerEvent language="en_US" name="DNDState">
317                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
318                         <synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
319                         <syntax>
320                                 <parameter name="DAHDIChannel">
321                                         <para>The DAHDI channel on which DND status changed.</para>
322                                         <note><para>This is not an Asterisk channel identifier.</para></note>
323                                 </parameter>
324                                 <parameter name="Status">
325                                         <enumlist>
326                                                 <enum name="enabled"/>
327                                                 <enum name="disabled"/>
328                                         </enumlist>
329                                 </parameter>
330                         </syntax>
331                 </managerEventInstance>
332         </managerEvent>
333         <managerEvent language="en_US" name="Alarm">
334                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
335                         <synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
336                         <syntax>
337                                 <parameter name="DAHDIChannel">
338                                         <para>The channel on which the alarm occurred.</para>
339                                         <note><para>This is not an Asterisk channel identifier.</para></note>
340                                 </parameter>
341                                 <parameter name="Alarm">
342                                         <para>A textual description of the alarm that occurred.</para>
343                                 </parameter>
344                         </syntax>
345                 </managerEventInstance>
346         </managerEvent>
347         <managerEvent language="en_US" name="SpanAlarm">
348                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
349                         <synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
350                         <syntax>
351                                 <parameter name="Span">
352                                         <para>The span on which the alarm occurred.</para>
353                                 </parameter>
354                                 <parameter name="Alarm">
355                                         <para>A textual description of the alarm that occurred.</para>
356                                 </parameter>
357                         </syntax>
358                 </managerEventInstance>
359         </managerEvent>
360         <managerEvent language="en_US" name="DAHDIChannel">
361                 <managerEventInstance class="EVENT_FLAG_CALL">
362                         <synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
363                         <syntax>
364                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
365                                 <parameter name="DAHDISpan">
366                                         <para>The DAHDI span associated with this channel.</para>
367                                 </parameter>
368                                 <parameter name="DAHDIChannel">
369                                         <para>The DAHDI channel associated with this channel.</para>
370                                 </parameter>
371                         </syntax>
372                 </managerEventInstance>
373         </managerEvent>
374  ***/
375
376 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
377
378 static const char * const lbostr[] = {
379 "0 db (CSU)/0-133 feet (DSX-1)",
380 "133-266 feet (DSX-1)",
381 "266-399 feet (DSX-1)",
382 "399-533 feet (DSX-1)",
383 "533-655 feet (DSX-1)",
384 "-7.5db (CSU)",
385 "-15db (CSU)",
386 "-22.5db (CSU)"
387 };
388
389 /*! Global jitterbuffer configuration - by default, jb is disabled
390  *  \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
391 static struct ast_jb_conf default_jbconf =
392 {
393         .flags = 0,
394         .max_size = 200,
395         .resync_threshold = 1000,
396         .impl = "fixed",
397         .target_extra = 40,
398 };
399 static struct ast_jb_conf global_jbconf;
400
401 /*!
402  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
403  * the user hangs up to reset the state machine so ring works properly.
404  * This is used to be able to support kewlstart by putting the zhone in
405  * groundstart mode since their forward disconnect supervision is entirely
406  * broken even though their documentation says it isn't and their support
407  * is entirely unwilling to provide any assistance with their channel banks
408  * even though their web site says they support their products for life.
409  */
410 /* #define ZHONE_HACK */
411
412 /*! \brief Typically, how many rings before we should send Caller*ID */
413 #define DEFAULT_CIDRINGS 1
414
415 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
416
417
418 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
419 #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))
420
421 static const char tdesc[] = "DAHDI Telephony"
422 #if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
423         " w/"
424         #if defined(HAVE_PRI)
425                 "PRI"
426         #endif  /* defined(HAVE_PRI) */
427         #if defined(HAVE_SS7)
428                 #if defined(HAVE_PRI)
429                 " & "
430                 #endif  /* defined(HAVE_PRI) */
431                 "SS7"
432         #endif  /* defined(HAVE_SS7) */
433         #if defined(HAVE_OPENR2)
434                 #if defined(HAVE_PRI) || defined(HAVE_SS7)
435                 " & "
436                 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
437                 "MFC/R2"
438         #endif  /* defined(HAVE_OPENR2) */
439 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
440 ;
441
442 static const char config[] = "chan_dahdi.conf";
443
444 #ifdef LOTS_OF_SPANS
445 #define NUM_SPANS       DAHDI_MAX_SPANS
446 #else
447 #define NUM_SPANS               32
448 #endif
449
450 #define CHAN_PSEUDO     -2
451
452 #define CALLPROGRESS_PROGRESS           1
453 #define CALLPROGRESS_FAX_OUTGOING       2
454 #define CALLPROGRESS_FAX_INCOMING       4
455 #define CALLPROGRESS_FAX                (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
456
457 #define NUM_CADENCE_MAX 25
458 static int num_cadence = 4;
459 static int user_has_defined_cadences = 0;
460
461 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
462         { { 125, 125, 2000, 4000 } },                   /*!< Quick chirp followed by normal ring */
463         { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
464         { { 125, 125, 125, 125, 125, 4000 } },  /*!< Three short bursts */
465         { { 1000, 500, 2500, 5000 } },  /*!< Long ring */
466 };
467
468 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
469  * is 1, the second pause is 2 and so on.
470  */
471
472 static int cidrings[NUM_CADENCE_MAX] = {
473         2,                                                                              /*!< Right after first long ring */
474         4,                                                                              /*!< Right after long part */
475         3,                                                                              /*!< After third chirp */
476         2,                                                                              /*!< Second spell */
477 };
478
479 /* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
480 static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
481
482 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
483                         (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
484
485 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
486 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
487
488 static char defaultcic[64] = "";
489 static char defaultozz[64] = "";
490
491 /*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
492 static char mwimonitornotify[PATH_MAX] = "";
493 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI
494 static int  mwisend_rpas = 0;
495 #endif
496
497 static char progzone[10] = "";
498
499 static int usedistinctiveringdetection = 0;
500 static int distinctiveringaftercid = 0;
501
502 static int numbufs = 4;
503
504 static int mwilevel = 512;
505 static int dtmfcid_level = 256;
506
507 #define REPORT_CHANNEL_ALARMS 1
508 #define REPORT_SPAN_ALARMS    2 
509 static int report_alarms = REPORT_CHANNEL_ALARMS;
510
511 #ifdef HAVE_PRI
512 static int pridebugfd = -1;
513 static char pridebugfilename[1024] = "";
514 #endif
515
516 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
517 static int firstdigittimeout = 16000;
518
519 /*! \brief How long to wait for following digits (FXO logic) */
520 static int gendigittimeout = 8000;
521
522 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
523 static int matchdigittimeout = 3000;
524
525 /*! \brief Protect the interface list (of dahdi_pvt's) */
526 AST_MUTEX_DEFINE_STATIC(iflock);
527
528
529 static int ifcount = 0;
530
531 #ifdef HAVE_PRI
532 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
533 #endif
534
535 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
536    when it's doing something critical. */
537 AST_MUTEX_DEFINE_STATIC(monlock);
538
539 /*! \brief This is the thread for the monitor which checks for input on the channels
540    which are not currently in use. */
541 static pthread_t monitor_thread = AST_PTHREADT_NULL;
542 static ast_cond_t ss_thread_complete;
543 AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
544 AST_MUTEX_DEFINE_STATIC(restart_lock);
545 static int ss_thread_count = 0;
546 static int num_restart_pending = 0;
547
548 static int restart_monitor(void);
549
550 static int dahdi_sendtext(struct ast_channel *c, const char *text);
551
552 static void mwi_event_cb(void *userdata, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *msg)
553 {
554         /* This module does not handle MWI in an event-based manner.  However, it
555          * subscribes to MWI for each mailbox that is configured so that the core
556          * knows that we care about it.  Then, chan_dahdi will get the MWI from the
557          * event cache instead of checking the mailbox directly. */
558 }
559
560 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
561 static inline int dahdi_get_event(int fd)
562 {
563         int j;
564         if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
565                 return -1;
566         return j;
567 }
568
569 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
570 static inline int dahdi_wait_event(int fd)
571 {
572         int i, j = 0;
573         i = DAHDI_IOMUX_SIGEVENT;
574         if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
575                 return -1;
576         if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
577                 return -1;
578         return j;
579 }
580
581 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
582 #define READ_SIZE 160
583
584 #define MASK_AVAIL              (1 << 0)        /*!< Channel available for PRI use */
585 #define MASK_INUSE              (1 << 1)        /*!< Channel currently in use */
586
587 #define CALLWAITING_SILENT_SAMPLES              ((300 * 8) / READ_SIZE) /*!< 300 ms */
588 #define CALLWAITING_REPEAT_SAMPLES              ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
589 #define CALLWAITING_SUPPRESS_SAMPLES    ((100 * 8) / READ_SIZE) /*!< 100 ms */
590 #define CIDCW_EXPIRE_SAMPLES                    ((500 * 8) / READ_SIZE) /*!< 500 ms */
591 #define MIN_MS_SINCE_FLASH                              ((2000) )       /*!< 2000 ms */
592 #define DEFAULT_RINGT                                   ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
593 #define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
594
595 /*!
596  * \brief Configured ring timeout base.
597  * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
598  */
599 static int ringt_base = DEFAULT_RINGT;
600
601 #if defined(HAVE_SS7)
602
603 struct dahdi_ss7 {
604         struct sig_ss7_linkset ss7;
605 };
606
607 static struct dahdi_ss7 linksets[NUM_SPANS];
608
609 static int cur_ss7type = -1;
610 static int cur_linkset = -1;
611 static int cur_pointcode = -1;
612 static int cur_cicbeginswith = -1;
613 static int cur_adjpointcode = -1;
614 static int cur_networkindicator = -1;
615 static int cur_defaultdpc = -1;
616 #endif  /* defined(HAVE_SS7) */
617
618 #ifdef HAVE_OPENR2
619 struct dahdi_mfcr2_conf {
620         openr2_variant_t variant;
621         int mfback_timeout;
622         int metering_pulse_timeout;
623         int max_ani;
624         int max_dnis;
625 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
626         int dtmf_time_on;
627         int dtmf_time_off;
628 #endif
629 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
630         int dtmf_end_timeout;
631 #endif
632         signed int get_ani_first:2;
633 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
634         signed int skip_category_request:2;
635 #endif
636         unsigned int call_files:1;
637         unsigned int allow_collect_calls:1;
638         unsigned int charge_calls:1;
639         unsigned int accept_on_offer:1;
640         unsigned int forced_release:1;
641         unsigned int double_answer:1;
642         signed int immediate_accept:2;
643 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
644         signed int dtmf_dialing:2;
645         signed int dtmf_detection:2;
646 #endif
647         char logdir[OR2_MAX_PATH];
648         char r2proto_file[OR2_MAX_PATH];
649         openr2_log_level_t loglevel;
650         openr2_calling_party_category_t category;
651 };
652
653 /* MFC-R2 pseudo-link structure */
654 struct dahdi_mfcr2 {
655         pthread_t r2master;                    /*!< Thread of master */
656         openr2_context_t *protocol_context;    /*!< OpenR2 context handle */
657         struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS];     /*!< Member channel pvt structs */
658         int numchans;                          /*!< Number of channels in this R2 block */
659         struct dahdi_mfcr2_conf conf;         /*!< Configuration used to setup this pseudo-link */
660 };
661
662 /* malloc'd array of malloc'd r2links */
663 static struct dahdi_mfcr2 **r2links;
664 /* how many r2links have been malloc'd */
665 static int r2links_count = 0;
666
667 #endif /* HAVE_OPENR2 */
668
669 #ifdef HAVE_PRI
670
671 struct dahdi_pri {
672         int dchannels[SIG_PRI_NUM_DCHANS];              /*!< What channel are the dchannels on */
673         int mastertrunkgroup;                                   /*!< What trunk group is our master */
674         int prilogicalspan;                                             /*!< Logical span number within trunk group */
675         struct sig_pri_span pri;
676 };
677
678 static struct dahdi_pri pris[NUM_SPANS];
679
680 #if defined(HAVE_PRI_CCSS)
681 /*! DAHDI PRI CCSS agent and monitor type name. */
682 static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
683 #endif  /* defined(HAVE_PRI_CCSS) */
684
685 #else
686 /*! Shut up the compiler */
687 struct dahdi_pri;
688 #endif
689
690 /* Polarity states */
691 #define POLARITY_IDLE   0
692 #define POLARITY_REV    1
693
694 const char * const subnames[] = {
695         "Real",
696         "Callwait",
697         "Threeway"
698 };
699
700 #define DATA_EXPORT_DAHDI_PVT(MEMBER)                                   \
701         MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE)                  \
702         MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE)                      \
703         MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE)                      \
704         MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE)                       \
705         MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE)                       \
706         MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN)                       \
707         MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN)     \
708         MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN)                 \
709         MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN)                 \
710         MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN)                \
711         MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN)        \
712         MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN)             \
713         MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN)                    \
714         MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN)              \
715         MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN)                    \
716         MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN)                     \
717         MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN)                 \
718         MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN)                    \
719         MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN)                    \
720         MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN)                        \
721         MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN)                  \
722         MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN)             \
723         MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN)                  \
724         MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN)                 \
725         MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN)              \
726         MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN)        \
727         MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN)                 \
728         MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN)     \
729         MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN)               \
730         MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN)               \
731         MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN)           \
732         MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN)                 \
733         MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN)                  \
734         MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN)                    \
735         MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN)                       \
736         MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN)                   \
737         MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN)            \
738         MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN)          \
739         MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN)               \
740         MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN)                      \
741         MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN)                  \
742         MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN)             \
743         MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN)                \
744         MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN)            \
745         MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN)                   \
746         MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN)               \
747         MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN)            \
748         MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN)        \
749         MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN)                    \
750         MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN)                     \
751         MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN)                    \
752         MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN)                     \
753         MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN)                    \
754         MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN)                   \
755         MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN)                      \
756         MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN)                          \
757         MEMBER(dahdi_pvt, locallyblocked, AST_DATA_BOOLEAN)                     \
758         MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_BOOLEAN)                    \
759         MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN)                \
760         MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN)                           \
761         MEMBER(dahdi_pvt, context, AST_DATA_STRING)                             \
762         MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING)                          \
763         MEMBER(dahdi_pvt, description, AST_DATA_STRING)                         \
764         MEMBER(dahdi_pvt, exten, AST_DATA_STRING)                               \
765         MEMBER(dahdi_pvt, language, AST_DATA_STRING)                            \
766         MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING)                        \
767         MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING)                          \
768         MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
769
770 AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
771
772 static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
773 static struct dahdi_pvt *ifend = NULL;  /*!< Main interface list end */
774
775 #if defined(HAVE_PRI)
776 static struct dahdi_parms_pseudo {
777         int buf_no;                                     /*!< Number of buffers */
778         int buf_policy;                         /*!< Buffer policy */
779         int faxbuf_no;              /*!< Number of Fax buffers */
780         int faxbuf_policy;          /*!< Fax buffer policy */
781 } dahdi_pseudo_parms;
782 #endif  /* defined(HAVE_PRI) */
783
784 /*! \brief Channel configuration from chan_dahdi.conf .
785  * This struct is used for parsing the [channels] section of chan_dahdi.conf.
786  * Generally there is a field here for every possible configuration item.
787  *
788  * The state of fields is saved along the parsing and whenever a 'channel'
789  * statement is reached, the current dahdi_chan_conf is used to configure the
790  * channel (struct dahdi_pvt)
791  *
792  * \see dahdi_chan_init for the default values.
793  */
794 struct dahdi_chan_conf {
795         struct dahdi_pvt chan;
796 #ifdef HAVE_PRI
797         struct dahdi_pri pri;
798 #endif
799
800 #if defined(HAVE_SS7)
801         struct dahdi_ss7 ss7;
802 #endif  /* defined(HAVE_SS7) */
803
804 #ifdef HAVE_OPENR2
805         struct dahdi_mfcr2_conf mfcr2;
806 #endif
807         struct dahdi_params timing;
808         int is_sig_auto; /*!< Use channel signalling from DAHDI? */
809         /*! Continue configuration even if a channel is not there. */
810         int ignore_failed_channels;
811
812         /*!
813          * \brief The serial port to listen for SMDI data on
814          * \note Set from the "smdiport" string read in from chan_dahdi.conf
815          */
816         char smdi_port[SMDI_MAX_FILENAME_LEN];
817 };
818
819 /*! returns a new dahdi_chan_conf with default values (by-value) */
820 static struct dahdi_chan_conf dahdi_chan_conf_default(void)
821 {
822         /* recall that if a field is not included here it is initialized
823          * to 0 or equivalent
824          */
825         struct dahdi_chan_conf conf = {
826 #ifdef HAVE_PRI
827                 .pri.pri = {
828                         .nsf = PRI_NSF_NONE,
829                         .switchtype = PRI_SWITCH_NI2,
830                         .dialplan = PRI_UNKNOWN + 1,
831                         .localdialplan = PRI_NATIONAL_ISDN + 1,
832                         .nodetype = PRI_CPE,
833                         .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
834
835 #if defined(HAVE_PRI_CCSS)
836                         .cc_ptmp_recall_mode = 1,/* specificRecall */
837                         .cc_qsig_signaling_link_req = 1,/* retain */
838                         .cc_qsig_signaling_link_rsp = 1,/* retain */
839 #endif  /* defined(HAVE_PRI_CCSS) */
840
841                         .minunused = 2,
842                         .idleext = "",
843                         .idledial = "",
844                         .internationalprefix = "",
845                         .nationalprefix = "",
846                         .localprefix = "",
847                         .privateprefix = "",
848                         .unknownprefix = "",
849                         .colp_send = SIG_PRI_COLP_UPDATE,
850                         .resetinterval = -1,
851                 },
852 #endif
853 #if defined(HAVE_SS7)
854                 .ss7.ss7 = {
855                         .called_nai = SS7_NAI_NATIONAL,
856                         .calling_nai = SS7_NAI_NATIONAL,
857                         .internationalprefix = "",
858                         .nationalprefix = "",
859                         .subscriberprefix = "",
860                         .unknownprefix = ""
861                 },
862 #endif  /* defined(HAVE_SS7) */
863 #ifdef HAVE_OPENR2
864                 .mfcr2 = {
865                         .variant = OR2_VAR_ITU,
866                         .mfback_timeout = -1,
867                         .metering_pulse_timeout = -1,
868                         .max_ani = 10,
869                         .max_dnis = 4,
870                         .get_ani_first = -1,
871 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
872                         .skip_category_request = -1,
873 #endif
874                         .call_files = 0,
875                         .allow_collect_calls = 0,
876                         .charge_calls = 1,
877                         .accept_on_offer = 1,
878                         .forced_release = 0,
879                         .double_answer = 0,
880                         .immediate_accept = -1,
881 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
882                         .dtmf_dialing = -1,
883                         .dtmf_detection = -1,
884                         .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
885                         .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
886 #endif
887 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
888                         .dtmf_end_timeout = -1,
889 #endif
890                         .logdir = "",
891                         .r2proto_file = "",
892                         .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
893                         .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
894                 },
895 #endif
896                 .chan = {
897                         .context = "default",
898                         .cid_num = "",
899                         .cid_name = "",
900                         .cid_tag = "",
901                         .mohinterpret = "default",
902                         .mohsuggest = "",
903                         .parkinglot = "",
904                         .transfertobusy = 1,
905
906                         .cid_signalling = CID_SIG_BELL,
907                         .cid_start = CID_START_RING,
908                         .dahditrcallerid = 0,
909                         .use_callerid = 1,
910                         .sig = -1,
911                         .outsigmod = -1,
912
913                         .cid_rxgain = +5.0,
914
915                         .tonezone = -1,
916
917                         .echocancel.head.tap_length = 1,
918
919                         .busycount = 3,
920
921                         .accountcode = "",
922
923                         .mailbox = "",
924
925 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
926                         .mwisend_fsk = 1,
927 #endif
928                         .polarityonanswerdelay = 600,
929
930                         .sendcalleridafter = DEFAULT_CIDRINGS,
931
932                         .buf_policy = DAHDI_POLICY_IMMEDIATE,
933                         .buf_no = numbufs,
934                         .usefaxbuffers = 0,
935                         .cc_params = ast_cc_config_params_init(),
936                 },
937                 .timing = {
938                         .prewinktime = -1,
939                         .preflashtime = -1,
940                         .winktime = -1,
941                         .flashtime = -1,
942                         .starttime = -1,
943                         .rxwinktime = -1,
944                         .rxflashtime = -1,
945                         .debouncetime = -1
946                 },
947                 .is_sig_auto = 1,
948                 .smdi_port = "/dev/ttyS0",
949         };
950
951         return conf;
952 }
953
954
955 static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
956 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
957 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
958 static int dahdi_sendtext(struct ast_channel *c, const char *text);
959 static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout);
960 static int dahdi_hangup(struct ast_channel *ast);
961 static int dahdi_answer(struct ast_channel *ast);
962 static struct ast_frame *dahdi_read(struct ast_channel *ast);
963 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
964 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
965 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
966 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
967 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
968 static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
969 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
970 static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
971 static int dahdi_devicestate(const char *data);
972 static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
973
974 static struct ast_channel_tech dahdi_tech = {
975         .type = "DAHDI",
976         .description = tdesc,
977         .requester = dahdi_request,
978         .send_digit_begin = dahdi_digit_begin,
979         .send_digit_end = dahdi_digit_end,
980         .send_text = dahdi_sendtext,
981         .call = dahdi_call,
982         .hangup = dahdi_hangup,
983         .answer = dahdi_answer,
984         .read = dahdi_read,
985         .write = dahdi_write,
986         .exception = dahdi_exception,
987         .indicate = dahdi_indicate,
988         .fixup = dahdi_fixup,
989         .setoption = dahdi_setoption,
990         .queryoption = dahdi_queryoption,
991         .func_channel_read = dahdi_func_read,
992         .func_channel_write = dahdi_func_write,
993         .devicestate = dahdi_devicestate,
994         .cc_callback = dahdi_cc_callback,
995 };
996
997 #define GET_CHANNEL(p) ((p)->channel)
998
999 static enum analog_sigtype dahdisig_to_analogsig(int sig)
1000 {
1001         switch (sig) {
1002         case SIG_FXOLS:
1003                 return ANALOG_SIG_FXOLS;
1004         case SIG_FXOGS:
1005                 return ANALOG_SIG_FXOGS;
1006         case SIG_FXOKS:
1007                 return ANALOG_SIG_FXOKS;
1008         case SIG_FXSLS:
1009                 return ANALOG_SIG_FXSLS;
1010         case SIG_FXSGS:
1011                 return ANALOG_SIG_FXSGS;
1012         case SIG_FXSKS:
1013                 return ANALOG_SIG_FXSKS;
1014         case SIG_EMWINK:
1015                 return ANALOG_SIG_EMWINK;
1016         case SIG_EM:
1017                 return ANALOG_SIG_EM;
1018         case SIG_EM_E1:
1019                 return ANALOG_SIG_EM_E1;
1020         case SIG_FEATD:
1021                 return ANALOG_SIG_FEATD;
1022         case SIG_FEATDMF:
1023                 return ANALOG_SIG_FEATDMF;
1024         case SIG_E911:
1025                 return SIG_E911;
1026         case SIG_FGC_CAMA:
1027                 return ANALOG_SIG_FGC_CAMA;
1028         case SIG_FGC_CAMAMF:
1029                 return ANALOG_SIG_FGC_CAMAMF;
1030         case SIG_FEATB:
1031                 return ANALOG_SIG_FEATB;
1032         case SIG_SFWINK:
1033                 return ANALOG_SIG_SFWINK;
1034         case SIG_SF:
1035                 return ANALOG_SIG_SF;
1036         case SIG_SF_FEATD:
1037                 return ANALOG_SIG_SF_FEATD;
1038         case SIG_SF_FEATDMF:
1039                 return ANALOG_SIG_SF_FEATDMF;
1040         case SIG_FEATDMF_TA:
1041                 return ANALOG_SIG_FEATDMF_TA;
1042         case SIG_SF_FEATB:
1043                 return ANALOG_SIG_FEATB;
1044         default:
1045                 return -1;
1046         }
1047 }
1048
1049
1050 static int analog_tone_to_dahditone(enum analog_tone tone)
1051 {
1052         switch (tone) {
1053         case ANALOG_TONE_RINGTONE:
1054                 return DAHDI_TONE_RINGTONE;
1055         case ANALOG_TONE_STUTTER:
1056                 return DAHDI_TONE_STUTTER;
1057         case ANALOG_TONE_CONGESTION:
1058                 return DAHDI_TONE_CONGESTION;
1059         case ANALOG_TONE_DIALTONE:
1060                 return DAHDI_TONE_DIALTONE;
1061         case ANALOG_TONE_DIALRECALL:
1062                 return DAHDI_TONE_DIALRECALL;
1063         case ANALOG_TONE_INFO:
1064                 return DAHDI_TONE_INFO;
1065         default:
1066                 return -1;
1067         }
1068 }
1069
1070 static int analogsub_to_dahdisub(enum analog_sub analogsub)
1071 {
1072         int index;
1073
1074         switch (analogsub) {
1075         case ANALOG_SUB_REAL:
1076                 index = SUB_REAL;
1077                 break;
1078         case ANALOG_SUB_CALLWAIT:
1079                 index = SUB_CALLWAIT;
1080                 break;
1081         case ANALOG_SUB_THREEWAY:
1082                 index = SUB_THREEWAY;
1083                 break;
1084         default:
1085                 ast_log(LOG_ERROR, "Unidentified sub!\n");
1086                 index = SUB_REAL;
1087         }
1088
1089         return index;
1090 }
1091
1092 /*!
1093  * \internal
1094  * \brief Send a dial string to DAHDI.
1095  * \since 12.0.0
1096  *
1097  * \param pvt DAHDI private pointer
1098  * \param operation DAHDI dial operation to do to string
1099  * \param dial_str Dial string to send
1100  *
1101  * \retval 0 on success.
1102  * \retval non-zero on error.
1103  */
1104 static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
1105 {
1106         int res;
1107         int offset;
1108         const char *pos;
1109         struct dahdi_dialoperation zo = {
1110                 .op = operation,
1111         };
1112
1113         /* Convert the W's to ww. */
1114         pos = dial_str;
1115         for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) {
1116                 if (!*pos) {
1117                         break;
1118                 }
1119                 if (*pos == 'W') {
1120                         /* Convert 'W' to "ww" */
1121                         ++pos;
1122                         if (offset >= sizeof(zo.dialstr) - 3) {
1123                                 /* No room to expand */
1124                                 break;
1125                         }
1126                         zo.dialstr[offset] = 'w';
1127                         ++offset;
1128                         zo.dialstr[offset] = 'w';
1129                         continue;
1130                 }
1131                 zo.dialstr[offset] = *pos++;
1132         }
1133         /* The zo initialization has already terminated the dialstr. */
1134
1135         ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1136                 pvt->channel, dial_str, zo.dialstr);
1137         res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
1138         if (res) {
1139                 ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
1140                         pvt->channel, dial_str, strerror(errno));
1141         }
1142
1143         return res;
1144 }
1145
1146 static enum analog_event dahdievent_to_analogevent(int event);
1147 static int bump_gains(struct dahdi_pvt *p);
1148 static int dahdi_setlinear(int dfd, int linear);
1149
1150 static int my_start_cid_detect(void *pvt, int cid_signalling)
1151 {
1152         struct dahdi_pvt *p = pvt;
1153         int index = SUB_REAL;
1154         p->cs = callerid_new(cid_signalling);
1155         if (!p->cs) {
1156                 ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1157                 return -1;
1158         }
1159         bump_gains(p);
1160         dahdi_setlinear(p->subs[index].dfd, 0);
1161
1162         return 0;
1163 }
1164
1165 static int my_stop_cid_detect(void *pvt)
1166 {
1167         struct dahdi_pvt *p = pvt;
1168         int index = SUB_REAL;
1169         if (p->cs)
1170                 callerid_free(p->cs);
1171         dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1172         return 0;
1173 }
1174
1175 static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
1176 {
1177         struct dahdi_pvt *p = pvt;
1178         struct analog_pvt *analog_p = p->sig_pvt;
1179         struct pollfd poller;
1180         char *name, *num;
1181         int index = SUB_REAL;
1182         int res;
1183         unsigned char buf[256];
1184         int flags;
1185         struct ast_format tmpfmt;
1186
1187         poller.fd = p->subs[SUB_REAL].dfd;
1188         poller.events = POLLPRI | POLLIN;
1189         poller.revents = 0;
1190
1191         res = poll(&poller, 1, timeout);
1192
1193         if (poller.revents & POLLPRI) {
1194                 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
1195                 return 1;
1196         }
1197
1198         if (poller.revents & POLLIN) {
1199                 /*** NOTES ***/
1200                 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1201                  * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1202                  * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1203                  * a failure and die, and returning 2 means no event was received. */
1204                 res = read(p->subs[index].dfd, buf, sizeof(buf));
1205                 if (res < 0) {
1206                         if (errno != ELAST) {
1207                                 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1208                                 callerid_free(p->cs);
1209                                 return -1;
1210                         }
1211                 }
1212
1213                 if (analog_p->ringt > 0) {
1214                         if (!(--analog_p->ringt)) {
1215                                 /* only return if we timeout from a ring event */
1216                                 return -1;
1217                         }
1218                 }
1219
1220                 if (p->cid_signalling == CID_SIG_V23_JP) {
1221                         res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1222                 } else {
1223                         res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1224                 }
1225                 if (res < 0) {
1226                         /*
1227                          * The previous diagnostic message output likely
1228                          * explains why it failed.
1229                          */
1230                         ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1231                         return -1;
1232                 }
1233
1234                 if (res == 1) {
1235                         callerid_get(p->cs, &name, &num, &flags);
1236                         if (name)
1237                                 ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1238                         if (num)
1239                                 ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1240
1241                         ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1242                         return 0;
1243                 }
1244         }
1245
1246         *ev = ANALOG_EVENT_NONE;
1247         return 2;
1248 }
1249
1250 static const char *event2str(int event);
1251 static int restore_gains(struct dahdi_pvt *p);
1252
1253 static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
1254 {
1255         unsigned char buf[256];
1256         int distMatches;
1257         int curRingData[RING_PATTERNS];
1258         int receivedRingT;
1259         int counter1;
1260         int counter;
1261         int i;
1262         int res;
1263         int checkaftercid = 0;
1264
1265         struct dahdi_pvt *p = pvt;
1266         struct analog_pvt *analog_p = p->sig_pvt;
1267
1268         if (ringdata == NULL) {
1269                 ringdata = curRingData;
1270         } else {
1271                 checkaftercid = 1;
1272         }
1273
1274         /* We must have a ring by now, so, if configured, lets try to listen for
1275          * distinctive ringing */
1276         if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1277                 /* Clear the current ring data array so we don't have old data in it. */
1278                 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1279                         ringdata[receivedRingT] = 0;
1280                 receivedRingT = 0;
1281                 if (checkaftercid && distinctiveringaftercid)
1282                         ast_verb(3, "Detecting post-CID distinctive ring\n");
1283                 /* Check to see if context is what it should be, if not set to be. */
1284                 else if (strcmp(p->context,p->defcontext) != 0) {
1285                         ast_copy_string(p->context, p->defcontext, sizeof(p->context));
1286                         ast_channel_context_set(chan, p->defcontext);
1287                 }
1288
1289                 for (;;) {
1290                         i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1291                         if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
1292                                 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1293                                 ast_hangup(chan);
1294                                 return 1;
1295                         }
1296                         if (i & DAHDI_IOMUX_SIGEVENT) {
1297                                 res = dahdi_get_event(p->subs[idx].dfd);
1298                                 if (res == DAHDI_EVENT_NOALARM) {
1299                                         p->inalarm = 0;
1300                                         analog_p->inalarm = 0;
1301                                 }
1302                                 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
1303                                 res = 0;
1304                                 /* Let us detect distinctive ring */
1305
1306                                 ringdata[receivedRingT] = analog_p->ringt;
1307
1308                                 if (analog_p->ringt < analog_p->ringt_base/2)
1309                                         break;
1310                                 /* Increment the ringT counter so we can match it against
1311                                    values in chan_dahdi.conf for distinctive ring */
1312                                 if (++receivedRingT == RING_PATTERNS)
1313                                         break;
1314                         } else if (i & DAHDI_IOMUX_READ) {
1315                                 res = read(p->subs[idx].dfd, buf, sizeof(buf));
1316                                 if (res < 0) {
1317                                         if (errno != ELAST) {
1318                                                 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1319                                                 ast_hangup(chan);
1320                                                 return 1;
1321                                         }
1322                                         break;
1323                                 }
1324                                 if (analog_p->ringt > 0) {
1325                                         if (!(--analog_p->ringt)) {
1326                                                 res = -1;
1327                                                 break;
1328                                         }
1329                                 }
1330                         }
1331                 }
1332         }
1333         if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
1334                 /* this only shows up if you have n of the dring patterns filled in */
1335                 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
1336                 for (counter = 0; counter < 3; counter++) {
1337                 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1338                         distMatches = 0;
1339                         /* this only shows up if you have n of the dring patterns filled in */
1340                         ast_verb(3, "Checking %d,%d,%d\n",
1341                                         p->drings.ringnum[counter].ring[0],
1342                                         p->drings.ringnum[counter].ring[1],
1343                                         p->drings.ringnum[counter].ring[2]);
1344                         for (counter1 = 0; counter1 < 3; counter1++) {
1345                                 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
1346                                 if (p->drings.ringnum[counter].ring[counter1] == -1) {
1347                                         ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1348                                         ringdata[counter1]);
1349                                         distMatches++;
1350                                 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
1351                                                                                 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
1352                                         ast_verb(3, "Ring pattern matched in range: %d to %d\n",
1353                                         (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
1354                                         (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
1355                                         distMatches++;
1356                                 }
1357                         }
1358
1359                         if (distMatches == 3) {
1360                                 /* The ring matches, set the context to whatever is for distinctive ring.. */
1361                                 ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
1362                                 ast_channel_context_set(chan, S_OR(p->drings.ringContext[counter].contextData, p->defcontext));
1363                                 ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
1364                                 break;
1365                         }
1366                 }
1367         }
1368         /* Restore linear mode (if appropriate) for Caller*ID processing */
1369         dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
1370         restore_gains(p);
1371
1372         return 0;
1373 }
1374
1375 static int my_stop_callwait(void *pvt)
1376 {
1377         struct dahdi_pvt *p = pvt;
1378         p->callwaitingrepeat = 0;
1379         p->cidcwexpire = 0;
1380         p->cid_suppress_expire = 0;
1381
1382         return 0;
1383 }
1384
1385 static int send_callerid(struct dahdi_pvt *p);
1386 static int save_conference(struct dahdi_pvt *p);
1387 static int restore_conference(struct dahdi_pvt *p);
1388
1389 static int my_callwait(void *pvt)
1390 {
1391         struct dahdi_pvt *p = pvt;
1392         struct ast_format tmpfmt;
1393         p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
1394         if (p->cidspill) {
1395                 ast_log(LOG_WARNING, "Spill already exists?!?\n");
1396                 ast_free(p->cidspill);
1397         }
1398
1399         /*
1400          * SAS: Subscriber Alert Signal, 440Hz for 300ms
1401          * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1402          */
1403         if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1404                 return -1;
1405         save_conference(p);
1406         /* Silence */
1407         memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1408         if (!p->callwaitrings && p->callwaitingcallerid) {
1409                 ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1410                 p->callwaitcas = 1;
1411                 p->cidlen = 2400 + 680 + READ_SIZE * 4;
1412         } else {
1413                 ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1414                 p->callwaitcas = 0;
1415                 p->cidlen = 2400 + READ_SIZE * 4;
1416         }
1417         p->cidpos = 0;
1418         send_callerid(p);
1419
1420         return 0;
1421 }
1422
1423 static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
1424 {
1425         struct dahdi_pvt *p = pvt;
1426         struct ast_format tmpfmt;
1427
1428         ast_debug(2, "Starting cid spill\n");
1429
1430         if (p->cidspill) {
1431                 ast_log(LOG_WARNING, "cidspill already exists??\n");
1432                 ast_free(p->cidspill);
1433         }
1434
1435         if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1436                 if (cwcid == 0) {
1437                         p->cidlen = ast_callerid_generate(p->cidspill,
1438                                 caller->id.name.str,
1439                                 caller->id.number.str,
1440                                 ast_format_set(&tmpfmt, AST_LAW(p), 0));
1441                 } else {
1442                         ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n",
1443                                 caller->id.name.str, caller->id.number.str);
1444                         p->callwaitcas = 0;
1445                         p->cidcwexpire = 0;
1446                         p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
1447                                 caller->id.name.str,
1448                                 caller->id.number.str,
1449                                 ast_format_set(&tmpfmt, AST_LAW(p), 0));
1450                         p->cidlen += READ_SIZE * 4;
1451                 }
1452                 p->cidpos = 0;
1453                 p->cid_suppress_expire = 0;
1454                 send_callerid(p);
1455         }
1456         return 0;
1457 }
1458
1459 static int my_dsp_reset_and_flush_digits(void *pvt)
1460 {
1461         struct dahdi_pvt *p = pvt;
1462         if (p->dsp)
1463                 ast_dsp_digitreset(p->dsp);
1464
1465         return 0;
1466 }
1467
1468 static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
1469 {
1470         struct dahdi_pvt *p = pvt;
1471
1472         if (p->channel == CHAN_PSEUDO)
1473                 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
1474
1475         if (mode == ANALOG_DIGITMODE_DTMF) {
1476                 /* If we do hardware dtmf, no need for a DSP */
1477                 if (p->hardwaredtmf) {
1478                         if (p->dsp) {
1479                                 ast_dsp_free(p->dsp);
1480                                 p->dsp = NULL;
1481                         }
1482                         return 0;
1483                 }
1484
1485                 if (!p->dsp) {
1486                         p->dsp = ast_dsp_new();
1487                         if (!p->dsp) {
1488                                 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1489                                 return -1;
1490                         }
1491                 }
1492
1493                 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
1494         } else if (mode == ANALOG_DIGITMODE_MF) {
1495                 if (!p->dsp) {
1496                         p->dsp = ast_dsp_new();
1497                         if (!p->dsp) {
1498                                 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1499                                 return -1;
1500                         }
1501                 }
1502                 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
1503         }
1504         return 0;
1505 }
1506
1507 static int dahdi_wink(struct dahdi_pvt *p, int index);
1508
1509 static int my_wink(void *pvt, enum analog_sub sub)
1510 {
1511         struct dahdi_pvt *p = pvt;
1512         int index = analogsub_to_dahdisub(sub);
1513         if (index != SUB_REAL) {
1514                 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1515         }
1516         return dahdi_wink(p, index);
1517 }
1518
1519 static void wakeup_sub(struct dahdi_pvt *p, int a);
1520
1521 static int reset_conf(struct dahdi_pvt *p);
1522
1523 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
1524
1525 static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
1526 {
1527         struct ast_frame *f = *dest;
1528         struct dahdi_pvt *p = pvt;
1529         int idx = analogsub_to_dahdisub(analog_index);
1530
1531         ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
1532                 f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
1533                 f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
1534
1535         if (f->subclass.integer == 'f') {
1536                 if (f->frametype == AST_FRAME_DTMF_END) {
1537                         /* Fax tone -- Handle and return NULL */
1538                         if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
1539                                 /* If faxbuffers are configured, use them for the fax transmission */
1540                                 if (p->usefaxbuffers && !p->bufferoverrideinuse) {
1541                                         struct dahdi_bufferinfo bi = {
1542                                                 .txbufpolicy = p->faxbuf_policy,
1543                                                 .bufsize = p->bufsize,
1544                                                 .numbufs = p->faxbuf_no
1545                                         };
1546                                         int res;
1547
1548                                         if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
1549                                                 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
1550                                         } else {
1551                                                 p->bufferoverrideinuse = 1;
1552                                         }
1553                                 }
1554                                 p->faxhandled = 1;
1555                                 if (p->dsp) {
1556                                         p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
1557                                         ast_dsp_set_features(p->dsp, p->dsp_features);
1558                                         ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
1559                                 }
1560                                 if (strcmp(ast_channel_exten(ast), "fax")) {
1561                                         const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
1562
1563                                         /* We need to unlock 'ast' here because ast_exists_extension has the
1564                                          * potential to start autoservice on the channel. Such action is prone
1565                                          * to deadlock.
1566                                          */
1567                                         ast_mutex_unlock(&p->lock);
1568                                         ast_channel_unlock(ast);
1569                                         if (ast_exists_extension(ast, target_context, "fax", 1,
1570                                                 S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
1571                                                 ast_channel_lock(ast);
1572                                                 ast_mutex_lock(&p->lock);
1573                                                 ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
1574                                                 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
1575                                                 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
1576                                                 if (ast_async_goto(ast, target_context, "fax", 1))
1577                                                         ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
1578                                         } else {
1579                                                 ast_channel_lock(ast);
1580                                                 ast_mutex_lock(&p->lock);
1581                                                 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
1582                                         }
1583                                 } else {
1584                                         ast_debug(1, "Already in a fax extension, not redirecting\n");
1585                                 }
1586                         } else {
1587                                 ast_debug(1, "Fax already handled\n");
1588                         }
1589                         dahdi_confmute(p, 0);
1590                 }
1591                 p->subs[idx].f.frametype = AST_FRAME_NULL;
1592                 p->subs[idx].f.subclass.integer = 0;
1593                 *dest = &p->subs[idx].f;
1594         }
1595 }
1596
1597 static void my_lock_private(void *pvt)
1598 {
1599         struct dahdi_pvt *p = pvt;
1600         ast_mutex_lock(&p->lock);
1601 }
1602
1603 static void my_unlock_private(void *pvt)
1604 {
1605         struct dahdi_pvt *p = pvt;
1606         ast_mutex_unlock(&p->lock);
1607 }
1608
1609 static void my_deadlock_avoidance_private(void *pvt)
1610 {
1611         struct dahdi_pvt *p = pvt;
1612
1613         DEADLOCK_AVOIDANCE(&p->lock);
1614 }
1615
1616 static struct ast_manager_event_blob *dahdichannel_to_ami(struct stasis_message *msg)
1617 {
1618         RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
1619         struct ast_channel_blob *obj = stasis_message_data(msg);
1620         struct ast_json *span, *channel;
1621
1622         channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1623         if (!channel_string) {
1624                 return NULL;
1625         }
1626
1627         span = ast_json_object_get(obj->blob, "span");
1628         channel = ast_json_object_get(obj->blob, "channel");
1629
1630         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
1631                 "%s"
1632                 "DAHDISpan: %d\r\n"
1633                 "DAHDIChannel: %s\r\n",
1634                 ast_str_buffer(channel_string),
1635                 (unsigned int)ast_json_integer_get(span),
1636                 ast_json_string_get(channel));
1637 }
1638
1639 STASIS_MESSAGE_TYPE_DEFN_LOCAL(dahdichannel_type,
1640         .to_ami = dahdichannel_to_ami,
1641         );
1642
1643 /*! \brief Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages */
1644 static void publish_dahdichannel(struct ast_channel *chan, int span, const char *dahdi_channel)
1645 {
1646         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1647
1648         ast_assert(dahdi_channel != NULL);
1649
1650         blob = ast_json_pack("{s: i, s: s}",
1651                 "span", span,
1652                 "channel", dahdi_channel);
1653         if (!blob) {
1654                 return;
1655         }
1656
1657         ast_channel_publish_blob(chan, dahdichannel_type(), blob);
1658 }
1659
1660 /*!
1661  * \internal
1662  * \brief Post an AMI DAHDI channel association event.
1663  * \since 1.8
1664  *
1665  * \param p DAHDI private pointer
1666  * \param chan Channel associated with the private pointer
1667  *
1668  * \return Nothing
1669  */
1670 static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
1671 {
1672         char ch_name[20];
1673
1674         if (p->channel < CHAN_PSEUDO) {
1675                 /* No B channel */
1676                 snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
1677         } else if (p->channel == CHAN_PSEUDO) {
1678                 /* Pseudo channel */
1679                 strcpy(ch_name, "pseudo");
1680         } else {
1681                 /* Real channel */
1682                 snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
1683         }
1684         publish_dahdichannel(chan, p->span, ch_name);
1685 }
1686
1687 #ifdef HAVE_PRI
1688 /*!
1689  * \internal
1690  * \brief Post an AMI DAHDI channel association event.
1691  * \since 1.8
1692  *
1693  * \param pvt DAHDI private pointer
1694  * \param chan Channel associated with the private pointer
1695  *
1696  * \return Nothing
1697  */
1698 static void my_ami_channel_event(void *pvt, struct ast_channel *chan)
1699 {
1700         struct dahdi_pvt *p = pvt;
1701
1702         dahdi_ami_channel_event(p, chan);
1703 }
1704 #endif
1705
1706 /* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
1707 *       returns the last value of the linear setting 
1708 */ 
1709 static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
1710 {
1711         struct dahdi_pvt *p = pvt;
1712         int oldval;
1713         int idx = analogsub_to_dahdisub(sub);
1714         
1715         dahdi_setlinear(p->subs[idx].dfd, linear_mode);
1716         oldval = p->subs[idx].linear;
1717         p->subs[idx].linear = linear_mode ? 1 : 0;
1718         return oldval;
1719 }
1720
1721 static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
1722 {
1723         struct dahdi_pvt *p = pvt;
1724         int idx = analogsub_to_dahdisub(sub);
1725
1726         p->subs[idx].inthreeway = inthreeway;
1727 }
1728
1729 static int get_alarms(struct dahdi_pvt *p);
1730 static void handle_alarms(struct dahdi_pvt *p, int alms);
1731 static void my_get_and_handle_alarms(void *pvt)
1732 {
1733         int res;
1734         struct dahdi_pvt *p = pvt;
1735
1736         res = get_alarms(p);
1737         handle_alarms(p, res);
1738 }
1739
1740 static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
1741 {
1742         struct ast_channel *bridged = ast_bridged_channel(chan);
1743
1744         if (bridged && ast_channel_tech(bridged) == &dahdi_tech) {
1745                 struct dahdi_pvt *p = ast_channel_tech_pvt(bridged);
1746
1747                 if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
1748                         return p->sig_pvt;
1749                 }
1750         }
1751         return NULL;
1752 }
1753
1754 static int my_get_sub_fd(void *pvt, enum analog_sub sub)
1755 {
1756         struct dahdi_pvt *p = pvt;
1757         int dahdi_sub = analogsub_to_dahdisub(sub);
1758         return p->subs[dahdi_sub].dfd;
1759 }
1760
1761 static void my_set_cadence(void *pvt, int *cid_rings, struct ast_channel *ast)
1762 {
1763         struct dahdi_pvt *p = pvt;
1764
1765         /* Choose proper cadence */
1766         if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
1767                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
1768                         ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
1769                 *cid_rings = cidrings[p->distinctivering - 1];
1770         } else {
1771                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
1772                         ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
1773                 *cid_rings = p->sendcalleridafter;
1774         }
1775 }
1776
1777 static void my_set_alarm(void *pvt, int in_alarm)
1778 {
1779         struct dahdi_pvt *p = pvt;
1780
1781         p->inalarm = in_alarm;
1782 }
1783
1784 static void my_set_dialing(void *pvt, int is_dialing)
1785 {
1786         struct dahdi_pvt *p = pvt;
1787
1788         p->dialing = is_dialing;
1789 }
1790
1791 static void my_set_outgoing(void *pvt, int is_outgoing)
1792 {
1793         struct dahdi_pvt *p = pvt;
1794
1795         p->outgoing = is_outgoing;
1796 }
1797
1798 #if defined(HAVE_PRI) || defined(HAVE_SS7)
1799 static void my_set_digital(void *pvt, int is_digital)
1800 {
1801         struct dahdi_pvt *p = pvt;
1802
1803         p->digital = is_digital;
1804 }
1805 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
1806
1807 #if defined(HAVE_SS7)
1808 static void my_set_inservice(void *pvt, int is_inservice)
1809 {
1810         struct dahdi_pvt *p = pvt;
1811
1812         p->inservice = is_inservice;
1813 }
1814 #endif  /* defined(HAVE_SS7) */
1815
1816 #if defined(HAVE_SS7)
1817 static void my_set_locallyblocked(void *pvt, int is_blocked)
1818 {
1819         struct dahdi_pvt *p = pvt;
1820
1821         p->locallyblocked = is_blocked;
1822 }
1823 #endif  /* defined(HAVE_SS7) */
1824
1825 #if defined(HAVE_SS7)
1826 static void my_set_remotelyblocked(void *pvt, int is_blocked)
1827 {
1828         struct dahdi_pvt *p = pvt;
1829
1830         p->remotelyblocked = is_blocked;
1831 }
1832 #endif  /* defined(HAVE_SS7) */
1833
1834 static void my_set_ringtimeout(void *pvt, int ringt)
1835 {
1836         struct dahdi_pvt *p = pvt;
1837         p->ringt = ringt;
1838 }
1839
1840 static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
1841 {
1842         struct dahdi_pvt *p = pvt;
1843
1844         if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
1845                 ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
1846                 gettimeofday(&p->waitingfordt, NULL);
1847                 ast_setstate(ast, AST_STATE_OFFHOOK);
1848         }
1849 }
1850
1851 static int my_check_waitingfordt(void *pvt)
1852 {
1853         struct dahdi_pvt *p = pvt;
1854
1855         if (p->waitingfordt.tv_usec) {
1856                 return 1;
1857         }
1858
1859         return 0;
1860 }
1861
1862 static void my_set_confirmanswer(void *pvt, int flag)
1863 {
1864         struct dahdi_pvt *p = pvt;
1865         p->confirmanswer = flag;
1866 }
1867
1868 static int my_check_confirmanswer(void *pvt)
1869 {
1870         struct dahdi_pvt *p = pvt;
1871         if (p->confirmanswer) {
1872                 return 1;
1873         }
1874
1875         return 0;
1876 }
1877
1878 static void my_set_callwaiting(void *pvt, int callwaiting_enable)
1879 {
1880         struct dahdi_pvt *p = pvt;
1881
1882         p->callwaiting = callwaiting_enable;
1883 }
1884
1885 static void my_cancel_cidspill(void *pvt)
1886 {
1887         struct dahdi_pvt *p = pvt;
1888
1889         ast_free(p->cidspill);
1890         p->cidspill = NULL;
1891         restore_conference(p);
1892 }
1893
1894 static int my_confmute(void *pvt, int mute)
1895 {
1896         struct dahdi_pvt *p = pvt;
1897         return dahdi_confmute(p, mute);
1898 }
1899
1900 static void my_set_pulsedial(void *pvt, int flag)
1901 {
1902         struct dahdi_pvt *p = pvt;
1903         p->pulsedial = flag;
1904 }
1905
1906 static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
1907 {
1908         struct dahdi_pvt *p = pvt;
1909
1910         p->owner = new_owner;
1911 }
1912
1913 static const char *my_get_orig_dialstring(void *pvt)
1914 {
1915         struct dahdi_pvt *p = pvt;
1916
1917         return p->dialstring;
1918 }
1919
1920 static void my_increase_ss_count(void)
1921 {
1922         ast_mutex_lock(&ss_thread_lock);
1923         ss_thread_count++;
1924         ast_mutex_unlock(&ss_thread_lock);
1925 }
1926
1927 static void my_decrease_ss_count(void)
1928 {
1929         ast_mutex_lock(&ss_thread_lock);
1930         ss_thread_count--;
1931         ast_cond_signal(&ss_thread_complete);
1932         ast_mutex_unlock(&ss_thread_lock);
1933 }
1934
1935 static void my_all_subchannels_hungup(void *pvt)
1936 {
1937         struct dahdi_pvt *p = pvt;
1938         int res, law;
1939
1940         p->faxhandled = 0;
1941         p->didtdd = 0;
1942
1943         if (p->dsp) {
1944                 ast_dsp_free(p->dsp);
1945                 p->dsp = NULL;
1946         }
1947
1948         p->law = p->law_default;
1949         law = p->law_default;
1950         res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
1951         if (res < 0)
1952                 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
1953
1954         dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
1955
1956 #if 1
1957         {
1958         int i;
1959         p->owner = NULL;
1960         /* Cleanup owners here */
1961         for (i = 0; i < 3; i++) {
1962                 p->subs[i].owner = NULL;
1963         }
1964         }
1965 #endif
1966
1967         reset_conf(p);
1968         if (num_restart_pending == 0) {
1969                 restart_monitor();
1970         }
1971 }
1972
1973 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
1974
1975 static int my_conf_del(void *pvt, enum analog_sub sub)
1976 {
1977         struct dahdi_pvt *p = pvt;
1978         int x = analogsub_to_dahdisub(sub);
1979
1980         return conf_del(p, &p->subs[x], x);
1981 }
1982
1983 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
1984
1985 static int my_conf_add(void *pvt, enum analog_sub sub)
1986 {
1987         struct dahdi_pvt *p = pvt;
1988         int x = analogsub_to_dahdisub(sub);
1989
1990         return conf_add(p, &p->subs[x], x, 0);
1991 }
1992
1993 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
1994
1995 static int my_complete_conference_update(void *pvt, int needconference)
1996 {
1997         struct dahdi_pvt *p = pvt;
1998         int needconf = needconference;
1999         int x;
2000         int useslavenative;
2001         struct dahdi_pvt *slave = NULL;
2002
2003         useslavenative = isslavenative(p, &slave);
2004
2005         /* If we have a slave, add him to our conference now. or DAX
2006            if this is slave native */
2007         for (x = 0; x < MAX_SLAVES; x++) {
2008                 if (p->slaves[x]) {
2009                         if (useslavenative)
2010                                 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2011                         else {
2012                                 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2013                                 needconf++;
2014                         }
2015                 }
2016         }
2017         /* If we're supposed to be in there, do so now */
2018         if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2019                 if (useslavenative)
2020                         conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2021                 else {
2022                         conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2023                         needconf++;
2024                 }
2025         }
2026         /* If we have a master, add ourselves to his conference */
2027         if (p->master) {
2028                 if (isslavenative(p->master, NULL)) {
2029                         conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
2030                 } else {
2031                         conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2032                 }
2033         }
2034         if (!needconf) {
2035                 /* Nobody is left (or should be left) in our conference.
2036                    Kill it. */
2037                 p->confno = -1;
2038         }
2039
2040         return 0;
2041 }
2042
2043 static int check_for_conference(struct dahdi_pvt *p);
2044
2045 static int my_check_for_conference(void *pvt)
2046 {
2047         struct dahdi_pvt *p = pvt;
2048         return check_for_conference(p);
2049 }
2050
2051 static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a,  enum analog_sub b, struct ast_channel *ast_b)
2052 {
2053         struct dahdi_pvt *p = pvt;
2054         int da, db;
2055         int tchan;
2056         int tinthreeway;
2057
2058         da = analogsub_to_dahdisub(a);
2059         db = analogsub_to_dahdisub(b);
2060
2061         tchan = p->subs[da].chan;
2062         p->subs[da].chan = p->subs[db].chan;
2063         p->subs[db].chan = tchan;
2064
2065         tinthreeway = p->subs[da].inthreeway;
2066         p->subs[da].inthreeway = p->subs[db].inthreeway;
2067         p->subs[db].inthreeway = tinthreeway;
2068
2069         p->subs[da].owner = ast_a;
2070         p->subs[db].owner = ast_b;
2071
2072         if (ast_a)
2073                 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2074         if (ast_b)
2075                 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2076
2077         wakeup_sub(p, a);
2078         wakeup_sub(p, b);
2079
2080         return;
2081 }
2082
2083 /*!
2084  * \internal
2085  * \brief performs duties of dahdi_new, but also removes and possibly unbinds (if callid_created is 1) before returning
2086  * \note this variant of dahdi should only be used in conjunction with ast_callid_threadstorage_auto()
2087  *
2088  * \param callid_created value returned from ast_callid_threadstorage_auto()
2089  */
2090 static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linked, struct ast_callid *callid, int callid_created);
2091
2092 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid);
2093
2094 static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
2095 {
2096         struct ast_callid *callid = NULL;
2097         int callid_created = ast_callid_threadstorage_auto(&callid);
2098         struct dahdi_pvt *p = pvt;
2099         int dsub = analogsub_to_dahdisub(sub);
2100
2101         return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
2102 }
2103
2104 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2105 static int dahdi_setlaw(int dfd, int law)
2106 {
2107         int res;
2108         res = ioctl(dfd, DAHDI_SETLAW, &law);
2109         if (res)
2110                 return res;
2111         return 0;
2112 }
2113 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2114
2115 #if defined(HAVE_PRI)
2116 static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor)
2117 {
2118         struct dahdi_pvt *p = pvt;
2119         int audio;
2120         int newlaw = -1;
2121         struct ast_callid *callid = NULL;
2122         int callid_created = ast_callid_threadstorage_auto(&callid);
2123
2124         switch (p->sig) {
2125         case SIG_PRI_LIB_HANDLE_CASES:
2126                 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
2127                         /* PRI nobch pseudo channel.  Does not handle ioctl(DAHDI_AUDIOMODE) */
2128                         break;
2129                 }
2130                 /* Fall through */
2131         default:
2132                 /* Set to audio mode at this point */
2133                 audio = 1;
2134                 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
2135                         ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
2136                                 p->channel, audio, strerror(errno));
2137                 }
2138                 break;
2139         }
2140
2141         if (law != SIG_PRI_DEFLAW) {
2142                 dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
2143         }
2144
2145         ast_copy_string(p->exten, exten, sizeof(p->exten));
2146
2147         switch (law) {
2148                 case SIG_PRI_DEFLAW:
2149                         newlaw = 0;
2150                         break;
2151                 case SIG_PRI_ALAW:
2152                         newlaw = DAHDI_LAW_ALAW;
2153                         break;
2154                 case SIG_PRI_ULAW:
2155                         newlaw = DAHDI_LAW_MULAW;
2156                         break;
2157         }
2158
2159         return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
2160 }
2161 #endif  /* defined(HAVE_PRI) */
2162
2163 static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
2164
2165 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2166 /*!
2167  * \internal
2168  * \brief Open the PRI/SS7 channel media path.
2169  * \since 1.8
2170  *
2171  * \param p Channel private control structure.
2172  *
2173  * \return Nothing
2174  */
2175 static void my_pri_ss7_open_media(void *p)
2176 {
2177         struct dahdi_pvt *pvt = p;
2178         int res;
2179         int dfd;
2180         int set_val;
2181
2182         dfd = pvt->subs[SUB_REAL].dfd;
2183
2184         /* Open the media path. */
2185         set_val = 1;
2186         res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2187         if (res < 0) {
2188                 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
2189                         pvt->channel, strerror(errno));
2190         }
2191
2192         /* Set correct companding law for this call. */
2193         res = dahdi_setlaw(dfd, pvt->law);
2194         if (res < 0) {
2195                 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
2196         }
2197
2198         /* Set correct gain for this call. */
2199         if (pvt->digital) {
2200                 res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
2201         } else {
2202                 res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
2203                         pvt->law);
2204         }
2205         if (res < 0) {
2206                 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
2207         }
2208
2209         if (pvt->dsp_features && pvt->dsp) {
2210                 ast_dsp_set_features(pvt->dsp, pvt->dsp_features);
2211                 pvt->dsp_features = 0;
2212         }
2213 }
2214 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2215
2216 #if defined(HAVE_PRI)
2217 /*!
2218  * \internal
2219  * \brief Ask DAHDI to dial the given dial string.
2220  * \since 1.8.11
2221  *
2222  * \param p Channel private control structure.
2223  * \param dial_string String to pass to DAHDI to dial.
2224  *
2225  * \note The channel private lock needs to be held when calling.
2226  *
2227  * \return Nothing
2228  */
2229 static void my_pri_dial_digits(void *p, const char *dial_string)
2230 {
2231         char dial_str[DAHDI_MAX_DTMF_BUF];
2232         struct dahdi_pvt *pvt = p;
2233         int res;
2234
2235         snprintf(dial_str, sizeof(dial_str), "T%s", dial_string);
2236         res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
2237         if (!res) {
2238                 pvt->dialing = 1;
2239         }
2240 }
2241 #endif  /* defined(HAVE_PRI) */
2242
2243 static int unalloc_sub(struct dahdi_pvt *p, int x);
2244
2245 static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
2246 {
2247         struct dahdi_pvt *p = pvt;
2248
2249         return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2250 }
2251
2252 static int alloc_sub(struct dahdi_pvt *p, int x);
2253
2254 static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
2255 {
2256         struct dahdi_pvt *p = pvt;
2257
2258         return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2259 }
2260
2261 static int has_voicemail(struct dahdi_pvt *p);
2262
2263 static int my_has_voicemail(void *pvt)
2264 {
2265         struct dahdi_pvt *p = pvt;
2266
2267         return has_voicemail(p);
2268 }
2269
2270 static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
2271 {
2272         struct dahdi_pvt *p = pvt;
2273         int index;
2274
2275         index = analogsub_to_dahdisub(sub);
2276
2277         return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2278 }
2279
2280 static enum analog_event dahdievent_to_analogevent(int event)
2281 {
2282         enum analog_event res;
2283
2284         switch (event) {
2285         case DAHDI_EVENT_ONHOOK:
2286                 res = ANALOG_EVENT_ONHOOK;
2287                 break;
2288         case DAHDI_EVENT_RINGOFFHOOK:
2289                 res = ANALOG_EVENT_RINGOFFHOOK;
2290                 break;
2291         case DAHDI_EVENT_WINKFLASH:
2292                 res = ANALOG_EVENT_WINKFLASH;
2293                 break;
2294         case DAHDI_EVENT_ALARM:
2295                 res = ANALOG_EVENT_ALARM;
2296                 break;
2297         case DAHDI_EVENT_NOALARM:
2298                 res = ANALOG_EVENT_NOALARM;
2299                 break;
2300         case DAHDI_EVENT_DIALCOMPLETE:
2301                 res = ANALOG_EVENT_DIALCOMPLETE;
2302                 break;
2303         case DAHDI_EVENT_RINGERON:
2304                 res = ANALOG_EVENT_RINGERON;
2305                 break;
2306         case DAHDI_EVENT_RINGEROFF:
2307                 res = ANALOG_EVENT_RINGEROFF;
2308                 break;
2309         case DAHDI_EVENT_HOOKCOMPLETE:
2310                 res = ANALOG_EVENT_HOOKCOMPLETE;
2311                 break;
2312         case DAHDI_EVENT_PULSE_START:
2313                 res = ANALOG_EVENT_PULSE_START;
2314                 break;
2315         case DAHDI_EVENT_POLARITY:
2316                 res = ANALOG_EVENT_POLARITY;
2317                 break;
2318         case DAHDI_EVENT_RINGBEGIN:
2319                 res = ANALOG_EVENT_RINGBEGIN;
2320                 break;
2321         case DAHDI_EVENT_EC_DISABLED:
2322                 res = ANALOG_EVENT_EC_DISABLED;
2323                 break;
2324         case DAHDI_EVENT_REMOVED:
2325                 res = ANALOG_EVENT_REMOVED;
2326                 break;
2327         case DAHDI_EVENT_NEONMWI_ACTIVE:
2328                 res = ANALOG_EVENT_NEONMWI_ACTIVE;
2329                 break;
2330         case DAHDI_EVENT_NEONMWI_INACTIVE:
2331                 res = ANALOG_EVENT_NEONMWI_INACTIVE;
2332                 break;
2333 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2334         case DAHDI_EVENT_TX_CED_DETECTED:
2335                 res = ANALOG_EVENT_TX_CED_DETECTED;
2336                 break;
2337         case DAHDI_EVENT_RX_CED_DETECTED:
2338                 res = ANALOG_EVENT_RX_CED_DETECTED;
2339                 break;
2340         case DAHDI_EVENT_EC_NLP_DISABLED:
2341                 res = ANALOG_EVENT_EC_NLP_DISABLED;
2342                 break;
2343         case DAHDI_EVENT_EC_NLP_ENABLED:
2344                 res = ANALOG_EVENT_EC_NLP_ENABLED;
2345                 break;
2346 #endif
2347         case DAHDI_EVENT_PULSEDIGIT:
2348                 res = ANALOG_EVENT_PULSEDIGIT;
2349                 break;
2350         case DAHDI_EVENT_DTMFDOWN:
2351                 res = ANALOG_EVENT_DTMFDOWN;
2352                 break;
2353         case DAHDI_EVENT_DTMFUP:
2354                 res = ANALOG_EVENT_DTMFUP;
2355                 break;
2356         default:
2357                 switch(event & 0xFFFF0000) {
2358                 case DAHDI_EVENT_PULSEDIGIT:
2359                 case DAHDI_EVENT_DTMFDOWN:
2360                 case DAHDI_EVENT_DTMFUP:
2361                         /* The event includes a digit number in the low word.
2362                          * Converting it to a 'enum analog_event' would remove
2363                          * that information. Thus it is returned as-is.
2364                          */
2365                         return event;
2366                 }
2367
2368                 res = ANALOG_EVENT_ERROR;
2369                 break;
2370         }
2371
2372         return res;
2373 }
2374
2375 static inline int dahdi_wait_event(int fd);
2376
2377 static int my_wait_event(void *pvt)
2378 {
2379         struct dahdi_pvt *p = pvt;
2380
2381         return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2382 }
2383
2384 static int my_get_event(void *pvt)
2385 {
2386         struct dahdi_pvt *p = pvt;
2387         int res;
2388
2389         if (p->fake_event) {
2390                 res = p->fake_event;
2391                 p->fake_event = 0;
2392         } else
2393                 res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2394
2395         return dahdievent_to_analogevent(res);
2396 }
2397
2398 static int my_is_off_hook(void *pvt)
2399 {
2400         struct dahdi_pvt *p = pvt;
2401         int res;
2402         struct dahdi_params par;
2403
2404         memset(&par, 0, sizeof(par));
2405
2406         if (p->subs[SUB_REAL].dfd > -1)
2407                 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2408         else {
2409                 /* Assume not off hook on CVRS */
2410                 res = 0;
2411                 par.rxisoffhook = 0;
2412         }
2413         if (res) {
2414                 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2415         }
2416
2417         if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2418                 /* When "onhook" that means no battery on the line, and thus
2419                 it is out of service..., if it's on a TDM card... If it's a channel
2420                 bank, there is no telling... */
2421                 return (par.rxbits > -1) || par.rxisoffhook;
2422         }
2423
2424         return par.rxisoffhook;
2425 }
2426
2427 static int my_set_echocanceller(void *pvt, int enable)
2428 {
2429         struct dahdi_pvt *p = pvt;
2430
2431         if (enable)
2432                 dahdi_ec_enable(p);
2433         else
2434                 dahdi_ec_disable(p);
2435
2436         return 0;
2437 }
2438
2439 static int dahdi_ring_phone(struct dahdi_pvt *p);
2440
2441 static int my_ring(void *pvt)
2442 {
2443         struct dahdi_pvt *p = pvt;
2444
2445         return dahdi_ring_phone(p);
2446 }
2447
2448 static int my_flash(void *pvt)
2449 {
2450         struct dahdi_pvt *p = pvt;
2451         int func = DAHDI_FLASH;
2452         return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2453 }
2454
2455 static inline int dahdi_set_hook(int fd, int hs);
2456
2457 static int my_off_hook(void *pvt)
2458 {
2459         struct dahdi_pvt *p = pvt;
2460         return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2461 }
2462
2463 static void my_set_needringing(void *pvt, int value)
2464 {
2465         struct dahdi_pvt *p = pvt;
2466         p->subs[SUB_REAL].needringing = value;
2467 }
2468
2469 static void my_set_polarity(void *pvt, int value)
2470 {
2471         struct dahdi_pvt *p = pvt;
2472
2473         if (p->channel == CHAN_PSEUDO) {
2474                 return;
2475         }
2476         p->polarity = value;
2477         ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2478 }
2479
2480 static void my_start_polarityswitch(void *pvt)
2481 {
2482         struct dahdi_pvt *p = pvt;
2483
2484         if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
2485                 my_set_polarity(pvt, 0);
2486         }
2487 }
2488
2489 static void my_answer_polarityswitch(void *pvt)
2490 {
2491         struct dahdi_pvt *p = pvt;
2492
2493         if (!p->answeronpolarityswitch) {
2494                 return;
2495         }
2496
2497         my_set_polarity(pvt, 1);
2498 }
2499
2500 static void my_hangup_polarityswitch(void *pvt)
2501 {
2502         struct dahdi_pvt *p = pvt;
2503
2504         if (!p->hanguponpolarityswitch) {
2505                 return;
2506         }
2507
2508         if (p->answeronpolarityswitch) {
2509                 my_set_polarity(pvt, 0);
2510         } else {
2511                 my_set_polarity(pvt, 1);
2512         }
2513 }
2514
2515 static int my_start(void *pvt)
2516 {
2517         struct dahdi_pvt *p = pvt;
2518         int x = DAHDI_START;
2519
2520         return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2521 }
2522
2523 static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
2524 {
2525         struct dahdi_pvt *p = pvt;
2526
2527         if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2528                 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2529                 return -1;
2530         }
2531
2532         if (sub != ANALOG_SUB_REAL) {
2533                 ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n",
2534                         dop->dialstr, p->channel, sub);
2535                 return -1;
2536         }
2537
2538         return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr);
2539 }
2540
2541 static void dahdi_train_ec(struct dahdi_pvt *p);
2542
2543 static int my_train_echocanceller(void *pvt)
2544 {
2545         struct dahdi_pvt *p = pvt;
2546
2547         dahdi_train_ec(p);
2548
2549         return 0;
2550 }
2551
2552 static int my_is_dialing(void *pvt, enum analog_sub sub)
2553 {
2554         struct dahdi_pvt *p = pvt;
2555         int index;
2556         int x;
2557
2558         index = analogsub_to_dahdisub(sub);
2559
2560         if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
2561                 ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
2562                 return -1;
2563         }
2564
2565         return x;
2566 }
2567
2568 static int my_on_hook(void *pvt)
2569 {
2570         struct dahdi_pvt *p = pvt;
2571         return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
2572 }
2573
2574 #if defined(HAVE_PRI)
2575 static void my_pri_fixup_chans(void *chan_old, void *chan_new)
2576 {
2577         struct dahdi_pvt *old_chan = chan_old;
2578         struct dahdi_pvt *new_chan = chan_new;
2579
2580         new_chan->owner = old_chan->owner;
2581         old_chan->owner = NULL;
2582         if (new_chan->owner) {
2583                 ast_channel_tech_pvt_set(new_chan->owner, new_chan);
2584                 ast_channel_internal_fd_set(new_chan->owner, 0, new_chan->subs[SUB_REAL].dfd);
2585                 new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
2586                 old_chan->subs[SUB_REAL].owner = NULL;
2587         }
2588         /* Copy any DSP that may be present */
2589         new_chan->dsp = old_chan->dsp;
2590         new_chan->dsp_features = old_chan->dsp_features;
2591         old_chan->dsp = NULL;
2592         old_chan->dsp_features = 0;
2593
2594         /* Transfer flags from the old channel. */
2595         new_chan->dialing = old_chan->dialing;
2596         new_chan->digital = old_chan->digital;
2597         new_chan->outgoing = old_chan->outgoing;
2598         old_chan->dialing = 0;
2599         old_chan->digital = 0;
2600         old_chan->outgoing = 0;
2601
2602         /* More stuff to transfer to the new channel. */
2603         new_chan->law = old_chan->law;
2604         strcpy(new_chan->dialstring, old_chan->dialstring);
2605 }
2606 #endif  /* defined(HAVE_PRI) */
2607
2608 #if defined(HAVE_PRI)
2609 static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
2610 {
2611         switch (tone) {
2612         case SIG_PRI_TONE_RINGTONE:
2613                 return DAHDI_TONE_RINGTONE;
2614         case SIG_PRI_TONE_STUTTER:
2615                 return DAHDI_TONE_STUTTER;
2616         case SIG_PRI_TONE_CONGESTION:
2617                 return DAHDI_TONE_CONGESTION;
2618         case SIG_PRI_TONE_DIALTONE:
2619                 return DAHDI_TONE_DIALTONE;
2620         case SIG_PRI_TONE_DIALRECALL:
2621                 return DAHDI_TONE_DIALRECALL;
2622         case SIG_PRI_TONE_INFO:
2623                 return DAHDI_TONE_INFO;
2624         case SIG_PRI_TONE_BUSY:
2625                 return DAHDI_TONE_BUSY;
2626         default:
2627                 return -1;
2628         }
2629 }
2630 #endif  /* defined(HAVE_PRI) */
2631
2632 #if defined(HAVE_PRI)
2633 static int pri_destroy_dchan(struct sig_pri_span *pri);
2634
2635 static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
2636 {
2637         int x;
2638
2639         ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
2640         switch (x) {
2641         case DAHDI_EVENT_NONE:
2642                 break;
2643         case DAHDI_EVENT_ALARM:
2644         case DAHDI_EVENT_NOALARM:
2645                 if (sig_pri_is_alarm_ignored(pri)) {
2646                         break;
2647                 }
2648                 /* Fall through */
2649         default:
2650                 ast_log(LOG_NOTICE, "Got DAHDI event: %s (%d) on D-channel of span %d\n",
2651                         event2str(x), x, pri->span);
2652                 break;
2653         }
2654         /* Keep track of alarm state */
2655         switch (x) {
2656         case DAHDI_EVENT_ALARM:
2657                 pri_event_alarm(pri, index, 0);
2658                 break;
2659         case DAHDI_EVENT_NOALARM:
2660                 pri_event_noalarm(pri, index, 0);
2661                 break;
2662         case DAHDI_EVENT_REMOVED:
2663                 pri_destroy_dchan(pri);
2664                 break;
2665         default:
2666                 break;
2667         }
2668 }
2669 #endif  /* defined(HAVE_PRI) */
2670
2671 #if defined(HAVE_PRI)
2672 static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
2673 {
2674         struct dahdi_pvt *p = pvt;
2675
2676         return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
2677 }
2678 #endif  /* defined(HAVE_PRI) */
2679
2680 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2681 /*!
2682  * \internal
2683  * \brief Set the caller id information.
2684  * \since 1.8
2685  *
2686  * \param pvt DAHDI private structure
2687  * \param caller Caller-id information to set.
2688  *
2689  * \return Nothing
2690  */
2691 static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
2692 {
2693         struct dahdi_pvt *p = pvt;
2694
2695         ast_copy_string(p->cid_num,
2696                 S_COR(caller->id.number.valid, caller->id.number.str, ""),
2697                 sizeof(p->cid_num));
2698         ast_copy_string(p->cid_name,
2699                 S_COR(caller->id.name.valid, caller->id.name.str, ""),
2700                 sizeof(p->cid_name));
2701         ast_copy_string(p->cid_subaddr,
2702                 S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
2703                 sizeof(p->cid_subaddr));
2704         p->cid_ton = caller->id.number.plan;
2705         p->callingpres = ast_party_id_presentation(&caller->id);
2706         if (caller->id.tag) {
2707                 ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
2708         }
2709         ast_copy_string(p->cid_ani,
2710                 S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
2711                 sizeof(p->cid_ani));
2712         p->cid_ani2 = caller->ani2;
2713 }
2714 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2715
2716 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2717 /*!
2718  * \internal
2719  * \brief Set the Dialed Number Identifier.
2720  * \since 1.8
2721  *
2722  * \param pvt DAHDI private structure
2723  * \param dnid Dialed Number Identifier string.
2724  *
2725  * \return Nothing
2726  */
2727 static void my_set_dnid(void *pvt, const char *dnid)
2728 {
2729         struct dahdi_pvt *p = pvt;
2730
2731         ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
2732 }
2733 #endif  /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2734
2735 #if defined(HAVE_PRI)
2736 /*!
2737  * \internal
2738  * \brief Set the Redirecting Directory Number Information Service (RDNIS).
2739  * \since 1.8
2740  *
2741  * \param pvt DAHDI private structure
2742  * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
2743  *
2744  * \return Nothing
2745  */
2746 static void my_set_rdnis(void *pvt, const char *rdnis)
2747 {
2748         struct dahdi_pvt *p = pvt;
2749
2750         ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
2751 }
2752 #endif  /* defined(HAVE_PRI) */
2753
2754 #if defined(HAVE_PRI)
2755 /*!
2756  * \internal
2757  * \brief Make a dialstring for native ISDN CC to recall properly.
2758  * \since 1.8
2759  *
2760  * \param priv Channel private control structure.
2761  * \param buf Where to put the modified dialstring.
2762  * \param buf_size Size of modified dialstring buffer.
2763  *
2764  * \details
2765  * original dialstring:
2766  * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2767  *
2768  * The modified dialstring will have prefixed the channel-group section
2769  * with the ISDN channel restriction.
2770  *
2771  * buf:
2772  * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2773  *
2774  * The routine will check to see if the ISDN channel restriction is already
2775  * in the original dialstring.
2776  *
2777  * \return Nothing
2778  */
2779 static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
2780 {
2781         char *dial;
2782         struct dahdi_pvt *pvt;
2783         AST_DECLARE_APP_ARGS(args,
2784                 AST_APP_ARG(tech);      /* channel technology token */
2785                 AST_APP_ARG(group);     /* channel/group token */
2786                 //AST_APP_ARG(ext);     /* extension token */
2787                 //AST_APP_ARG(opts);    /* options token */
2788                 //AST_APP_ARG(other);   /* Any remining unused arguments */
2789         );
2790
2791         pvt = priv;
2792         dial = ast_strdupa(pvt->dialstring);
2793         AST_NONSTANDARD_APP_ARGS(args, dial, '/');
2794         if (!args.tech) {
2795                 ast_copy_string(buf, pvt->dialstring, buf_size);
2796                 return;
2797         }
2798         if (!args.group) {
2799                 /* Append the ISDN span channel restriction to the dialstring. */
2800                 snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
2801                 return;
2802         }
2803         if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
2804                 /* The ISDN span channel restriction is not needed or already
2805                  * in the dialstring. */
2806                 ast_copy_string(buf, pvt->dialstring, buf_size);
2807                 return;
2808         }
2809         /* Insert the ISDN span channel restriction into the dialstring. */
2810         snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
2811 }
2812 #endif  /* defined(HAVE_PRI) */
2813
2814 #if defined(HAVE_PRI)
2815 /*!
2816  * \internal
2817  * \brief Reevaluate the PRI span device state.
2818  * \since 1.8
2819  *
2820  * \param pri Asterisk D channel control structure.
2821  *
2822  * \return Nothing
2823  *
2824  * \note Assumes the pri->lock is already obtained.
2825  */
2826 static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
2827 {
2828         unsigned idx;
2829         unsigned num_b_chans;   /* Number of B channels provisioned on the span. */
2830         unsigned in_use;                /* Number of B channels in use on the span. */
2831         unsigned in_alarm;              /* TRUE if the span is in alarm condition. */
2832         enum ast_device_state new_state;
2833
2834         /* Count the number of B channels and the number of B channels in use. */
2835         num_b_chans = 0;
2836         in_use = 0;
2837         in_alarm = 1;
2838         for (idx = pri->numchans; idx--;) {
2839                 if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
2840                         /* This is a B channel interface. */
2841                         ++num_b_chans;
2842                         if (!sig_pri_is_chan_available(pri->pvts[idx])) {
2843                                 ++in_use;
2844                         }
2845                         if (!pri->pvts[idx]->inalarm) {
2846                                 /* There is a channel that is not in alarm. */
2847                                 in_alarm = 0;
2848                         }
2849                 }
2850         }
2851
2852         /* Update the span congestion device state and report any change. */
2853         if (in_alarm) {
2854                 new_state = AST_DEVICE_UNAVAILABLE;
2855         } else {
2856                 new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
2857         }
2858         if (pri->congestion_devstate != new_state) {
2859                 pri->congestion_devstate = new_state;
2860                 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
2861         }
2862 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
2863         /* Update the span threshold device state and report any change. */
2864         if (in_alarm) {
2865                 new_state = AST_DEVICE_UNAVAILABLE;
2866         } else if (!in_use) {
2867                 new_state = AST_DEVICE_NOT_INUSE;
2868         } else if (!pri->user_busy_threshold) {
2869                 new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
2870         } else {
2871                 new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
2872                         : AST_DEVICE_BUSY;
2873         }
2874         if (pri->threshold_devstate != new_state) {
2875                 pri->threshold_devstate = new_state;
2876                 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
2877         }
2878 #endif  /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
2879 }
2880 #endif  /* defined(HAVE_PRI) */
2881
2882 #if defined(HAVE_PRI)
2883 /*!
2884  * \internal
2885  * \brief Reference this module.
2886  * \since 1.8
2887  *
2888  * \return Nothing
2889  */
2890 static void my_module_ref(void)
2891 {
2892         ast_module_ref(ast_module_info->self);
2893 }
2894 #endif  /* defined(HAVE_PRI) */
2895
2896 #if defined(HAVE_PRI)
2897 /*!
2898  * \internal
2899  * \brief Unreference this module.
2900  * \since 1.8
2901  *
2902  * \return Nothing
2903  */
2904 static void my_module_unref(void)
2905 {
2906         ast_module_unref(ast_module_info->self);
2907 }
2908 #endif  /* defined(HAVE_PRI) */
2909
2910 #if defined(HAVE_PRI)
2911 #if defined(HAVE_PRI_CALL_WAITING)
2912 static void my_pri_init_config(void *priv, struct sig_pri_span *pri);
2913 #endif  /* defined(HAVE_PRI_CALL_WAITING) */
2914 static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri);
2915
2916 struct sig_pri_callback sig_pri_callbacks =
2917 {
2918         .handle_dchan_exception = my_handle_dchan_exception,
2919         .play_tone = my_pri_play_tone,
2920         .set_echocanceller = my_set_echocanceller,
2921         .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
2922         .lock_private = my_lock_private,
2923         .unlock_private = my_unlock_private,
2924         .deadlock_avoidance_private = my_deadlock_avoidance_private,
2925         .new_ast_channel = my_new_pri_ast_channel,
2926         .fixup_chans = my_pri_fixup_chans,
2927         .set_alarm = my_set_alarm,
2928         .set_dialing = my_set_dialing,
2929         .set_outgoing = my_set_outgoing,
2930         .set_digital = my_set_digital,
2931         .set_callerid = my_set_callerid,
2932         .set_dnid = my_set_dnid,
2933         .set_rdnis = my_set_rdnis,
2934         .new_nobch_intf = dahdi_new_pri_nobch_channel,
2935 #if defined(HAVE_PRI_CALL_WAITING)
2936         .init_config = my_pri_init_config,
2937 #endif  /* defined(HAVE_PRI_CALL_WAITING) */
2938         .get_orig_dialstring = my_get_orig_dialstring,
2939         .make_cc_dialstring = my_pri_make_cc_dialstring,
2940         .update_span_devstate = dahdi_pri_update_span_devstate,
2941         .module_ref = my_module_ref,
2942         .module_unref = my_module_unref,
2943         .dial_digits = my_pri_dial_digits,
2944         .open_media = my_pri_ss7_open_media,
2945         .ami_channel_event = my_ami_channel_event,
2946 };
2947 #endif  /* defined(HAVE_PRI) */
2948
2949 #if defined(HAVE_SS7)
2950 /*!
2951  * \internal
2952  * \brief Handle the SS7 link exception.
2953  * \since 1.8
2954  *
2955  * \param linkset Controlling linkset for the channel.
2956  * \param which Link index of the signaling channel.
2957  *
2958  * \return Nothing
2959  */
2960 static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
2961 {
2962         int event;
2963
2964         if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
2965                 ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
2966                         linkset->span, which);
2967                 return;
2968         }
2969         switch (event) {
2970         case DAHDI_EVENT_NONE:
2971                 break;
2972         case DAHDI_EVENT_ALARM:
2973                 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
2974                         event2str(event), event, linkset->span, which);
2975                 sig_ss7_link_alarm(linkset, which);
2976                 break;
2977         case DAHDI_EVENT_NOALARM:
2978                 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
2979                         event2str(event), event, linkset->span, which);
2980                 sig_ss7_link_noalarm(linkset, which);
2981                 break;
2982         default:
2983                 ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
2984                         event2str(event), event, linkset->span, which);
2985                 break;
2986         }
2987 }
2988 #endif  /* defined(HAVE_SS7) */
2989
2990 #if defined(HAVE_SS7)
2991 static void my_ss7_set_loopback(void *pvt, int enable)
2992 {
2993         struct dahdi_pvt *p = pvt;
2994
2995         if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
2996                 ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
2997                         strerror(errno));
2998         }
2999 }
3000 #endif  /* defined(HAVE_SS7) */
3001
3002 #if defined(HAVE_SS7)
3003 /*!
3004  * \internal
3005  * \brief Create a new asterisk channel structure for SS7.
3006  * \since 1.8
3007  *
3008  * \param pvt Private channel structure.
3009  * \param state Initial state of new channel.
3010  * \param law Combanding law to use.
3011  * \param exten Dialplan extension for incoming call.
3012  * \param requestor Channel requesting this new channel.
3013  *
3014  * \retval ast_channel on success.
3015  * \retval NULL on error.
3016  */
3017 static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor)
3018 {
3019         struct dahdi_pvt *p = pvt;
3020         int audio;
3021         int newlaw;
3022         struct ast_callid *callid = NULL;
3023         int callid_created = ast_callid_threadstorage_auto(&callid);
3024
3025         /* Set to audio mode at this point */
3026         audio = 1;
3027         if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
3028                 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
3029                         p->channel, audio, strerror(errno));
3030
3031         if (law != SIG_SS7_DEFLAW) {
3032                 dahdi_setlaw(p->subs[SUB_REAL].dfd,
3033                         (law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
3034         }
3035
3036         ast_copy_string(p->exten, exten, sizeof(p->exten));
3037
3038         newlaw = -1;
3039         switch (law) {
3040         case SIG_SS7_DEFLAW:
3041                 newlaw = 0;
3042                 break;
3043         case SIG_SS7_ALAW:
3044                 newlaw = DAHDI_LAW_ALAW;
3045                 break;
3046         case SIG_SS7_ULAW:
3047                 newlaw = DAHDI_LAW_MULAW;
3048                 break;
3049         }
3050         return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
3051 }
3052 #endif  /* defined(HAVE_SS7) */
3053
3054 #if defined(HAVE_SS7)
3055 static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
3056 {
3057         switch (tone) {
3058         case SIG_SS7_TONE_RINGTONE:
3059                 return DAHDI_TONE_RINGTONE;
3060         case SIG_SS7_TONE_STUTTER:
3061                 return DAHDI_TONE_STUTTER;
3062         case SIG_SS7_TONE_CONGESTION:
3063                 return DAHDI_TONE_CONGESTION;
3064         case SIG_SS7_TONE_DIALTONE:
3065                 return DAHDI_TONE_DIALTONE;
3066         case SIG_SS7_TONE_DIALRECALL:
3067                 return DAHDI_TONE_DIALRECALL;
3068         case SIG_SS7_TONE_INFO:
3069                 return DAHDI_TONE_INFO;
3070         case SIG_SS7_TONE_BUSY:
3071                 return DAHDI_TONE_BUSY;
3072         default:
3073                 return -1;
3074         }
3075 }
3076 #endif  /* defined(HAVE_SS7) */
3077
3078 #if defined(HAVE_SS7)
3079 static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
3080 {
3081         struct dahdi_pvt *p = pvt;
3082
3083         return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
3084 }
3085 #endif  /* defined(HAVE_SS7) */
3086
3087 #if defined(HAVE_SS7)
3088 struct sig_ss7_callback sig_ss7_callbacks =
3089 {
3090         .lock_private = my_lock_private,
3091         .unlock_private = my_unlock_private,
3092         .deadlock_avoidance_private = my_deadlock_avoidance_private,
3093
3094         .set_echocanceller = my_set_echocanceller,
3095         .set_loopback = my_ss7_set_loopback,
3096
3097         .new_ast_channel = my_new_ss7_ast_channel,
3098         .play_tone = my_ss7_play_tone,
3099
3100         .handle_link_exception = my_handle_link_exception,
3101         .set_alarm = my_set_alarm,
3102         .set_dialing = my_set_dialing,
3103         .set_outgoing = my_set_outgoing,
3104         .set_digital = my_set_digital,
3105         .set_inservice = my_set_inservice,
3106         .set_locallyblocked = my_set_locallyblocked,
3107         .set_remotelyblocked = my_set_remotelyblocked,
3108         .set_callerid = my_set_callerid,
3109         .set_dnid = my_set_dnid,
3110         .open_media = my_pri_ss7_open_media,
3111 };
3112 #endif  /* defined(HAVE_SS7) */
3113
3114 /*!
3115  * \brief Send MWI state change
3116  *
3117  * \arg mailbox_full This is the mailbox associated with the FXO line that the
3118  *      MWI state has changed on.
3119  * \arg thereornot This argument should simply be set to 1 or 0, to indicate
3120  *      whether there are messages waiting or not.
3121  *
3122  *  \return nothing
3123  *
3124  * This function does two things:
3125  *
3126  * 1) It generates an internal Asterisk event notifying any other module that
3127  *    cares about MWI that the state of a mailbox has changed.
3128  *
3129  * 2) It runs the script specified by the mwimonitornotify option to allow
3130  *    some custom handling of the state change.
3131  */
3132 static void notify_message(char *mailbox_full, int thereornot)
3133 {
3134         char s[sizeof(mwimonitornotify) + 80];
3135         char *mailbox, *context;
3136
3137         /* Strip off @default */
3138         context = mailbox = ast_strdupa(mailbox_full);
3139         strsep(&context, "@");
3140         if (ast_strlen_zero(context))
3141                 context = "default";
3142
3143         ast_publish_mwi_state(mailbox, context, thereornot, thereornot);
3144
3145         if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
3146                 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3147                 ast_safe_system(s);
3148         }
3149 }
3150
3151 static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
3152 {
3153         struct dahdi_pvt *p = pvt;
3154
3155         if (neon_mwievent > -1 && !p->mwimonitor_neon)
3156                 return;
3157
3158         if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3159                 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3160                 notify_message(p->mailbox, 1);
3161         } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3162                 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3163                 notify_message(p->mailbox, 0);
3164         }
3165         /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3166         /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3167         if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3168                 ast_hangup(chan);
3169                 return;
3170         }
3171 }
3172
3173 static int my_have_progressdetect(void *pvt)
3174 {
3175         struct dahdi_pvt *p = pvt;
3176
3177         if ((p->callprogress & CALLPROGRESS_PROGRESS)
3178                 && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3179                 return 1;
3180         } else {
3181                 /* Don't have progress detection. */
3182                 return 0;
3183         }
3184 }
3185
3186 struct analog_callback analog_callbacks =
3187 {
3188         .play_tone = my_play_tone,
3189         .get_event = my_get_event,
3190         .wait_event = my_wait_event,
3191         .is_off_hook = my_is_off_hook,
3192         .set_echocanceller = my_set_echocanceller,
3193         .ring = my_ring,
3194         .flash = my_flash,
3195         .off_hook = my_off_hook,
3196         .dial_digits = my_dial_digits,
3197         .train_echocanceller = my_train_echocanceller,
3198         .on_hook = my_on_hook,
3199         .is_dialing = my_is_dialing,
3200         .allocate_sub = my_allocate_sub,
3201         .unallocate_sub = my_unallocate_sub,
3202         .swap_subs = my_swap_subchannels,
3203         .has_voicemail = my_has_voicemail,
3204         .check_for_conference = my_check_for_conference,
3205         .conf_add = my_conf_add,
3206         .conf_del = my_conf_del,
3207         .complete_conference_update = my_complete_conference_update,
3208         .start = my_start,
3209         .all_subchannels_hungup = my_all_subchannels_hungup,
3210         .lock_private = my_lock_private,
3211         .unlock_private = my_unlock_private,
3212         .deadlock_avoidance_private = my_deadlock_avoidance_private,
3213         .handle_dtmf = my_handle_dtmf,
3214         .wink = my_wink,
3215         .new_ast_channel = my_new_analog_ast_channel,
3216         .dsp_set_digitmode = my_dsp_set_digitmode,
3217         .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3218         .send_callerid = my_send_callerid,
3219         .callwait = my_callwait,
3220         .stop_callwait = my_stop_callwait,
3221         .get_callerid = my_get_callerid,
3222         .start_cid_detect = my_start_cid_detect,
3223         .stop_cid_detect = my_stop_cid_detect,
3224         .handle_notify_message = my_handle_notify_message,
3225         .increase_ss_count = my_increase_ss_count,
3226         .decrease_ss_count = my_decrease_ss_count,
3227         .distinctive_ring = my_distinctive_ring,
3228         .set_linear_mode = my_set_linear_mode,
3229         .set_inthreeway = my_set_inthreeway,
3230         .get_and_handle_alarms = my_get_and_handle_alarms,
3231         .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
3232         .get_sub_fd = my_get_sub_fd,
3233         .set_cadence = my_set_cadence,
3234         .set_alarm = my_set_alarm,
3235         .set_dialing = my_set_dialing,
3236         .set_outgoing = my_set_outgoing,
3237         .set_ringtimeout = my_set_ringtimeout,