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