Asterisk - The Open Source Telephony Project  18.5.0
chan_dahdi.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Mark Spencer <[email protected]>
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 <[email protected]>
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  <depend>dahdi</depend>
47  <depend>tonezone</depend>
48  <use type="module">res_smdi</use>
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 #if defined(__NetBSD__) || defined(__FreeBSD__)
58 #include <pthread.h>
59 #else
60 #include <sys/sysmacros.h>
61 #endif
62 #include <signal.h>
63 #include <sys/stat.h>
64 #include <math.h>
65 
66 #include "sig_analog.h"
67 /* Analog signaling is currently still present in chan_dahdi for use with
68  * radio. Sig_analog does not currently handle any radio operations. If
69  * radio only uses analog signaling, then the radio handling logic could
70  * be placed in sig_analog and the duplicated code could be removed.
71  */
72 
73 #if defined(HAVE_PRI)
74 #include "sig_pri.h"
75 #ifndef PRI_RESTART
76 #error "Upgrade your libpri"
77 #endif
78 #endif /* defined(HAVE_PRI) */
79 
80 #if defined(HAVE_SS7)
81 #include "sig_ss7.h"
82 #if !defined(LIBSS7_ABI_COMPATIBILITY)
83 #error "Upgrade your libss7"
84 #elif LIBSS7_ABI_COMPATIBILITY != 2
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/mwi.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/devicestate.h"
122 #include "asterisk/paths.h"
123 #include "asterisk/ccss.h"
125 #include "asterisk/bridge.h"
127 #include "asterisk/parking.h"
128 #include "asterisk/format_cache.h"
129 #include "chan_dahdi.h"
131 
132 /*** DOCUMENTATION
133  <application name="DAHDISendKeypadFacility" language="en_US">
134  <synopsis>
135  Send digits out of band over a PRI.
136  </synopsis>
137  <syntax>
138  <parameter name="digits" required="true" />
139  </syntax>
140  <description>
141  <para>This application will send the given string of digits in a Keypad
142  Facility IE over the current channel.</para>
143  </description>
144  </application>
145  <application name="DAHDISendCallreroutingFacility" language="en_US">
146  <synopsis>
147  Send an ISDN call rerouting/deflection facility message.
148  </synopsis>
149  <syntax argsep=",">
150  <parameter name="destination" required="true">
151  <para>Destination number.</para>
152  </parameter>
153  <parameter name="original">
154  <para>Original called number.</para>
155  </parameter>
156  <parameter name="reason">
157  <para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
158  </parameter>
159  </syntax>
160  <description>
161  <para>This application will send an ISDN switch specific call
162  rerouting/deflection facility message over the current channel.
163  Supported switches depend upon the version of libpri in use.</para>
164  </description>
165  </application>
166  <application name="DAHDIAcceptR2Call" language="en_US">
167  <synopsis>
168  Accept an R2 call if its not already accepted (you still need to answer it)
169  </synopsis>
170  <syntax>
171  <parameter name="charge" required="true">
172  <para>Yes or No.</para>
173  <para>Whether you want to accept the call with charge or without charge.</para>
174  </parameter>
175  </syntax>
176  <description>
177  <para>This application will Accept the R2 call either with charge or no charge.</para>
178  </description>
179  </application>
180  <info name="CHANNEL" language="en_US" tech="DAHDI">
181  <enumlist>
182  <enum name="dahdi_channel">
183  <para>R/O DAHDI channel related to this channel.</para>
184  </enum>
185  <enum name="dahdi_span">
186  <para>R/O DAHDI span related to this channel.</para>
187  </enum>
188  <enum name="dahdi_group">
189  <para>R/O DAHDI logical group related to this channel.</para>
190  </enum>
191  <enum name="dahdi_type">
192  <para>R/O DAHDI channel type, one of:</para>
193  <enumlist>
194  <enum name="analog" />
195  <enum name="mfc/r2" />
196  <enum name="pri" />
197  <enum name="pseudo" />
198  <enum name="ss7" />
199  </enumlist>
200  </enum>
201  <enum name="keypad_digits">
202  <para>R/O PRI Keypad digits that came in with the SETUP message.</para>
203  </enum>
204  <enum name="reversecharge">
205  <para>R/O PRI Reverse Charging Indication, one of:</para>
206  <enumlist>
207  <enum name="-1"> <para>None</para></enum>
208  <enum name=" 1"> <para>Reverse Charging Requested</para></enum>
209  </enumlist>
210  </enum>
211  <enum name="no_media_path">
212  <para>R/O PRI Nonzero if the channel has no B channel.
213  The channel is either on hold or a call waiting call.</para>
214  </enum>
215  <enum name="buffers">
216  <para>W/O Change the channel's buffer policy (for the current call only)</para>
217  <para>This option takes two arguments:</para>
218  <para> Number of buffers,</para>
219  <para> Buffer policy being one of:</para>
220  <para> <literal>full</literal></para>
221  <para> <literal>immediate</literal></para>
222  <para> <literal>half</literal></para>
223  </enum>
224  <enum name="echocan_mode">
225  <para>W/O Change the configuration of the active echo
226  canceller on the channel (if any), for the current call
227  only.</para>
228  <para>Possible values are:</para>
229  <para> <literal>on</literal> Normal mode (the echo canceller is actually reinitalized)</para>
230  <para> <literal>off</literal> Disabled</para>
231  <para> <literal>fax</literal> FAX/data mode (NLP disabled if possible, otherwise
232  completely disabled)</para>
233  <para> <literal>voice</literal> Voice mode (returns from FAX mode, reverting the changes that were made)</para>
234  </enum>
235  </enumlist>
236  </info>
237  <manager name="DAHDITransfer" language="en_US">
238  <synopsis>
239  Transfer DAHDI Channel.
240  </synopsis>
241  <syntax>
242  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
243  <parameter name="DAHDIChannel" required="true">
244  <para>DAHDI channel number to transfer.</para>
245  </parameter>
246  </syntax>
247  <description>
248  <para>Simulate a flash hook event by the user connected to the channel.</para>
249  <note><para>Valid only for analog channels.</para></note>
250  </description>
251  </manager>
252  <manager name="DAHDIHangup" language="en_US">
253  <synopsis>
254  Hangup DAHDI Channel.
255  </synopsis>
256  <syntax>
257  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
258  <parameter name="DAHDIChannel" required="true">
259  <para>DAHDI channel number to hangup.</para>
260  </parameter>
261  </syntax>
262  <description>
263  <para>Simulate an on-hook event by the user connected to the channel.</para>
264  <note><para>Valid only for analog channels.</para></note>
265  </description>
266  </manager>
267  <manager name="DAHDIDialOffhook" language="en_US">
268  <synopsis>
269  Dial over DAHDI channel while offhook.
270  </synopsis>
271  <syntax>
272  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
273  <parameter name="DAHDIChannel" required="true">
274  <para>DAHDI channel number to dial digits.</para>
275  </parameter>
276  <parameter name="Number" required="true">
277  <para>Digits to dial.</para>
278  </parameter>
279  </syntax>
280  <description>
281  <para>Generate DTMF control frames to the bridged peer.</para>
282  </description>
283  </manager>
284  <manager name="DAHDIDNDon" language="en_US">
285  <synopsis>
286  Toggle DAHDI channel Do Not Disturb status ON.
287  </synopsis>
288  <syntax>
289  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
290  <parameter name="DAHDIChannel" required="true">
291  <para>DAHDI channel number to set DND on.</para>
292  </parameter>
293  </syntax>
294  <description>
295  <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
296  <note><para>Feature only supported by analog channels.</para></note>
297  </description>
298  </manager>
299  <manager name="DAHDIDNDoff" language="en_US">
300  <synopsis>
301  Toggle DAHDI channel Do Not Disturb status OFF.
302  </synopsis>
303  <syntax>
304  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
305  <parameter name="DAHDIChannel" required="true">
306  <para>DAHDI channel number to set DND off.</para>
307  </parameter>
308  </syntax>
309  <description>
310  <para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
311  <note><para>Feature only supported by analog channels.</para></note>
312  </description>
313  </manager>
314  <manager name="DAHDIShowChannels" language="en_US">
315  <synopsis>
316  Show status of DAHDI channels.
317  </synopsis>
318  <syntax>
319  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
320  <parameter name="DAHDIChannel">
321  <para>Specify the specific channel number to show. Show all channels if zero or not present.</para>
322  </parameter>
323  </syntax>
324  <description>
325  <para>Similar to the CLI command "dahdi show channels".</para>
326  </description>
327  </manager>
328  <manager name="DAHDIRestart" language="en_US">
329  <synopsis>
330  Fully Restart DAHDI channels (terminates calls).
331  </synopsis>
332  <syntax>
333  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
334  </syntax>
335  <description>
336  <para>Equivalent to the CLI command "dahdi restart".</para>
337  </description>
338  </manager>
339  <manager name="PRIShowSpans" language="en_US">
340  <synopsis>
341  Show status of PRI spans.
342  </synopsis>
343  <syntax>
344  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
345  <parameter name="Span">
346  <para>Specify the specific span to show. Show all spans if zero or not present.</para>
347  </parameter>
348  </syntax>
349  <description>
350  <para>Similar to the CLI command "pri show spans".</para>
351  </description>
352  </manager>
353  <manager name="PRIDebugSet" language="en_US">
354  <synopsis>
355  Set PRI debug levels for a span
356  </synopsis>
357  <syntax>
358  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
359  <parameter name="Span" required="true">
360  <para>Which span to affect.</para>
361  </parameter>
362  <parameter name="Level" required="true">
363  <para>What debug level to set. May be a numerical value or a text value from the list below</para>
364  <enumlist>
365  <enum name="off" />
366  <enum name="on" />
367  <enum name="hex" />
368  <enum name="intense" />
369  </enumlist>
370  </parameter>
371  </syntax>
372  <description>
373  <para>Equivalent to the CLI command "pri set debug &lt;level&gt; span &lt;span&gt;".</para>
374  </description>
375  </manager>
376  <manager name="PRIDebugFileSet" language="en_US">
377  <synopsis>
378  Set the file used for PRI debug message output
379  </synopsis>
380  <syntax>
381  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
382  <parameter name="File" required="true">
383  <para>Path of file to write debug output.</para>
384  </parameter>
385  </syntax>
386  <description>
387  <para>Equivalent to the CLI command "pri set debug file &lt;output-file&gt;"</para>
388  </description>
389  </manager>
390  <manager name="PRIDebugFileUnset" language="en_US">
391  <synopsis>
392  Disables file output for PRI debug messages
393  </synopsis>
394  <syntax>
395  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
396  </syntax>
397  </manager>
398  <managerEvent language="en_US" name="AlarmClear">
399  <managerEventInstance class="EVENT_FLAG_SYSTEM">
400  <synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
401  <syntax>
402  <parameter name="DAHDIChannel">
403  <para>The DAHDI channel on which the alarm was cleared.</para>
404  <note><para>This is not an Asterisk channel identifier.</para></note>
405  </parameter>
406  </syntax>
407  </managerEventInstance>
408  </managerEvent>
409  <managerEvent language="en_US" name="SpanAlarmClear">
410  <managerEventInstance class="EVENT_FLAG_SYSTEM">
411  <synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
412  <syntax>
413  <parameter name="Span">
414  <para>The span on which the alarm was cleared.</para>
415  </parameter>
416  </syntax>
417  </managerEventInstance>
418  </managerEvent>
419  <managerEvent language="en_US" name="DNDState">
420  <managerEventInstance class="EVENT_FLAG_SYSTEM">
421  <synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
422  <syntax>
423  <parameter name="DAHDIChannel">
424  <para>The DAHDI channel on which DND status changed.</para>
425  <note><para>This is not an Asterisk channel identifier.</para></note>
426  </parameter>
427  <parameter name="Status">
428  <enumlist>
429  <enum name="enabled"/>
430  <enum name="disabled"/>
431  </enumlist>
432  </parameter>
433  </syntax>
434  </managerEventInstance>
435  </managerEvent>
436  <managerEvent language="en_US" name="Alarm">
437  <managerEventInstance class="EVENT_FLAG_SYSTEM">
438  <synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
439  <syntax>
440  <parameter name="DAHDIChannel">
441  <para>The channel on which the alarm occurred.</para>
442  <note><para>This is not an Asterisk channel identifier.</para></note>
443  </parameter>
444  <parameter name="Alarm">
445  <para>A textual description of the alarm that occurred.</para>
446  </parameter>
447  </syntax>
448  </managerEventInstance>
449  </managerEvent>
450  <managerEvent language="en_US" name="SpanAlarm">
451  <managerEventInstance class="EVENT_FLAG_SYSTEM">
452  <synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
453  <syntax>
454  <parameter name="Span">
455  <para>The span on which the alarm occurred.</para>
456  </parameter>
457  <parameter name="Alarm">
458  <para>A textual description of the alarm that occurred.</para>
459  </parameter>
460  </syntax>
461  </managerEventInstance>
462  </managerEvent>
463  <managerEvent language="en_US" name="DAHDIChannel">
464  <managerEventInstance class="EVENT_FLAG_CALL">
465  <synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
466  <syntax>
467  <channel_snapshot/>
468  <parameter name="DAHDIGroup">
469  <para>The DAHDI logical group associated with this channel.</para>
470  </parameter>
471  <parameter name="DAHDISpan">
472  <para>The DAHDI span associated with this channel.</para>
473  </parameter>
474  <parameter name="DAHDIChannel">
475  <para>The DAHDI channel associated with this channel.</para>
476  </parameter>
477  </syntax>
478  </managerEventInstance>
479  </managerEvent>
480  ***/
481 
482 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
483 
484 static const char * const lbostr[] = {
485 "0 db (CSU)/0-133 feet (DSX-1)",
486 "133-266 feet (DSX-1)",
487 "266-399 feet (DSX-1)",
488 "399-533 feet (DSX-1)",
489 "533-655 feet (DSX-1)",
490 "-7.5db (CSU)",
491 "-15db (CSU)",
492 "-22.5db (CSU)"
493 };
494 
495 /*! Global jitterbuffer configuration - by default, jb is disabled
496  * \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
498 {
499  .flags = 0,
500  .max_size = 200,
501  .resync_threshold = 1000,
502  .impl = "fixed",
503  .target_extra = 40,
504 };
506 
507 /*!
508  * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
509  * the user hangs up to reset the state machine so ring works properly.
510  * This is used to be able to support kewlstart by putting the zhone in
511  * groundstart mode since their forward disconnect supervision is entirely
512  * broken even though their documentation says it isn't and their support
513  * is entirely unwilling to provide any assistance with their channel banks
514  * even though their web site says they support their products for life.
515  */
516 /* #define ZHONE_HACK */
517 
518 /*! \brief Typically, how many rings before we should send Caller*ID */
519 #define DEFAULT_CIDRINGS 1
520 
521 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
522 
523 
524 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
525 #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))
526 
527 static const char tdesc[] = "DAHDI Telephony"
528 #if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
529  " w/"
530  #if defined(HAVE_PRI)
531  "PRI"
532  #endif /* defined(HAVE_PRI) */
533  #if defined(HAVE_SS7)
534  #if defined(HAVE_PRI)
535  " & "
536  #endif /* defined(HAVE_PRI) */
537  "SS7"
538  #endif /* defined(HAVE_SS7) */
539  #if defined(HAVE_OPENR2)
540  #if defined(HAVE_PRI) || defined(HAVE_SS7)
541  " & "
542  #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
543  "MFC/R2"
544  #endif /* defined(HAVE_OPENR2) */
545 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
546 ;
547 
548 static const char config[] = "chan_dahdi.conf";
549 
550 #ifdef LOTS_OF_SPANS
551 #define NUM_SPANS DAHDI_MAX_SPANS
552 #else
553 #define NUM_SPANS 32
554 #endif
555 
556 #define CHAN_PSEUDO -2
557 
558 #define CALLPROGRESS_PROGRESS 1
559 #define CALLPROGRESS_FAX_OUTGOING 2
560 #define CALLPROGRESS_FAX_INCOMING 4
561 #define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
562 
563 #define NUM_CADENCE_MAX 25
564 static int num_cadence = 4;
566 
567 static int has_pseudo;
568 
569 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
570  { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
571  { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
572  { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
573  { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
574 };
575 
576 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
577  * is 1, the second pause is 2 and so on.
578  */
579 
580 static int cidrings[NUM_CADENCE_MAX] = {
581  2, /*!< Right after first long ring */
582  4, /*!< Right after long part */
583  3, /*!< After third chirp */
584  2, /*!< Second spell */
585 };
586 
587 /* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
588 static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
589 
590 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
591  (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
592 
593 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
594 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
595 
596 static char defaultcic[64] = "";
597 static char defaultozz[64] = "";
598 
599 /*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
600 static char mwimonitornotify[PATH_MAX] = "";
601 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI
602 static int mwisend_rpas = 0;
603 #endif
604 
605 static char progzone[10] = "";
606 
608 static int distinctiveringaftercid = 0;
609 
610 static int numbufs = 4;
611 
612 static int mwilevel = 512;
613 static int dtmfcid_level = 256;
614 
615 #define REPORT_CHANNEL_ALARMS 1
616 #define REPORT_SPAN_ALARMS 2
618 
619 #ifdef HAVE_PRI
620 static int pridebugfd = -1;
621 static char pridebugfilename[1024] = "";
622 #endif
623 
624 /*! \brief Protect the interface list (of dahdi_pvt's) */
626 
627 
628 static int ifcount = 0;
629 
630 #ifdef HAVE_PRI
631 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
632 #endif
633 
634 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
635  when it's doing something critical. */
637 
638 /*! \brief This is the thread for the monitor which checks for input on the channels
639  which are not currently in use. */
644 static int ss_thread_count = 0;
645 static int num_restart_pending = 0;
646 
647 static int restart_monitor(void);
648 
649 static int dahdi_sendtext(struct ast_channel *c, const char *text);
650 
651 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
652 static inline int dahdi_get_event(int fd)
653 {
654  int j;
655  if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
656  return -1;
657  return j;
658 }
659 
660 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
661 static inline int dahdi_wait_event(int fd)
662 {
663  int i, j = 0;
664  i = DAHDI_IOMUX_SIGEVENT;
665  if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
666  return -1;
667  if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
668  return -1;
669  return j;
670 }
671 
672 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
673 #define READ_SIZE 160
674 
675 #define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
676 #define MASK_INUSE (1 << 1) /*!< Channel currently in use */
677 
678 #define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE) /*!< 300 ms */
679 #define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
680 #define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) /*!< 100 ms */
681 #define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) /*!< 500 ms */
682 #define MIN_MS_SINCE_FLASH ((2000) ) /*!< 2000 ms */
683 #define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
684 #define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
685 
686 /*!
687  * \brief Configured ring timeout base.
688  * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
689  */
691 
692 #if defined(HAVE_SS7)
693 
694 struct dahdi_ss7 {
695  struct sig_ss7_linkset ss7;
696 };
697 
698 static struct dahdi_ss7 linksets[NUM_SPANS];
699 
700 static int cur_ss7type = -1;
701 static int cur_slc = -1;
702 static int cur_linkset = -1;
703 static int cur_pointcode = -1;
704 static int cur_cicbeginswith = -1;
705 static int cur_adjpointcode = -1;
706 static int cur_networkindicator = -1;
707 static int cur_defaultdpc = -1;
708 #endif /* defined(HAVE_SS7) */
709 
710 #ifdef HAVE_OPENR2
711 struct dahdi_mfcr2_conf {
712  openr2_variant_t variant;
713  int mfback_timeout;
714  int metering_pulse_timeout;
715  int max_ani;
716  int max_dnis;
717 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
718  int dtmf_time_on;
719  int dtmf_time_off;
720 #endif
721 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
722  int dtmf_end_timeout;
723 #endif
724  signed int get_ani_first:2;
725 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
726  signed int skip_category_request:2;
727 #endif
728  unsigned int call_files:1;
729  unsigned int allow_collect_calls:1;
730  unsigned int charge_calls:1;
731  unsigned int accept_on_offer:1;
732  unsigned int forced_release:1;
733  unsigned int double_answer:1;
734  signed int immediate_accept:2;
735 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
736  signed int dtmf_dialing:2;
737  signed int dtmf_detection:2;
738 #endif
739  char logdir[OR2_MAX_PATH];
740  char r2proto_file[OR2_MAX_PATH];
741  openr2_log_level_t loglevel;
742  openr2_calling_party_category_t category;
743 };
744 
745 /* MFC-R2 pseudo-link structure */
746 struct dahdi_mfcr2 {
747  int index; /*!< Unique index for CLI */
748  pthread_t r2master; /*!< Thread of master */
749  openr2_context_t *protocol_context; /*!< OpenR2 context handle */
750  struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
751  int numchans; /*!< Number of channels in this R2 block */
752  int live_chans; /*!< Number of unremoved channels in this R2 block */
753  int nodev; /*!< Link disconnected? */
754  struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */
755 };
756 
757 struct r2link_entry {
758  struct dahdi_mfcr2 mfcr2;
759  AST_LIST_ENTRY(r2link_entry) list;
760 };
761 static AST_LIST_HEAD_STATIC(r2links, r2link_entry);
762 static struct r2links nodev_r2links = AST_LIST_HEAD_INIT_VALUE;
763 
764 
765 /* how many r2links have been malloc'd */
766 static int r2links_count = 0;
767 
768 #endif /* HAVE_OPENR2 */
769 
770 #ifdef HAVE_PRI
771 
772 struct dahdi_pri {
773  int dchannels[SIG_PRI_NUM_DCHANS]; /*!< What channel are the dchannels on */
774  int mastertrunkgroup; /*!< What trunk group is our master */
775  int prilogicalspan; /*!< Logical span number within trunk group */
776  struct sig_pri_span pri;
777 };
778 
779 static struct dahdi_pri pris[NUM_SPANS];
780 
781 #if defined(HAVE_PRI_CCSS)
782 /*! DAHDI PRI CCSS agent and monitor type name. */
783 static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
784 #endif /* defined(HAVE_PRI_CCSS) */
785 
786 #else
787 /*! Shut up the compiler */
788 struct dahdi_pri;
789 #endif
790 
791 /* Polarity states */
792 #define POLARITY_IDLE 0
793 #define POLARITY_REV 1
794 
795 const char * const subnames[] = {
796  "Real",
797  "Callwait",
798  "Threeway"
799 };
800 
801 static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
802 static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
803 
804 #if defined(HAVE_PRI)
805 struct doomed_pri {
806  struct sig_pri_span *pri;
807  AST_LIST_ENTRY(doomed_pri) list;
808 };
809 static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
810 
811 static void pri_destroy_span(struct sig_pri_span *pri);
812 
813 static struct dahdi_parms_pseudo {
814  int buf_no; /*!< Number of buffers */
815  int buf_policy; /*!< Buffer policy */
816  int faxbuf_no; /*!< Number of Fax buffers */
817  int faxbuf_policy; /*!< Fax buffer policy */
818 } dahdi_pseudo_parms;
819 #endif /* defined(HAVE_PRI) */
820 
821 /*! \brief Channel configuration from chan_dahdi.conf .
822  * This struct is used for parsing the [channels] section of chan_dahdi.conf.
823  * Generally there is a field here for every possible configuration item.
824  *
825  * The state of fields is saved along the parsing and whenever a 'channel'
826  * statement is reached, the current dahdi_chan_conf is used to configure the
827  * channel (struct dahdi_pvt)
828  *
829  * \see dahdi_chan_init for the default values.
830  */
832  struct dahdi_pvt chan;
833 #ifdef HAVE_PRI
834  struct dahdi_pri pri;
835 #endif
836 
837 #if defined(HAVE_SS7)
838  struct dahdi_ss7 ss7;
839 #endif /* defined(HAVE_SS7) */
840 
841 #ifdef HAVE_OPENR2
842  struct dahdi_mfcr2_conf mfcr2;
843 #endif
844  struct dahdi_params timing;
845  int is_sig_auto; /*!< Use channel signalling from DAHDI? */
846  /*! Continue configuration even if a channel is not there. */
848 
849  /*!
850  * \brief The serial port to listen for SMDI data on
851  * \note Set from the "smdiport" string read in from chan_dahdi.conf
852  */
853  char smdi_port[SMDI_MAX_FILENAME_LEN];
854 
855  /*!
856  * \brief Don't create channels below this number
857  * \note by default is 0 (no limit)
858  */
860 
861  /*!
862  * \brief Don't create channels above this number (infinity by default)
863  * \note by default is 0 (special value that means "no limit").
864  */
866 };
867 
868 /*! returns a new dahdi_chan_conf with default values (by-value) */
870 {
871  /* recall that if a field is not included here it is initialized
872  * to 0 or equivalent
873  */
874  struct dahdi_chan_conf conf = {
875 #ifdef HAVE_PRI
876  .pri.pri = {
877  .nsf = PRI_NSF_NONE,
878  .switchtype = PRI_SWITCH_NI2,
879  .dialplan = PRI_UNKNOWN + 1,
880  .localdialplan = PRI_NATIONAL_ISDN + 1,
881  .nodetype = PRI_CPE,
882  .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
883 
884 #if defined(HAVE_PRI_CCSS)
885  .cc_ptmp_recall_mode = 1,/* specificRecall */
886  .cc_qsig_signaling_link_req = 1,/* retain */
887  .cc_qsig_signaling_link_rsp = 1,/* retain */
888 #endif /* defined(HAVE_PRI_CCSS) */
889 
890  .minunused = 2,
891  .idleext = "",
892  .idledial = "",
893  .internationalprefix = "",
894  .nationalprefix = "",
895  .localprefix = "",
896  .privateprefix = "",
897  .unknownprefix = "",
898  .colp_send = SIG_PRI_COLP_UPDATE,
899  .resetinterval = -1,
900  },
901 #endif
902 #if defined(HAVE_SS7)
903  .ss7.ss7 = {
904  .called_nai = SS7_NAI_NATIONAL,
905  .calling_nai = SS7_NAI_NATIONAL,
906  .internationalprefix = "",
907  .nationalprefix = "",
908  .subscriberprefix = "",
909  .unknownprefix = "",
910  .networkroutedprefix = ""
911  },
912 #endif /* defined(HAVE_SS7) */
913 #ifdef HAVE_OPENR2
914  .mfcr2 = {
915  .variant = OR2_VAR_ITU,
916  .mfback_timeout = -1,
917  .metering_pulse_timeout = -1,
918  .max_ani = 10,
919  .max_dnis = 4,
920  .get_ani_first = -1,
921 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
922  .skip_category_request = -1,
923 #endif
924  .call_files = 0,
925  .allow_collect_calls = 0,
926  .charge_calls = 1,
927  .accept_on_offer = 1,
928  .forced_release = 0,
929  .double_answer = 0,
930  .immediate_accept = -1,
931 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
932  .dtmf_dialing = -1,
933  .dtmf_detection = -1,
934  .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
935  .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
936 #endif
937 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
938  .dtmf_end_timeout = -1,
939 #endif
940  .logdir = "",
941  .r2proto_file = "",
942  .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
943  .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
944  },
945 #endif
946  .chan = {
947  .context = "default",
948  .cid_num = "",
949  .cid_name = "",
950  .cid_tag = "",
951  .mohinterpret = "default",
952  .mohsuggest = "",
953  .parkinglot = "",
954  .transfertobusy = 1,
955 
956  .cid_signalling = CID_SIG_BELL,
957  .cid_start = CID_START_RING,
958  .dahditrcallerid = 0,
959  .use_callerid = 1,
960  .sig = -1,
961  .outsigmod = -1,
962 
963  .cid_rxgain = +5.0,
964 
965  .tonezone = -1,
966 
967  .echocancel.head.tap_length = 1,
968 
969  .busycount = 3,
970 
971  .accountcode = "",
972 
973  .mailbox = "",
974 
975 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
976  .mwisend_fsk = 1,
977 #endif
978  .polarityonanswerdelay = 600,
979 
980  .sendcalleridafter = DEFAULT_CIDRINGS,
981 
982  .buf_policy = DAHDI_POLICY_IMMEDIATE,
983  .buf_no = numbufs,
984  .usefaxbuffers = 0,
985  .cc_params = ast_cc_config_params_init(),
986  .firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
987  .interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
988  .matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
989  },
990  .timing = {
991  .prewinktime = -1,
992  .preflashtime = -1,
993  .winktime = -1,
994  .flashtime = -1,
995  .starttime = -1,
996  .rxwinktime = -1,
997  .rxflashtime = -1,
998  .debouncetime = -1
999  },
1000  .is_sig_auto = 1,
1001  .ignore_failed_channels = 1,
1002  .smdi_port = "/dev/ttyS0",
1003  };
1004 
1005  return conf;
1006 }
1007 
1008 
1009 static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap,
1010  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
1011  const char *data, int *cause);
1012 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
1013 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
1014 static int dahdi_sendtext(struct ast_channel *c, const char *text);
1015 static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout);
1016 static int dahdi_hangup(struct ast_channel *ast);
1017 static int dahdi_answer(struct ast_channel *ast);
1018 static struct ast_frame *dahdi_read(struct ast_channel *ast);
1019 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
1020 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
1021 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
1022 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1023 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1024 static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
1025 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
1026 static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
1027 static int dahdi_devicestate(const char *data);
1028 static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
1029 
1030 static struct ast_channel_tech dahdi_tech = {
1031  .type = "DAHDI",
1032  .description = tdesc,
1033  .requester = dahdi_request,
1034  .send_digit_begin = dahdi_digit_begin,
1035  .send_digit_end = dahdi_digit_end,
1036  .send_text = dahdi_sendtext,
1037  .call = dahdi_call,
1038  .hangup = dahdi_hangup,
1039  .answer = dahdi_answer,
1040  .read = dahdi_read,
1041  .write = dahdi_write,
1042  .exception = dahdi_exception,
1043  .indicate = dahdi_indicate,
1044  .fixup = dahdi_fixup,
1045  .setoption = dahdi_setoption,
1046  .queryoption = dahdi_queryoption,
1047  .func_channel_read = dahdi_func_read,
1048  .func_channel_write = dahdi_func_write,
1049  .devicestate = dahdi_devicestate,
1050  .cc_callback = dahdi_cc_callback,
1051 };
1052 
1053 #define GET_CHANNEL(p) ((p)->channel)
1054 
1056 {
1057  switch (sig) {
1058  case SIG_FXOLS:
1059  return ANALOG_SIG_FXOLS;
1060  case SIG_FXOGS:
1061  return ANALOG_SIG_FXOGS;
1062  case SIG_FXOKS:
1063  return ANALOG_SIG_FXOKS;
1064  case SIG_FXSLS:
1065  return ANALOG_SIG_FXSLS;
1066  case SIG_FXSGS:
1067  return ANALOG_SIG_FXSGS;
1068  case SIG_FXSKS:
1069  return ANALOG_SIG_FXSKS;
1070  case SIG_EMWINK:
1071  return ANALOG_SIG_EMWINK;
1072  case SIG_EM:
1073  return ANALOG_SIG_EM;
1074  case SIG_EM_E1:
1075  return ANALOG_SIG_EM_E1;
1076  case SIG_FEATD:
1077  return ANALOG_SIG_FEATD;
1078  case SIG_FEATDMF:
1079  return ANALOG_SIG_FEATDMF;
1080  case SIG_E911:
1081  return SIG_E911;
1082  case SIG_FGC_CAMA:
1083  return ANALOG_SIG_FGC_CAMA;
1084  case SIG_FGC_CAMAMF:
1085  return ANALOG_SIG_FGC_CAMAMF;
1086  case SIG_FEATB:
1087  return ANALOG_SIG_FEATB;
1088  case SIG_SFWINK:
1089  return ANALOG_SIG_SFWINK;
1090  case SIG_SF:
1091  return ANALOG_SIG_SF;
1092  case SIG_SF_FEATD:
1093  return ANALOG_SIG_SF_FEATD;
1094  case SIG_SF_FEATDMF:
1095  return ANALOG_SIG_SF_FEATDMF;
1096  case SIG_FEATDMF_TA:
1097  return ANALOG_SIG_FEATDMF_TA;
1098  case SIG_SF_FEATB:
1099  return ANALOG_SIG_FEATB;
1100  default:
1101  return -1;
1102  }
1103 }
1104 
1105 
1107 {
1108  switch (tone) {
1109  case ANALOG_TONE_RINGTONE:
1110  return DAHDI_TONE_RINGTONE;
1111  case ANALOG_TONE_STUTTER:
1112  return DAHDI_TONE_STUTTER;
1114  return DAHDI_TONE_CONGESTION;
1115  case ANALOG_TONE_DIALTONE:
1116  return DAHDI_TONE_DIALTONE;
1118  return DAHDI_TONE_DIALRECALL;
1119  case ANALOG_TONE_INFO:
1120  return DAHDI_TONE_INFO;
1121  default:
1122  return -1;
1123  }
1124 }
1125 
1126 static int analogsub_to_dahdisub(enum analog_sub analogsub)
1127 {
1128  int index;
1129 
1130  switch (analogsub) {
1131  case ANALOG_SUB_REAL:
1132  index = SUB_REAL;
1133  break;
1134  case ANALOG_SUB_CALLWAIT:
1135  index = SUB_CALLWAIT;
1136  break;
1137  case ANALOG_SUB_THREEWAY:
1138  index = SUB_THREEWAY;
1139  break;
1140  default:
1141  ast_log(LOG_ERROR, "Unidentified sub!\n");
1142  index = SUB_REAL;
1143  }
1144 
1145  return index;
1146 }
1147 
1148 /*!
1149  * \internal
1150  * \brief release all members on the doomed pris list
1151  * \since 13.0
1152  *
1153  * Called priodically by the monitor threads to release spans marked for
1154  * removal.
1155  */
1156 static void release_doomed_pris(void)
1157 {
1158 #ifdef HAVE_PRI
1159  struct doomed_pri *entry;
1160 
1161  AST_LIST_LOCK(&doomed_pris);
1162  while ((entry = AST_LIST_REMOVE_HEAD(&doomed_pris, list))) {
1163  /* The span destruction must be done with this lock not held */
1164  AST_LIST_UNLOCK(&doomed_pris);
1165  ast_debug(4, "Destroying span %d from doomed queue.\n",
1166  entry->pri->span);
1167  pri_destroy_span(entry->pri);
1168  ast_free(entry);
1169  AST_LIST_LOCK(&doomed_pris);
1170  }
1171  AST_LIST_UNLOCK(&doomed_pris);
1172 #endif
1173 }
1174 
1175 #ifdef HAVE_PRI
1176 /*!
1177  * \brief Queue a span for destruction
1178  * \since 13.0
1179  *
1180  * \param pri the span to destroy
1181  *
1182  * Add a span to the list of spans to be destroyed later on
1183  * by the monitor thread. Allows destroying a span while holding its
1184  * lock.
1185  */
1186 static void pri_queue_for_destruction(struct sig_pri_span *pri)
1187 {
1188  struct doomed_pri *entry;
1189 
1190  AST_LIST_LOCK(&doomed_pris);
1191  AST_LIST_TRAVERSE(&doomed_pris, entry, list) {
1192  if (entry->pri == pri) {
1193  AST_LIST_UNLOCK(&doomed_pris);
1194  return;
1195  }
1196  }
1197  entry = ast_calloc(sizeof(struct doomed_pri), 1);
1198  if (!entry) {
1199  /* Nothing useful to do here. Panic? */
1200  ast_log(LOG_WARNING, "Failed allocating memory for a doomed_pri.\n");
1201  AST_LIST_UNLOCK(&doomed_pris);
1202  return;
1203  }
1204  entry->pri = pri;
1205  ast_debug(4, "Queue span %d for destruction.\n", pri->span);
1206  AST_LIST_INSERT_TAIL(&doomed_pris, entry, list);
1207  AST_LIST_UNLOCK(&doomed_pris);
1208 }
1209 #endif
1210 
1211 /*!
1212  * \internal
1213  * \brief Send a dial string to DAHDI.
1214  * \since 12.0.0
1215  *
1216  * \param pvt DAHDI private pointer
1217  * \param operation DAHDI dial operation to do to string
1218  * \param dial_str Dial string to send
1219  *
1220  * \retval 0 on success.
1221  * \retval non-zero on error.
1222  */
1223 static int dahdi_dial_str(struct dahdi_pvt *pvt, int operation, const char *dial_str)
1224 {
1225  int res;
1226  int offset;
1227  const char *pos;
1228  struct dahdi_dialoperation zo = {
1229  .op = operation,
1230  };
1231 
1232  /* Convert the W's to ww. */
1233  pos = dial_str;
1234  for (offset = 0; offset < sizeof(zo.dialstr) - 1; ++offset) {
1235  if (!*pos) {
1236  break;
1237  }
1238  if (*pos == 'W') {
1239  /* Convert 'W' to "ww" */
1240  ++pos;
1241  if (offset >= sizeof(zo.dialstr) - 3) {
1242  /* No room to expand */
1243  break;
1244  }
1245  zo.dialstr[offset] = 'w';
1246  ++offset;
1247  zo.dialstr[offset] = 'w';
1248  continue;
1249  }
1250  zo.dialstr[offset] = *pos++;
1251  }
1252  /* The zo initialization has already terminated the dialstr. */
1253 
1254  ast_debug(1, "Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1255  pvt->channel, dial_str, zo.dialstr);
1256  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo);
1257  if (res) {
1258  ast_log(LOG_WARNING, "Channel %d: Couldn't dial '%s': %s\n",
1259  pvt->channel, dial_str, strerror(errno));
1260  }
1261 
1262  return res;
1263 }
1264 
1266 static int bump_gains(struct dahdi_pvt *p);
1267 static int dahdi_setlinear(int dfd, int linear);
1268 
1269 static int my_start_cid_detect(void *pvt, int cid_signalling)
1270 {
1271  struct dahdi_pvt *p = pvt;
1272  int index = SUB_REAL;
1273  p->cs = callerid_new(cid_signalling);
1274  if (!p->cs) {
1275  ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1276  return -1;
1277  }
1278  bump_gains(p);
1279  dahdi_setlinear(p->subs[index].dfd, 0);
1280 
1281  return 0;
1282 }
1283 
1284 static int restore_gains(struct dahdi_pvt *p);
1285 
1286 static int my_stop_cid_detect(void *pvt)
1287 {
1288  struct dahdi_pvt *p = pvt;
1289  int index = SUB_REAL;
1290 
1291  if (p->cs) {
1292  callerid_free(p->cs);
1293  }
1294 
1295  /* Restore linear mode after Caller*ID processing */
1296  dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1297  restore_gains(p);
1298 
1299  return 0;
1300 }
1301 
1302 static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
1303 {
1304  struct dahdi_pvt *p = pvt;
1305  struct analog_pvt *analog_p = p->sig_pvt;
1306  struct pollfd poller;
1307  char *name, *num;
1308  int index = SUB_REAL;
1309  int res;
1310  unsigned char buf[256];
1311  int flags;
1312 
1313  poller.fd = p->subs[SUB_REAL].dfd;
1314  poller.events = POLLPRI | POLLIN;
1315  poller.revents = 0;
1316 
1317  res = poll(&poller, 1, timeout);
1318 
1319  if (poller.revents & POLLPRI) {
1321  return 1;
1322  }
1323 
1324  if (poller.revents & POLLIN) {
1325  /*** NOTES ***/
1326  /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1327  * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1328  * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1329  * a failure and die, and returning 2 means no event was received. */
1330  res = read(p->subs[index].dfd, buf, sizeof(buf));
1331  if (res < 0) {
1332  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1333  return -1;
1334  }
1335 
1336  if (analog_p->ringt > 0) {
1337  if (!(--analog_p->ringt)) {
1338  /* only return if we timeout from a ring event */
1339  return -1;
1340  }
1341  }
1342 
1343  if (p->cid_signalling == CID_SIG_V23_JP) {
1344  res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
1345  } else {
1346  res = callerid_feed(p->cs, buf, res, AST_LAW(p));
1347  }
1348  if (res < 0) {
1349  /*
1350  * The previous diagnostic message output likely
1351  * explains why it failed.
1352  */
1353  ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1354  return -1;
1355  }
1356 
1357  if (res == 1) {
1358  callerid_get(p->cs, &name, &num, &flags);
1359  if (name)
1360  ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1361  if (num)
1362  ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1363 
1364  ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1365  return 0;
1366  }
1367  }
1368 
1369  *ev = ANALOG_EVENT_NONE;
1370  return 2;
1371 }
1372 
1373 static const char *event2str(int event);
1374 
1375 static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
1376 {
1377  unsigned char buf[256];
1378  int distMatches;
1379  int curRingData[RING_PATTERNS];
1380  int receivedRingT;
1381  int counter1;
1382  int counter;
1383  int i;
1384  int res;
1385  int checkaftercid = 0;
1386  const char *matched_context;
1387  struct dahdi_pvt *p = pvt;
1388  struct analog_pvt *analog_p = p->sig_pvt;
1389 
1390  if (ringdata == NULL) {
1391  ringdata = curRingData;
1392  } else {
1393  checkaftercid = 1;
1394  }
1395 
1396  /* We must have a ring by now so lets try to listen for distinctive ringing */
1397  if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1398  /* Clear the current ring data array so we don't have old data in it. */
1399  for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1400  ringdata[receivedRingT] = 0;
1401  receivedRingT = 0;
1402 
1403  if (checkaftercid && distinctiveringaftercid) {
1404  ast_verb(3, "Detecting post-CID distinctive ring\n");
1405  }
1406 
1407  for (;;) {
1408  i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1409  res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i);
1410  if (res) {
1411  ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1412  ast_hangup(chan);
1413  return 1;
1414  }
1415  if (i & DAHDI_IOMUX_SIGEVENT) {
1416  res = dahdi_get_event(p->subs[idx].dfd);
1417  ast_debug(3, "Got event %d (%s)...\n", res, event2str(res));
1418  if (res == DAHDI_EVENT_NOALARM) {
1419  p->inalarm = 0;
1420  analog_p->inalarm = 0;
1421  } else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1422  /* Let us detect distinctive ring */
1423  ringdata[receivedRingT] = analog_p->ringt;
1424 
1425  if (analog_p->ringt < analog_p->ringt_base / 2) {
1426  break;
1427  }
1428  /* Increment the ringT counter so we can match it against
1429  values in chan_dahdi.conf for distinctive ring */
1430  if (++receivedRingT == RING_PATTERNS) {
1431  break;
1432  }
1433  }
1434  } else if (i & DAHDI_IOMUX_READ) {
1435  res = read(p->subs[idx].dfd, buf, sizeof(buf));
1436  if (res < 0) {
1437  if (errno != ELAST) {
1438  ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1439  ast_hangup(chan);
1440  return 1;
1441  }
1442  break;
1443  }
1444  if (analog_p->ringt > 0) {
1445  if (!(--analog_p->ringt)) {
1446  break;
1447  }
1448  }
1449  }
1450  }
1451  }
1452 
1453  /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1454  ast_verb(3, "Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1455  matched_context = p->defcontext;
1456  for (counter = 0; counter < 3; counter++) {
1457  int range = p->drings.ringnum[counter].range;
1458 
1459  distMatches = 0;
1460  ast_verb(3, "Checking %d,%d,%d with +/- %d range\n",
1461  p->drings.ringnum[counter].ring[0],
1462  p->drings.ringnum[counter].ring[1],
1463  p->drings.ringnum[counter].ring[2],
1464  range);
1465  for (counter1 = 0; counter1 < 3; counter1++) {
1466  int ring = p->drings.ringnum[counter].ring[counter1];
1467 
1468  if (ring == -1) {
1469  ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1470  ringdata[counter1]);
1471  distMatches++;
1472  } else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1473  ast_verb(3, "Ring pattern %d is in range: %d to %d\n",
1474  ringdata[counter1], ring - range, ring + range);
1475  distMatches++;
1476  } else {
1477  /* The current dring pattern cannot match. */
1478  break;
1479  }
1480  }
1481 
1482  if (distMatches == 3) {
1483  /* The ring matches, set the context to whatever is for distinctive ring.. */
1484  matched_context = S_OR(p->drings.ringContext[counter].contextData, p->defcontext);
1485  ast_verb(3, "Matched Distinctive Ring context %s\n", matched_context);
1486  break;
1487  }
1488  }
1489 
1490  /* Set selected distinctive ring context if not already set. */
1491  if (strcmp(p->context, matched_context) != 0) {
1492  ast_copy_string(p->context, matched_context, sizeof(p->context));
1493  ast_channel_context_set(chan, matched_context);
1494  }
1495 
1496  return 0;
1497 }
1498 
1499 static int my_stop_callwait(void *pvt)
1500 {
1501  struct dahdi_pvt *p = pvt;
1502  p->callwaitingrepeat = 0;
1503  p->cidcwexpire = 0;
1504  p->cid_suppress_expire = 0;
1505 
1506  return 0;
1507 }
1508 
1509 static int send_callerid(struct dahdi_pvt *p);
1510 static int save_conference(struct dahdi_pvt *p);
1511 static int restore_conference(struct dahdi_pvt *p);
1512 
1513 static int my_callwait(void *pvt)
1514 {
1515  struct dahdi_pvt *p = pvt;
1516 
1518  if (p->cidspill) {
1519  ast_log(LOG_WARNING, "Spill already exists?!?\n");
1520  ast_free(p->cidspill);
1521  }
1522 
1523  /*
1524  * SAS: Subscriber Alert Signal, 440Hz for 300ms
1525  * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1526  */
1527  if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1528  return -1;
1529  save_conference(p);
1530  /* Silence */
1531  memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1532  if (!p->callwaitrings && p->callwaitingcallerid) {
1533  ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
1534  p->callwaitcas = 1;
1535  p->cidlen = 2400 + 680 + READ_SIZE * 4;
1536  } else {
1537  ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
1538  p->callwaitcas = 0;
1539  p->cidlen = 2400 + READ_SIZE * 4;
1540  }
1541  p->cidpos = 0;
1542  send_callerid(p);
1543 
1544  return 0;
1545 }
1546 
1547 static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
1548 {
1549  struct dahdi_pvt *p = pvt;
1550 
1551  ast_debug(2, "Starting cid spill\n");
1552 
1553  if (p->cidspill) {
1554  ast_log(LOG_WARNING, "cidspill already exists??\n");
1555  ast_free(p->cidspill);
1556  }
1557 
1558  if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1559  if (cwcid == 0) {
1561  caller->id.name.str,
1562  caller->id.number.str,
1563  AST_LAW(p));
1564  } else {
1565  ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1566  caller->id.name.str, caller->id.number.str);
1567  p->callwaitcas = 0;
1568  p->cidcwexpire = 0;
1570  caller->id.name.str,
1571  caller->id.number.str,
1572  AST_LAW(p));
1573  p->cidlen += READ_SIZE * 4;
1574  }
1575  p->cidpos = 0;
1576  p->cid_suppress_expire = 0;
1577  send_callerid(p);
1578  }
1579  return 0;
1580 }
1581 
1582 static int my_dsp_reset_and_flush_digits(void *pvt)
1583 {
1584  struct dahdi_pvt *p = pvt;
1585  if (p->dsp)
1586  ast_dsp_digitreset(p->dsp);
1587 
1588  return 0;
1589 }
1590 
1591 static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
1592 {
1593  struct dahdi_pvt *p = pvt;
1594 
1595  if (p->channel == CHAN_PSEUDO)
1596  ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
1597 
1598  if (mode == ANALOG_DIGITMODE_DTMF) {
1599  /* If we do hardware dtmf, no need for a DSP */
1600  if (p->hardwaredtmf) {
1601  if (p->dsp) {
1602  ast_dsp_free(p->dsp);
1603  p->dsp = NULL;
1604  }
1605  return 0;
1606  }
1607 
1608  if (!p->dsp) {
1609  p->dsp = ast_dsp_new();
1610  if (!p->dsp) {
1611  ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1612  return -1;
1613  }
1614  }
1615 
1617  } else if (mode == ANALOG_DIGITMODE_MF) {
1618  if (!p->dsp) {
1619  p->dsp = ast_dsp_new();
1620  if (!p->dsp) {
1621  ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1622  return -1;
1623  }
1624  }
1626  }
1627  return 0;
1628 }
1629 
1630 static int dahdi_wink(struct dahdi_pvt *p, int index);
1631 
1632 static int my_wink(void *pvt, enum analog_sub sub)
1633 {
1634  struct dahdi_pvt *p = pvt;
1635  int index = analogsub_to_dahdisub(sub);
1636  if (index != SUB_REAL) {
1637  ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1638  }
1639  return dahdi_wink(p, index);
1640 }
1641 
1642 static void wakeup_sub(struct dahdi_pvt *p, int a);
1643 
1644 static int reset_conf(struct dahdi_pvt *p);
1645 
1646 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
1647 
1648 static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
1649 {
1650  struct ast_frame *f = *dest;
1651  struct dahdi_pvt *p = pvt;
1652  int idx = analogsub_to_dahdisub(analog_index);
1653 
1654  ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
1655  f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
1656  (unsigned)f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
1657 
1658  if (f->subclass.integer == 'f') {
1659  if (f->frametype == AST_FRAME_DTMF_END) {
1660  /* Fax tone -- Handle and return NULL */
1661  if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
1662  /* If faxbuffers are configured, use them for the fax transmission */
1663  if (p->usefaxbuffers && !p->bufferoverrideinuse) {
1664  struct dahdi_bufferinfo bi = {
1665  .txbufpolicy = p->faxbuf_policy,
1666  .bufsize = p->bufsize,
1667  .numbufs = p->faxbuf_no
1668  };
1669  int res;
1670 
1671  if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
1672  ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
1673  } else {
1674  p->bufferoverrideinuse = 1;
1675  }
1676  }
1677  p->faxhandled = 1;
1678  if (p->dsp) {
1681  ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
1682  }
1683  if (strcmp(ast_channel_exten(ast), "fax")) {
1684  const char *target_context = S_OR(ast_channel_macrocontext(ast), ast_channel_context(ast));
1685 
1686  /*
1687  * We need to unlock 'ast' here because ast_exists_extension has the
1688  * potential to start autoservice on the channel. Such action is prone
1689  * to deadlock if the channel is locked.
1690  *
1691  * ast_async_goto() has its own restriction on not holding the
1692  * channel lock.
1693  */
1694  ast_mutex_unlock(&p->lock);
1695  ast_channel_unlock(ast);
1696  if (ast_exists_extension(ast, target_context, "fax", 1,
1697  S_COR(ast_channel_caller(ast)->id.number.valid, ast_channel_caller(ast)->id.number.str, NULL))) {
1698  ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
1699  /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
1700  pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast_channel_exten(ast));
1701  if (ast_async_goto(ast, target_context, "fax", 1))
1702  ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
1703  } else {
1704  ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
1705  }
1706  ast_channel_lock(ast);
1707  ast_mutex_lock(&p->lock);
1708  } else {
1709  ast_debug(1, "Already in a fax extension, not redirecting\n");
1710  }
1711  } else {
1712  ast_debug(1, "Fax already handled\n");
1713  }
1714  dahdi_confmute(p, 0);
1715  }
1716  p->subs[idx].f.frametype = AST_FRAME_NULL;
1717  p->subs[idx].f.subclass.integer = 0;
1718  *dest = &p->subs[idx].f;
1719  }
1720 }
1721 
1722 static void my_lock_private(void *pvt)
1723 {
1724  struct dahdi_pvt *p = pvt;
1725  ast_mutex_lock(&p->lock);
1726 }
1727 
1728 static void my_unlock_private(void *pvt)
1729 {
1730  struct dahdi_pvt *p = pvt;
1731  ast_mutex_unlock(&p->lock);
1732 }
1733 
1734 static void my_deadlock_avoidance_private(void *pvt)
1735 {
1736  struct dahdi_pvt *p = pvt;
1737 
1738  DEADLOCK_AVOIDANCE(&p->lock);
1739 }
1740 
1742 {
1743  RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
1744  struct ast_channel_blob *obj = stasis_message_data(msg);
1745  struct ast_json *group, *span, *channel;
1746 
1747  channel_string = ast_manager_build_channel_state_string(obj->snapshot);
1748  if (!channel_string) {
1749  return NULL;
1750  }
1751 
1752  group = ast_json_object_get(obj->blob, "group");
1753  span = ast_json_object_get(obj->blob, "span");
1754  channel = ast_json_object_get(obj->blob, "channel");
1755 
1756  return ast_manager_event_blob_create(EVENT_FLAG_CALL, "DAHDIChannel",
1757  "%s"
1758  "DAHDIGroup: %llu\r\n"
1759  "DAHDISpan: %u\r\n"
1760  "DAHDIChannel: %s\r\n",
1761  ast_str_buffer(channel_string),
1763  (unsigned int)ast_json_integer_get(span),
1764  ast_json_string_get(channel));
1765 }
1766 
1767 STASIS_MESSAGE_TYPE_DEFN_LOCAL(dahdichannel_type,
1769  );
1770 
1771 /*! \brief Sends a DAHDIChannel channel blob used to produce DAHDIChannel AMI messages */
1772 static void publish_dahdichannel(struct ast_channel *chan, ast_group_t group, int span, const char *dahdi_channel)
1773 {
1774  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1775 
1776  ast_assert(dahdi_channel != NULL);
1777 
1778  blob = ast_json_pack("{s: I, s: i, s: s}",
1779  "group", (ast_json_int_t)group,
1780  "span", span,
1781  "channel", dahdi_channel);
1782  if (!blob) {
1783  return;
1784  }
1785 
1786  ast_channel_lock(chan);
1787  ast_channel_publish_blob(chan, dahdichannel_type(), blob);
1788  ast_channel_unlock(chan);
1789 }
1790 
1791 /*!
1792  * \internal
1793  * \brief Post an AMI DAHDI channel association event.
1794  * \since 1.8
1795  *
1796  * \param p DAHDI private pointer
1797  * \param chan Channel associated with the private pointer
1798  *
1799  * \return Nothing
1800  */
1801 static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
1802 {
1803  char ch_name[23];
1804 
1805  if (p->channel < CHAN_PSEUDO) {
1806  /* No B channel */
1807  snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
1808  } else if (p->channel == CHAN_PSEUDO) {
1809  /* Pseudo channel */
1810  strcpy(ch_name, "pseudo");
1811  } else {
1812  /* Real channel */
1813  snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
1814  }
1815  publish_dahdichannel(chan, p->group, p->span, ch_name);
1816 }
1817 
1818 #ifdef HAVE_PRI
1819 /*!
1820  * \internal
1821  * \brief Post an AMI DAHDI channel association event.
1822  * \since 1.8
1823  *
1824  * \param pvt DAHDI private pointer
1825  * \param chan Channel associated with the private pointer
1826  *
1827  * \return Nothing
1828  */
1829 static void my_ami_channel_event(void *pvt, struct ast_channel *chan)
1830 {
1831  struct dahdi_pvt *p = pvt;
1832 
1833  dahdi_ami_channel_event(p, chan);
1834 }
1835 #endif
1836 
1837 /* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
1838 * returns the last value of the linear setting
1839 */
1840 static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
1841 {
1842  struct dahdi_pvt *p = pvt;
1843  int oldval;
1844  int idx = analogsub_to_dahdisub(sub);
1845 
1846  dahdi_setlinear(p->subs[idx].dfd, linear_mode);
1847  oldval = p->subs[idx].linear;
1848  p->subs[idx].linear = linear_mode ? 1 : 0;
1849  return oldval;
1850 }
1851 
1852 static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
1853 {
1854  struct dahdi_pvt *p = pvt;
1855  int idx = analogsub_to_dahdisub(sub);
1856 
1857  p->subs[idx].inthreeway = inthreeway;
1858 }
1859 
1860 static int get_alarms(struct dahdi_pvt *p);
1861 static void handle_alarms(struct dahdi_pvt *p, int alms);
1862 static void my_get_and_handle_alarms(void *pvt)
1863 {
1864  int res;
1865  struct dahdi_pvt *p = pvt;
1866 
1867  res = get_alarms(p);
1868  handle_alarms(p, res);
1869 }
1870 
1871 static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
1872 {
1874 
1875  if (bridged && ast_channel_tech(bridged) == &dahdi_tech) {
1876  struct dahdi_pvt *p = ast_channel_tech_pvt(bridged);
1877 
1878  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
1879  return p->sig_pvt;
1880  }
1881  }
1882  return NULL;
1883 }
1884 
1885 static int my_get_sub_fd(void *pvt, enum analog_sub sub)
1886 {
1887  struct dahdi_pvt *p = pvt;
1888  int dahdi_sub = analogsub_to_dahdisub(sub);
1889  return p->subs[dahdi_sub].dfd;
1890 }
1891 
1892 static void my_set_cadence(void *pvt, int *cid_rings, struct ast_channel *ast)
1893 {
1894  struct dahdi_pvt *p = pvt;
1895 
1896  /* Choose proper cadence */
1897  if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
1898  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
1899  ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
1900  *cid_rings = cidrings[p->distinctivering - 1];
1901  } else {
1902  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
1903  ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
1904  *cid_rings = p->sendcalleridafter;
1905  }
1906 }
1907 
1908 static void my_set_alarm(void *pvt, int in_alarm)
1909 {
1910  struct dahdi_pvt *p = pvt;
1911 
1912  p->inalarm = in_alarm;
1913 }
1914 
1915 static void my_set_dialing(void *pvt, int is_dialing)
1916 {
1917  struct dahdi_pvt *p = pvt;
1918 
1919  p->dialing = is_dialing;
1920 }
1921 
1922 static void my_set_outgoing(void *pvt, int is_outgoing)
1923 {
1924  struct dahdi_pvt *p = pvt;
1925 
1926  p->outgoing = is_outgoing;
1927 }
1928 
1929 #if defined(HAVE_PRI) || defined(HAVE_SS7)
1930 static void my_set_digital(void *pvt, int is_digital)
1931 {
1932  struct dahdi_pvt *p = pvt;
1933 
1934  p->digital = is_digital;
1935 }
1936 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
1937 
1938 #if defined(HAVE_SS7)
1939 static void my_set_inservice(void *pvt, int is_inservice)
1940 {
1941  struct dahdi_pvt *p = pvt;
1942 
1943  p->inservice = is_inservice;
1944 }
1945 #endif /* defined(HAVE_SS7) */
1946 
1947 #if defined(HAVE_SS7)
1948 static void my_set_locallyblocked(void *pvt, int is_blocked)
1949 {
1950  struct dahdi_pvt *p = pvt;
1951 
1952  p->locallyblocked = is_blocked;
1953 }
1954 #endif /* defined(HAVE_SS7) */
1955 
1956 #if defined(HAVE_SS7)
1957 static void my_set_remotelyblocked(void *pvt, int is_blocked)
1958 {
1959  struct dahdi_pvt *p = pvt;
1960 
1961  p->remotelyblocked = is_blocked;
1962 }
1963 #endif /* defined(HAVE_SS7) */
1964 
1965 static void my_set_ringtimeout(void *pvt, int ringt)
1966 {
1967  struct dahdi_pvt *p = pvt;
1968  p->ringt = ringt;
1969 }
1970 
1971 static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
1972 {
1973  struct dahdi_pvt *p = pvt;
1974 
1975  if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
1976  ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
1977  gettimeofday(&p->waitingfordt, NULL);
1979  }
1980 }
1981 
1982 static int my_check_waitingfordt(void *pvt)
1983 {
1984  struct dahdi_pvt *p = pvt;
1985 
1986  if (p->waitingfordt.tv_sec) {
1987  return 1;
1988  }
1989 
1990  return 0;
1991 }
1992 
1993 static void my_set_confirmanswer(void *pvt, int flag)
1994 {
1995  struct dahdi_pvt *p = pvt;
1996  p->confirmanswer = flag;
1997 }
1998 
1999 static int my_check_confirmanswer(void *pvt)
2000 {
2001  struct dahdi_pvt *p = pvt;
2002  if (p->confirmanswer) {
2003  return 1;
2004  }
2005 
2006  return 0;
2007 }
2008 
2009 static void my_set_callwaiting(void *pvt, int callwaiting_enable)
2010 {
2011  struct dahdi_pvt *p = pvt;
2012 
2013  p->callwaiting = callwaiting_enable;
2014 }
2015 
2016 static void my_cancel_cidspill(void *pvt)
2017 {
2018  struct dahdi_pvt *p = pvt;
2019 
2020  ast_free(p->cidspill);
2021  p->cidspill = NULL;
2022  restore_conference(p);
2023 }
2024 
2025 static int my_confmute(void *pvt, int mute)
2026 {
2027  struct dahdi_pvt *p = pvt;
2028  return dahdi_confmute(p, mute);
2029 }
2030 
2031 static void my_set_pulsedial(void *pvt, int flag)
2032 {
2033  struct dahdi_pvt *p = pvt;
2034  p->pulsedial = flag;
2035 }
2036 
2037 static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
2038 {
2039  struct dahdi_pvt *p = pvt;
2040 
2041  p->owner = new_owner;
2042 }
2043 
2044 static const char *my_get_orig_dialstring(void *pvt)
2045 {
2046  struct dahdi_pvt *p = pvt;
2047 
2048  return p->dialstring;
2049 }
2050 
2051 static void my_increase_ss_count(void)
2052 {
2054  ss_thread_count++;
2056 }
2057 
2058 static void my_decrease_ss_count(void)
2059 {
2061  ss_thread_count--;
2064 }
2065 
2066 static void my_all_subchannels_hungup(void *pvt)
2067 {
2068  struct dahdi_pvt *p = pvt;
2069  int res, law;
2070 
2071  p->faxhandled = 0;
2072  p->didtdd = 0;
2073 
2074  if (p->dsp) {
2075  ast_dsp_free(p->dsp);
2076  p->dsp = NULL;
2077  }
2078 
2079  p->law = p->law_default;
2080  law = p->law_default;
2081  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2082  if (res < 0)
2083  ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2084 
2085  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2086 
2087 #if 1
2088  {
2089  int i;
2090  p->owner = NULL;
2091  /* Cleanup owners here */
2092  for (i = 0; i < 3; i++) {
2093  p->subs[i].owner = NULL;
2094  }
2095  }
2096 #endif
2097 
2098  reset_conf(p);
2099  if (num_restart_pending == 0) {
2100  restart_monitor();
2101  }
2102 }
2103 
2104 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
2105 
2106 static int my_conf_del(void *pvt, enum analog_sub sub)
2107 {
2108  struct dahdi_pvt *p = pvt;
2109  int x = analogsub_to_dahdisub(sub);
2110 
2111  return conf_del(p, &p->subs[x], x);
2112 }
2113 
2114 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
2115 
2116 static int my_conf_add(void *pvt, enum analog_sub sub)
2117 {
2118  struct dahdi_pvt *p = pvt;
2119  int x = analogsub_to_dahdisub(sub);
2120 
2121  return conf_add(p, &p->subs[x], x, 0);
2122 }
2123 
2124 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
2125 
2126 static int my_complete_conference_update(void *pvt, int needconference)
2127 {
2128  struct dahdi_pvt *p = pvt;
2129  int needconf = needconference;
2130  int x;
2131  int useslavenative;
2132  struct dahdi_pvt *slave = NULL;
2133 
2134  useslavenative = isslavenative(p, &slave);
2135 
2136  /* If we have a slave, add him to our conference now. or DAX
2137  if this is slave native */
2138  for (x = 0; x < MAX_SLAVES; x++) {
2139  if (p->slaves[x]) {
2140  if (useslavenative)
2141  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2142  else {
2143  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2144  needconf++;
2145  }
2146  }
2147  }
2148  /* If we're supposed to be in there, do so now */
2149  if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2150  if (useslavenative)
2151  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2152  else {
2153  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2154  needconf++;
2155  }
2156  }
2157  /* If we have a master, add ourselves to his conference */
2158  if (p->master) {
2159  if (isslavenative(p->master, NULL)) {
2161  } else {
2162  conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2163  }
2164  }
2165  if (!needconf) {
2166  /* Nobody is left (or should be left) in our conference.
2167  Kill it. */
2168  p->confno = -1;
2169  }
2170 
2171  return 0;
2172 }
2173 
2174 static int check_for_conference(struct dahdi_pvt *p);
2175 
2176 static int my_check_for_conference(void *pvt)
2177 {
2178  struct dahdi_pvt *p = pvt;
2179  return check_for_conference(p);
2180 }
2181 
2182 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)
2183 {
2184  struct dahdi_pvt *p = pvt;
2185  int da, db;
2186  int tchan;
2187  int tinthreeway;
2188 
2189  da = analogsub_to_dahdisub(a);
2190  db = analogsub_to_dahdisub(b);
2191 
2192  tchan = p->subs[da].chan;
2193  p->subs[da].chan = p->subs[db].chan;
2194  p->subs[db].chan = tchan;
2195 
2196  tinthreeway = p->subs[da].inthreeway;
2197  p->subs[da].inthreeway = p->subs[db].inthreeway;
2198  p->subs[db].inthreeway = tinthreeway;
2199 
2200  p->subs[da].owner = ast_a;
2201  p->subs[db].owner = ast_b;
2202 
2203  if (ast_a)
2204  ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2205  if (ast_b)
2206  ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2207 
2208  wakeup_sub(p, a);
2209  wakeup_sub(p, b);
2210 
2211  return;
2212 }
2213 
2214 /*!
2215  * \internal
2216  * \brief performs duties of dahdi_new, but also removes and possibly unbinds (if callid_created is 1) before returning
2217  * \note this variant of dahdi should only be used in conjunction with ast_callid_threadstorage_auto()
2218  *
2219  * \param callid_created value returned from ast_callid_threadstorage_auto()
2220  */
2221 static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid, int callid_created);
2222 
2223 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, ast_callid callid);
2224 
2225 static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
2226 {
2227  ast_callid callid = 0;
2228  int callid_created = ast_callid_threadstorage_auto(&callid);
2229  struct dahdi_pvt *p = pvt;
2230  int dsub = analogsub_to_dahdisub(sub);
2231 
2232  return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, NULL, requestor, callid, callid_created);
2233 }
2234 
2235 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2236 static int dahdi_setlaw(int dfd, int law)
2237 {
2238  int res;
2239  res = ioctl(dfd, DAHDI_SETLAW, &law);
2240  if (res)
2241  return res;
2242  return 0;
2243 }
2244 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2245 
2246 #if defined(HAVE_PRI)
2247 static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state,
2248  enum sig_pri_law law, char *exten, const struct ast_assigned_ids *assignedids,
2249  const struct ast_channel *requestor)
2250 {
2251  struct dahdi_pvt *p = pvt;
2252  int audio;
2253  int newlaw = -1;
2254  ast_callid callid = 0;
2255  int callid_created = ast_callid_threadstorage_auto(&callid);
2256 
2257  switch (p->sig) {
2259  if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
2260  /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
2261  break;
2262  }
2263  /* Fall through */
2264  default:
2265  /* Set to audio mode at this point */
2266  audio = 1;
2267  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
2268  ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
2269  p->channel, audio, strerror(errno));
2270  }
2271  break;
2272  }
2273 
2274  if (law != SIG_PRI_DEFLAW) {
2275  dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
2276  }
2277 
2278  ast_copy_string(p->exten, exten, sizeof(p->exten));
2279 
2280  switch (law) {
2281  case SIG_PRI_DEFLAW:
2282  newlaw = 0;
2283  break;
2284  case SIG_PRI_ALAW:
2285  newlaw = DAHDI_LAW_ALAW;
2286  break;
2287  case SIG_PRI_ULAW:
2288  newlaw = DAHDI_LAW_MULAW;
2289  break;
2290  }
2291 
2292  return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
2293 }
2294 #endif /* defined(HAVE_PRI) */
2295 
2296 static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
2297 
2298 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2299 /*!
2300  * \internal
2301  * \brief Open the PRI/SS7 channel media path.
2302  * \since 1.8
2303  *
2304  * \param p Channel private control structure.
2305  *
2306  * \return Nothing
2307  */
2308 static void my_pri_ss7_open_media(void *p)
2309 {
2310  struct dahdi_pvt *pvt = p;
2311  int res;
2312  int dfd;
2313  int set_val;
2314 
2315  dfd = pvt->subs[SUB_REAL].dfd;
2316 
2317  /* Open the media path. */
2318  set_val = 1;
2319  res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2320  if (res < 0) {
2321  ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
2322  pvt->channel, strerror(errno));
2323  }
2324 
2325  /* Set correct companding law for this call. */
2326  res = dahdi_setlaw(dfd, pvt->law);
2327  if (res < 0) {
2328  ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
2329  }
2330 
2331  /* Set correct gain for this call. */
2332  if (pvt->digital) {
2333  res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
2334  } else {
2335  res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
2336  pvt->law);
2337  }
2338  if (res < 0) {
2339  ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
2340  }
2341 
2342  if (pvt->dsp_features && pvt->dsp) {
2344  }
2345 }
2346 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2347 
2348 #if defined(HAVE_PRI)
2349 /*!
2350  * \internal
2351  * \brief Ask DAHDI to dial the given dial string.
2352  * \since 1.8.11
2353  *
2354  * \param p Channel private control structure.
2355  * \param dial_string String to pass to DAHDI to dial.
2356  *
2357  * \note The channel private lock needs to be held when calling.
2358  *
2359  * \return Nothing
2360  */
2361 static void my_pri_dial_digits(void *p, const char *dial_string)
2362 {
2363  char dial_str[DAHDI_MAX_DTMF_BUF];
2364  struct dahdi_pvt *pvt = p;
2365  int res;
2366 
2367  snprintf(dial_str, sizeof(dial_str), "T%s", dial_string);
2368  res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
2369  if (!res) {
2370  pvt->dialing = 1;
2371  }
2372 }
2373 #endif /* defined(HAVE_PRI) */
2374 
2375 static int unalloc_sub(struct dahdi_pvt *p, int x);
2376 
2377 static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
2378 {
2379  struct dahdi_pvt *p = pvt;
2380 
2381  return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2382 }
2383 
2384 static int alloc_sub(struct dahdi_pvt *p, int x);
2385 
2386 static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
2387 {
2388  struct dahdi_pvt *p = pvt;
2389 
2390  return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2391 }
2392 
2393 static int has_voicemail(struct dahdi_pvt *p);
2394 
2395 static int my_has_voicemail(void *pvt)
2396 {
2397  struct dahdi_pvt *p = pvt;
2398 
2399  return has_voicemail(p);
2400 }
2401 
2402 static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
2403 {
2404  struct dahdi_pvt *p = pvt;
2405  int index;
2406 
2407  index = analogsub_to_dahdisub(sub);
2408 
2409  return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2410 }
2411 
2413 {
2414  enum analog_event res;
2415 
2416  switch (event) {
2417  case DAHDI_EVENT_ONHOOK:
2418  res = ANALOG_EVENT_ONHOOK;
2419  break;
2420  case DAHDI_EVENT_RINGOFFHOOK:
2422  break;
2423  case DAHDI_EVENT_WINKFLASH:
2424  res = ANALOG_EVENT_WINKFLASH;
2425  break;
2426  case DAHDI_EVENT_ALARM:
2427  res = ANALOG_EVENT_ALARM;
2428  break;
2429  case DAHDI_EVENT_NOALARM:
2430  res = ANALOG_EVENT_NOALARM;
2431  break;
2432  case DAHDI_EVENT_DIALCOMPLETE:
2434  break;
2435  case DAHDI_EVENT_RINGERON:
2436  res = ANALOG_EVENT_RINGERON;
2437  break;
2438  case DAHDI_EVENT_RINGEROFF:
2439  res = ANALOG_EVENT_RINGEROFF;
2440  break;
2441  case DAHDI_EVENT_HOOKCOMPLETE:
2443  break;
2444  case DAHDI_EVENT_PULSE_START:
2446  break;
2447  case DAHDI_EVENT_POLARITY:
2448  res = ANALOG_EVENT_POLARITY;
2449  break;
2450  case DAHDI_EVENT_RINGBEGIN:
2451  res = ANALOG_EVENT_RINGBEGIN;
2452  break;
2453  case DAHDI_EVENT_EC_DISABLED:
2455  break;
2456  case DAHDI_EVENT_REMOVED:
2457  res = ANALOG_EVENT_REMOVED;
2458  break;
2459  case DAHDI_EVENT_NEONMWI_ACTIVE:
2461  break;
2462  case DAHDI_EVENT_NEONMWI_INACTIVE:
2464  break;
2465 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2466  case DAHDI_EVENT_TX_CED_DETECTED:
2468  break;
2469  case DAHDI_EVENT_RX_CED_DETECTED:
2471  break;
2472  case DAHDI_EVENT_EC_NLP_DISABLED:
2474  break;
2475  case DAHDI_EVENT_EC_NLP_ENABLED:
2477  break;
2478 #endif
2479  case DAHDI_EVENT_PULSEDIGIT:
2481  break;
2482  case DAHDI_EVENT_DTMFDOWN:
2483  res = ANALOG_EVENT_DTMFDOWN;
2484  break;
2485  case DAHDI_EVENT_DTMFUP:
2486  res = ANALOG_EVENT_DTMFUP;
2487  break;
2488  default:
2489  switch(event & 0xFFFF0000) {
2490  case DAHDI_EVENT_PULSEDIGIT:
2491  case DAHDI_EVENT_DTMFDOWN:
2492  case DAHDI_EVENT_DTMFUP:
2493  /* The event includes a digit number in the low word.
2494  * Converting it to a 'enum analog_event' would remove
2495  * that information. Thus it is returned as-is.
2496  */
2497  return event;
2498  }
2499 
2500  res = ANALOG_EVENT_ERROR;
2501  break;
2502  }
2503 
2504  return res;
2505 }
2506 
2507 static inline int dahdi_wait_event(int fd);
2508 
2509 static int my_wait_event(void *pvt)
2510 {
2511  struct dahdi_pvt *p = pvt;
2512 
2513  return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2514 }
2515 
2516 static int my_get_event(void *pvt)
2517 {
2518  struct dahdi_pvt *p = pvt;
2519  int res;
2520 
2521  if (p->fake_event) {
2522  res = p->fake_event;
2523  p->fake_event = 0;
2524  } else
2525  res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2526 
2527  return dahdievent_to_analogevent(res);
2528 }
2529 
2530 static int my_is_off_hook(void *pvt)
2531 {
2532  struct dahdi_pvt *p = pvt;
2533  int res;
2534  struct dahdi_params par;
2535 
2536  memset(&par, 0, sizeof(par));
2537 
2538  if (p->subs[SUB_REAL].dfd > -1)
2539  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2540  else {
2541  /* Assume not off hook on CVRS */
2542  res = 0;
2543  par.rxisoffhook = 0;
2544  }
2545  if (res) {
2546  ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2547  }
2548 
2549  if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2550  /* When "onhook" that means no battery on the line, and thus
2551  it is out of service..., if it's on a TDM card... If it's a channel
2552  bank, there is no telling... */
2553  return (par.rxbits > -1) || par.rxisoffhook;
2554  }
2555 
2556  return par.rxisoffhook;
2557 }
2558 
2559 static int my_set_echocanceller(void *pvt, int enable)
2560 {
2561  struct dahdi_pvt *p = pvt;
2562 
2563  if (enable)
2564  dahdi_ec_enable(p);
2565  else
2566  dahdi_ec_disable(p);
2567 
2568  return 0;
2569 }
2570 
2571 static int dahdi_ring_phone(struct dahdi_pvt *p);
2572 
2573 static int my_ring(void *pvt)
2574 {
2575  struct dahdi_pvt *p = pvt;
2576 
2577  return dahdi_ring_phone(p);
2578 }
2579 
2580 static int my_flash(void *pvt)
2581 {
2582  struct dahdi_pvt *p = pvt;
2583  int func = DAHDI_FLASH;
2584  return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2585 }
2586 
2587 static inline int dahdi_set_hook(int fd, int hs);
2588 
2589 static int my_off_hook(void *pvt)
2590 {
2591  struct dahdi_pvt *p = pvt;
2592  return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2593 }
2594 
2595 static void my_set_needringing(void *pvt, int value)
2596 {
2597  struct dahdi_pvt *p = pvt;
2599 }
2600 
2601 static void my_set_polarity(void *pvt, int value)
2602 {
2603  struct dahdi_pvt *p = pvt;
2604 
2605  if (p->channel == CHAN_PSEUDO) {
2606  return;
2607  }
2608  p->polarity = value;
2609  ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2610 }
2611 
2612 static void my_start_polarityswitch(void *pvt)
2613 {
2614  struct dahdi_pvt *p = pvt;
2615 
2617  my_set_polarity(pvt, 0);
2618  }
2619 }
2620 
2621 static void my_answer_polarityswitch(void *pvt)
2622 {
2623  struct dahdi_pvt *p = pvt;
2624 
2625  if (!p->answeronpolarityswitch) {
2626  return;
2627  }
2628 
2629  my_set_polarity(pvt, 1);
2630 }
2631 
2632 static void my_hangup_polarityswitch(void *pvt)
2633 {
2634  struct dahdi_pvt *p = pvt;
2635 
2636  if (!p->hanguponpolarityswitch) {
2637  return;
2638  }
2639 
2640  if (p->answeronpolarityswitch) {
2641  my_set_polarity(pvt, 0);
2642  } else {
2643  my_set_polarity(pvt, 1);
2644  }
2645 }
2646 
2647 static int my_start(void *pvt)
2648 {
2649  struct dahdi_pvt *p = pvt;
2650  int x = DAHDI_START;
2651 
2652  return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2653 }
2654 
2655 static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
2656 {
2657  struct dahdi_pvt *p = pvt;
2658 
2659  if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2660  ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2661  return -1;
2662  }
2663 
2664  if (sub != ANALOG_SUB_REAL) {
2665  ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %u\n",
2666  dop->dialstr, p->channel, sub);
2667  return -1;
2668  }
2669 
2670  return dahdi_dial_str(p, DAHDI_DIAL_OP_REPLACE, dop->dialstr);
2671 }
2672 
2673 static void dahdi_train_ec(struct dahdi_pvt *p);
2674 
2675 static int my_train_echocanceller(void *pvt)
2676 {
2677  struct dahdi_pvt *p = pvt;
2678 
2679  dahdi_train_ec(p);
2680 
2681  return 0;
2682 }
2683 
2684 static int my_is_dialing(void *pvt, enum analog_sub sub)
2685 {
2686  struct dahdi_pvt *p = pvt;
2687  int index;
2688  int x;
2689 
2690  index = analogsub_to_dahdisub(sub);
2691 
2692  if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
2693  ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
2694  return -1;
2695  }
2696 
2697  return x;
2698 }
2699 
2700 static int my_on_hook(void *pvt)
2701 {
2702  struct dahdi_pvt *p = pvt;
2703  return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
2704 }
2705 
2706 #if defined(HAVE_PRI)
2707 static void my_pri_fixup_chans(void *chan_old, void *chan_new)
2708 {
2709  struct dahdi_pvt *old_chan = chan_old;
2710  struct dahdi_pvt *new_chan = chan_new;
2711 
2712  new_chan->owner = old_chan->owner;
2713  old_chan->owner = NULL;
2714  if (new_chan->owner) {
2715  ast_channel_tech_pvt_set(new_chan->owner, new_chan);
2716  ast_channel_internal_fd_set(new_chan->owner, 0, new_chan->subs[SUB_REAL].dfd);
2717  new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
2718  old_chan->subs[SUB_REAL].owner = NULL;
2719  }
2720  /* Copy any DSP that may be present */
2721  new_chan->dsp = old_chan->dsp;
2722  new_chan->dsp_features = old_chan->dsp_features;
2723  old_chan->dsp = NULL;
2724  old_chan->dsp_features = 0;
2725 
2726  /* Transfer flags from the old channel. */
2727  new_chan->dialing = old_chan->dialing;
2728  new_chan->digital = old_chan->digital;
2729  new_chan->outgoing = old_chan->outgoing;
2730  old_chan->dialing = 0;
2731  old_chan->digital = 0;
2732  old_chan->outgoing = 0;
2733 
2734  /* More stuff to transfer to the new channel. */
2735  new_chan->law = old_chan->law;
2736  strcpy(new_chan->dialstring, old_chan->dialstring);
2737 }
2738 #endif /* defined(HAVE_PRI) */
2739 
2740 #if defined(HAVE_PRI)
2741 static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
2742 {
2743  switch (tone) {
2744  case SIG_PRI_TONE_RINGTONE:
2745  return DAHDI_TONE_RINGTONE;
2746  case SIG_PRI_TONE_STUTTER:
2747  return DAHDI_TONE_STUTTER;
2749  return DAHDI_TONE_CONGESTION;
2750  case SIG_PRI_TONE_DIALTONE:
2751  return DAHDI_TONE_DIALTONE;
2753  return DAHDI_TONE_DIALRECALL;
2754  case SIG_PRI_TONE_INFO:
2755  return DAHDI_TONE_INFO;
2756  case SIG_PRI_TONE_BUSY:
2757  return DAHDI_TONE_BUSY;
2758  default:
2759  return -1;
2760  }
2761 }
2762 #endif /* defined(HAVE_PRI) */
2763 
2764 #if defined(HAVE_PRI)
2765 static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
2766 {
2767  int x;
2768 
2769  ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
2770  switch (x) {
2771  case DAHDI_EVENT_NONE:
2772  break;
2773  case DAHDI_EVENT_ALARM:
2774  case DAHDI_EVENT_NOALARM:
2775  if (sig_pri_is_alarm_ignored(pri)) {
2776  break;
2777  }
2778  /* Fall through */
2779  default:
2780  ast_log(LOG_NOTICE, "Got DAHDI event: %s (%d) on D-channel of span %d\n",
2781  event2str(x), x, pri->span);
2782  break;
2783  }
2784  /* Keep track of alarm state */
2785  switch (x) {
2786  case DAHDI_EVENT_ALARM:
2787  pri_event_alarm(pri, index, 0);
2788  break;
2789  case DAHDI_EVENT_NOALARM:
2790  pri_event_noalarm(pri, index, 0);
2791  break;
2792  case DAHDI_EVENT_REMOVED:
2793  pri_queue_for_destruction(pri);
2794  break;
2795  default:
2796  break;
2797  }
2798 }
2799 #endif /* defined(HAVE_PRI) */
2800 
2801 #if defined(HAVE_PRI)
2802 static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
2803 {
2804  struct dahdi_pvt *p = pvt;
2805 
2806  return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
2807 }
2808 #endif /* defined(HAVE_PRI) */
2809 
2810 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2811 /*!
2812  * \internal
2813  * \brief Set the caller id information.
2814  * \since 1.8
2815  *
2816  * \param pvt DAHDI private structure
2817  * \param caller Caller-id information to set.
2818  *
2819  * \return Nothing
2820  */
2821 static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
2822 {
2823  struct dahdi_pvt *p = pvt;
2824 
2826  S_COR(caller->id.number.valid, caller->id.number.str, ""),
2827  sizeof(p->cid_num));
2829  S_COR(caller->id.name.valid, caller->id.name.str, ""),
2830  sizeof(p->cid_name));
2832  S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
2833  sizeof(p->cid_subaddr));
2834  p->cid_ton = caller->id.number.plan;
2835  p->callingpres = ast_party_id_presentation(&caller->id);
2836  if (caller->id.tag) {
2837  ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
2838  }
2839  ast_copy_string(p->cid_ani,
2840  S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
2841  sizeof(p->cid_ani));
2842  p->cid_ani2 = caller->ani2;
2843 }
2844 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2845 
2846 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2847 /*!
2848  * \internal
2849  * \brief Set the Dialed Number Identifier.
2850  * \since 1.8
2851  *
2852  * \param pvt DAHDI private structure
2853  * \param dnid Dialed Number Identifier string.
2854  *
2855  * \return Nothing
2856  */
2857 static void my_set_dnid(void *pvt, const char *dnid)
2858 {
2859  struct dahdi_pvt *p = pvt;
2860 
2861  ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
2862 }
2863 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2864 
2865 #if defined(HAVE_PRI)
2866 /*!
2867  * \internal
2868  * \brief Set the Redirecting Directory Number Information Service (RDNIS).
2869  * \since 1.8
2870  *
2871  * \param pvt DAHDI private structure
2872  * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
2873  *
2874  * \return Nothing
2875  */
2876 static void my_set_rdnis(void *pvt, const char *rdnis)
2877 {
2878  struct dahdi_pvt *p = pvt;
2879 
2880  ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
2881 }
2882 #endif /* defined(HAVE_PRI) */
2883 
2884 #if defined(HAVE_PRI)
2885 /*!
2886  * \internal
2887  * \brief Make a dialstring for native ISDN CC to recall properly.
2888  * \since 1.8
2889  *
2890  * \param priv Channel private control structure.
2891  * \param buf Where to put the modified dialstring.
2892  * \param buf_size Size of modified dialstring buffer.
2893  *
2894  * \details
2895  * original dialstring:
2896  * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2897  *
2898  * The modified dialstring will have prefixed the channel-group section
2899  * with the ISDN channel restriction.
2900  *
2901  * buf:
2902  * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2903  *
2904  * The routine will check to see if the ISDN channel restriction is already
2905  * in the original dialstring.
2906  *
2907  * \return Nothing
2908  */
2909 static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
2910 {
2911  char *dial;
2912  struct dahdi_pvt *pvt;
2914  AST_APP_ARG(tech); /* channel technology token */
2915  AST_APP_ARG(group); /* channel/group token */
2916  //AST_APP_ARG(ext); /* extension token */
2917  //AST_APP_ARG(opts); /* options token */
2918  //AST_APP_ARG(other); /* Any remining unused arguments */
2919  );
2920 
2921  pvt = priv;
2922  dial = ast_strdupa(pvt->dialstring);
2923  AST_NONSTANDARD_APP_ARGS(args, dial, '/');
2924  if (!args.tech) {
2925  ast_copy_string(buf, pvt->dialstring, buf_size);
2926  return;
2927  }
2928  if (!args.group) {
2929  /* Append the ISDN span channel restriction to the dialstring. */
2930  snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
2931  return;
2932  }
2933  if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
2934  /* The ISDN span channel restriction is not needed or already
2935  * in the dialstring. */
2936  ast_copy_string(buf, pvt->dialstring, buf_size);
2937  return;
2938  }
2939  /* Insert the ISDN span channel restriction into the dialstring. */
2940  snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
2941 }
2942 #endif /* defined(HAVE_PRI) */
2943 
2944 #if defined(HAVE_PRI)
2945 /*!
2946  * \internal
2947  * \brief Reevaluate the PRI span device state.
2948  * \since 1.8
2949  *
2950  * \param pri Asterisk D channel control structure.
2951  *
2952  * \return Nothing
2953  *
2954  * \note Assumes the pri->lock is already obtained.
2955  */
2956 static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
2957 {
2958  unsigned idx;
2959  unsigned num_b_chans; /* Number of B channels provisioned on the span. */
2960  unsigned in_use; /* Number of B channels in use on the span. */
2961  unsigned in_alarm; /* TRUE if the span is in alarm condition. */
2962  enum ast_device_state new_state;
2963 
2964  /* Count the number of B channels and the number of B channels in use. */
2965  num_b_chans = 0;
2966  in_use = 0;
2967  in_alarm = 1;
2968  for (idx = pri->numchans; idx--;) {
2969  if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
2970  /* This is a B channel interface. */
2971  ++num_b_chans;
2972  if (!sig_pri_is_chan_available(pri->pvts[idx])) {
2973  ++in_use;
2974  }
2975  if (!pri->pvts[idx]->inalarm) {
2976  /* There is a channel that is not in alarm. */
2977  in_alarm = 0;
2978  }
2979  }
2980  }
2981 
2982  /* Update the span congestion device state and report any change. */
2983  if (in_alarm) {
2984  new_state = AST_DEVICE_UNAVAILABLE;
2985  } else {
2986  new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
2987  }
2988  if (pri->congestion_devstate != new_state) {
2989  pri->congestion_devstate = new_state;
2991  }
2992 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
2993  /* Update the span threshold device state and report any change. */
2994  if (in_alarm) {
2995  new_state = AST_DEVICE_UNAVAILABLE;
2996  } else if (!in_use) {
2997  new_state = AST_DEVICE_NOT_INUSE;
2998  } else if (!pri->user_busy_threshold) {
2999  new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
3000  } else {
3001  new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
3002  : AST_DEVICE_BUSY;
3003  }
3004  if (pri->threshold_devstate != new_state) {
3005  pri->threshold_devstate = new_state;
3007  }
3008 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
3009 }
3010 #endif /* defined(HAVE_PRI) */
3011 
3012 #if defined(HAVE_PRI)
3013 /*!
3014  * \internal
3015  * \brief Reference this module.
3016  * \since 1.8
3017  *
3018  * \return Nothing
3019  */
3020 static void my_module_ref(void)
3021 {
3023 }
3024 #endif /* defined(HAVE_PRI) */
3025 
3026 #if defined(HAVE_PRI)
3027 /*!
3028  * \internal
3029  * \brief Unreference this module.
3030  * \since 1.8
3031  *
3032  * \return Nothing
3033  */
3034 static void my_module_unref(void)
3035 {
3037 }
3038 #endif /* defined(HAVE_PRI) */
3039 
3040 #if defined(HAVE_PRI)
3041 #if defined(HAVE_PRI_CALL_WAITING)
3042 static void my_pri_init_config(void *priv, struct sig_pri_span *pri);
3043 #endif /* defined(HAVE_PRI_CALL_WAITING) */
3044 static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri);
3045 
3046 struct sig_pri_callback sig_pri_callbacks =
3047 {
3048  .handle_dchan_exception = my_handle_dchan_exception,
3049  .play_tone = my_pri_play_tone,
3050  .set_echocanceller = my_set_echocanceller,
3051  .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3052  .lock_private = my_lock_private,
3053  .unlock_private = my_unlock_private,
3054  .deadlock_avoidance_private = my_deadlock_avoidance_private,
3055  .new_ast_channel = my_new_pri_ast_channel,
3056  .fixup_chans = my_pri_fixup_chans,
3057  .set_alarm = my_set_alarm,
3058  .set_dialing = my_set_dialing,
3059  .set_outgoing = my_set_outgoing,
3060  .set_digital = my_set_digital,
3061  .set_callerid = my_set_callerid,
3062  .set_dnid = my_set_dnid,
3063  .set_rdnis = my_set_rdnis,
3064  .new_nobch_intf = dahdi_new_pri_nobch_channel,
3065 #if defined(HAVE_PRI_CALL_WAITING)
3066  .init_config = my_pri_init_config,
3067 #endif /* defined(HAVE_PRI_CALL_WAITING) */
3068  .get_orig_dialstring = my_get_orig_dialstring,
3069  .make_cc_dialstring = my_pri_make_cc_dialstring,
3070  .update_span_devstate = dahdi_pri_update_span_devstate,
3071  .module_ref = my_module_ref,
3072  .module_unref = my_module_unref,
3073  .dial_digits = my_pri_dial_digits,
3074  .open_media = my_pri_ss7_open_media,
3075  .ami_channel_event = my_ami_channel_event,
3076  .destroy_later = pri_queue_for_destruction,
3077 };
3078 #endif /* defined(HAVE_PRI) */
3079 
3080 #if defined(HAVE_SS7)
3081 /*!
3082  * \internal
3083  * \brief Handle the SS7 link exception.
3084  * \since 1.8
3085  *
3086  * \param linkset Controlling linkset for the channel.
3087  * \param which Link index of the signaling channel.
3088  *
3089  * \return Nothing
3090  */
3091 static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
3092 {
3093  int event;
3094 
3095  if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
3096  ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
3097  linkset->span, which);
3098  return;
3099  }
3100  switch (event) {
3101  case DAHDI_EVENT_NONE:
3102  break;
3103  case DAHDI_EVENT_ALARM:
3104  ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3105  event2str(event), event, linkset->span, which);
3106  sig_ss7_link_alarm(linkset, which);
3107  break;
3108  case DAHDI_EVENT_NOALARM:
3109  ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3110  event2str(event), event, linkset->span, which);
3111  sig_ss7_link_noalarm(linkset, which);
3112  break;
3113  default:
3114  ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
3115  event2str(event), event, linkset->span, which);
3116  break;
3117  }
3118 }
3119 #endif /* defined(HAVE_SS7) */
3120 
3121 #if defined(HAVE_SS7)
3122 static void my_ss7_set_loopback(void *pvt, int enable)
3123 {
3124  struct dahdi_pvt *p = pvt;
3125 
3126  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
3127  ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
3128  strerror(errno));
3129  }
3130 }
3131 #endif /* defined(HAVE_SS7) */
3132 
3133 #if defined(HAVE_SS7)
3134 /*!
3135  * \internal
3136  * \brief Find the linkset to which SS7 belongs.
3137  * \since 11.0
3138  *
3139  * \param ss7 structure to match on.
3140  *
3141  * \retval linkset if found.
3142  * \retval NULL if not found.
3143  */
3144 static struct sig_ss7_linkset *my_ss7_find_linkset(struct ss7 *ss7)
3145 {
3146  int idx;
3147 
3148  if (!ss7) {
3149  return NULL;
3150  }
3151 
3152  for (idx = 0; idx < NUM_SPANS; ++idx) {
3153  if (linksets[idx].ss7.ss7 == ss7) {
3154  return &linksets[idx].ss7;
3155  }
3156  }
3157  return NULL;
3158 }
3159 #endif /* defined(HAVE_SS7) */
3160 
3161 #if defined(HAVE_SS7)
3162 /*!
3163  * \internal
3164  * \brief Create a new asterisk channel structure for SS7.
3165  * \since 1.8
3166  *
3167  * \param pvt Private channel structure.
3168  * \param state Initial state of new channel.
3169  * \param law Combanding law to use.
3170  * \param exten Dialplan extension for incoming call.
3171  * \param requestor Channel requesting this new channel.
3172  *
3173  * \retval ast_channel on success.
3174  * \retval NULL on error.
3175  */
3176 static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
3177 {
3178  struct dahdi_pvt *p = pvt;
3179  int audio;
3180  int newlaw;
3181  ast_callid callid = 0;
3182  int callid_created = ast_callid_threadstorage_auto(&callid);
3183 
3184  /* Set to audio mode at this point */
3185  audio = 1;
3186  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
3187  ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
3188  p->channel, audio, strerror(errno));
3189 
3190  if (law != SIG_SS7_DEFLAW) {
3191  dahdi_setlaw(p->subs[SUB_REAL].dfd,
3192  (law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
3193  }
3194 
3195  ast_copy_string(p->exten, exten, sizeof(p->exten));
3196 
3197  newlaw = -1;
3198  switch (law) {
3199  case SIG_SS7_DEFLAW:
3200  newlaw = 0;
3201  break;
3202  case SIG_SS7_ALAW:
3203  newlaw = DAHDI_LAW_ALAW;
3204  break;
3205  case SIG_SS7_ULAW:
3206  newlaw = DAHDI_LAW_MULAW;
3207  break;
3208  }
3209  return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
3210 }
3211 #endif /* defined(HAVE_SS7) */
3212 
3213 #if defined(HAVE_SS7)
3214 static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
3215 {
3216  switch (tone) {
3217  case SIG_SS7_TONE_RINGTONE:
3218  return DAHDI_TONE_RINGTONE;
3219  case SIG_SS7_TONE_STUTTER:
3220  return DAHDI_TONE_STUTTER;
3222  return DAHDI_TONE_CONGESTION;
3223  case SIG_SS7_TONE_DIALTONE:
3224  return DAHDI_TONE_DIALTONE;
3226  return DAHDI_TONE_DIALRECALL;
3227  case SIG_SS7_TONE_INFO:
3228  return DAHDI_TONE_INFO;
3229  case SIG_SS7_TONE_BUSY:
3230  return DAHDI_TONE_BUSY;
3231  default:
3232  return -1;
3233  }
3234 }
3235 #endif /* defined(HAVE_SS7) */
3236 
3237 #if defined(HAVE_SS7)
3238 static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
3239 {
3240  struct dahdi_pvt *p = pvt;
3241 
3242  return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
3243 }
3244 #endif /* defined(HAVE_SS7) */
3245 
3246 #if defined(HAVE_SS7)
3247 struct sig_ss7_callback sig_ss7_callbacks =
3248 {
3250  .unlock_private = my_unlock_private,
3251  .deadlock_avoidance_private = my_deadlock_avoidance_private,
3252 
3253  .set_echocanceller = my_set_echocanceller,
3254  .set_loopback = my_ss7_set_loopback,
3255 
3256  .new_ast_channel = my_new_ss7_ast_channel,
3257  .play_tone = my_ss7_play_tone,
3258 
3259  .handle_link_exception = my_handle_link_exception,
3260  .set_alarm = my_set_alarm,
3261  .set_dialing = my_set_dialing,
3262  .set_outgoing = my_set_outgoing,
3263  .set_digital = my_set_digital,
3264  .set_inservice = my_set_inservice,
3265  .set_locallyblocked = my_set_locallyblocked,
3266  .set_remotelyblocked = my_set_remotelyblocked,
3267  .set_callerid = my_set_callerid,
3268  .set_dnid = my_set_dnid,
3269  .open_media = my_pri_ss7_open_media,
3270  .find_linkset = my_ss7_find_linkset,
3271 };
3272 #endif /* defined(HAVE_SS7) */
3273 
3274 /*!
3275  * \brief Send MWI state change
3276  *
3277  * \param mailbox This is the mailbox associated with the FXO line that the
3278  * MWI state has changed on.
3279  * \param thereornot This argument should simply be set to 1 or 0, to indicate
3280  * whether there are messages waiting or not.
3281  *
3282  * \return nothing
3283  *
3284  * This function does two things:
3285  *
3286  * 1) It generates an internal Asterisk event notifying any other module that
3287  * cares about MWI that the state of a mailbox has changed.
3288  *
3289  * 2) It runs the script specified by the mwimonitornotify option to allow
3290  * some custom handling of the state change.
3291  */
3292 static void notify_message(char *mailbox, int thereornot)
3293 {
3294  char s[sizeof(mwimonitornotify) + 80];
3295 
3296  if (ast_strlen_zero(mailbox)) {
3297  return;
3298  }
3299 
3300  ast_publish_mwi_state(mailbox, NULL, thereornot, thereornot);
3302  snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3303  ast_safe_system(s);
3304  }
3305 }
3306 
3307 static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
3308 {
3309  struct dahdi_pvt *p = pvt;
3310 
3311  if (neon_mwievent > -1 && !p->mwimonitor_neon)
3312  return;
3313 
3314  if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3315  ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3316  notify_message(p->mailbox, 1);
3317  } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3318  ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3319  notify_message(p->mailbox, 0);
3320  }
3321  /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3322  /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3323  if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3324  ast_hangup(chan);
3325  return;
3326  }
3327 }
3328 
3329 static int my_have_progressdetect(void *pvt)
3330 {
3331  struct dahdi_pvt *p = pvt;
3332 
3334  && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3335  return 1;
3336  } else {
3337  /* Don't have progress detection. */
3338  return 0;
3339  }
3340 }
3341 
3342 #define gen_pvt_field_callback(type, field) \
3343  static type my_get_##field(void *pvt) \
3344  { \
3345  struct dahdi_pvt *p = pvt; \
3346  return p->field; \
3347  }
3348 
3352 
3353 #undef gen_pvt_field_callback
3354 
3356 {
3358  .get_event = my_get_event,
3359  .wait_event = my_wait_event,
3360  .is_off_hook = my_is_off_hook,
3361  .set_echocanceller = my_set_echocanceller,
3362  .ring = my_ring,
3363  .flash = my_flash,
3364  .off_hook = my_off_hook,
3365  .dial_digits = my_dial_digits,
3366  .train_echocanceller = my_train_echocanceller,
3367  .on_hook = my_on_hook,
3368  .is_dialing = my_is_dialing,
3369  .allocate_sub = my_allocate_sub,
3370  .unallocate_sub = my_unallocate_sub,
3371  .swap_subs = my_swap_subchannels,
3372  .has_voicemail = my_has_voicemail,
3373  .check_for_conference = my_check_for_conference,
3374  .conf_add = my_conf_add,
3375  .conf_del = my_conf_del,
3376  .complete_conference_update = my_complete_conference_update,
3377  .start = my_start,
3378  .all_subchannels_hungup = my_all_subchannels_hungup,
3379  .lock_private = my_lock_private,
3380  .unlock_private = my_unlock_private,
3381  .deadlock_avoidance_private = my_deadlock_avoidance_private,
3382  .handle_dtmf = my_handle_dtmf,
3383  .wink = my_wink,
3384  .new_ast_channel = my_new_analog_ast_channel,
3385  .dsp_set_digitmode = my_dsp_set_digitmode,
3386  .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3387  .send_callerid = my_send_callerid,
3388  .callwait = my_callwait,
3389  .stop_callwait = my_stop_callwait,
3390  .get_callerid = my_get_callerid,
3391  .start_cid_detect = my_start_cid_detect,
3392  .stop_cid_detect = my_stop_cid_detect,
3393  .handle_notify_message = my_handle_notify_message,
3394  .increase_ss_count = my_increase_ss_count,
3395  .decrease_ss_count = my_decrease_ss_count,
3396  .distinctive_ring = my_distinctive_ring,
3397  .set_linear_mode = my_set_linear_mode,
3398  .set_inthreeway = my_set_inthreeway,
3399  .get_and_handle_alarms = my_get_and_handle_alarms,
3400  .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
3401  .get_sub_fd = my_get_sub_fd,
3402  .set_cadence = my_set_cadence,
3403  .set_alarm = my_set_alarm,
3404  .set_dialing = my_set_dialing,
3405  .set_outgoing = my_set_outgoing,
3406  .set_ringtimeout = my_set_ringtimeout,
3407  .set_waitingfordt = my_set_waitingfordt,
3408  .check_waitingfordt = my_check_waitingfordt,
3409  .set_confirmanswer = my_set_confirmanswer,
3410  .check_confirmanswer = my_check_confirmanswer,
3411  .set_callwaiting = my_set_callwaiting,
3412  .cancel_cidspill = my_cancel_cidspill,
3413  .confmute = my_confmute,
3414  .set_pulsedial = my_set_pulsedial,
3415  .set_new_owner = my_set_new_owner,
3416  .get_orig_dialstring = my_get_orig_dialstring,
3417  .set_needringing = my_set_needringing,
3418  .set_polarity = my_set_polarity,
3419  .start_polarityswitch = my_start_polarityswitch,
3420  .answer_polarityswitch = my_answer_polarityswitch,
3421  .hangup_polarityswitch = my_hangup_polarityswitch,
3422  .have_progressdetect = my_have_progressdetect,
3423  .get_firstdigit_timeout = my_get_firstdigit_timeout,
3424  .get_matchdigit_timeout = my_get_matchdigit_timeout,
3425  .get_interdigit_timeout = my_get_interdigit_timeout,
3426 };
3427 
3428 /*! Round robin search locations. */
3429 static struct dahdi_pvt *round_robin[32];
3430 
3431 int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
3432 {
3433  int res;
3434  if (p->subs[SUB_REAL].owner == ast)
3435  res = 0;
3436  else if (p->subs[SUB_CALLWAIT].owner == ast)
3437  res = 1;
3438  else if (p->subs[SUB_THREEWAY].owner == ast)
3439  res = 2;
3440  else {
3441  res = -1;
3442  if (!nullok)
3444  "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3445  ast ? ast_channel_name(ast) : "", p->channel, fname, line);
3446  }
3447  return res;
3448 }
3449 
3450 /*!
3451  * \internal
3452  * \brief Obtain the specified subchannel owner lock if the owner exists.
3453  *
3454  * \param pvt Channel private struct.
3455  * \param sub_idx Subchannel owner to lock.
3456  *
3457  * \note Assumes the pvt->lock is already obtained.
3458  *
3459  * \note
3460  * Because deadlock avoidance may have been necessary, you need to confirm
3461  * the state of things before continuing.
3462  *
3463  * \return Nothing
3464  */
3465 static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
3466 {
3467  for (;;) {
3468  if (!pvt->subs[sub_idx].owner) {
3469  /* No subchannel owner pointer */
3470  break;
3471  }
3472  if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
3473  /* Got subchannel owner lock */
3474  break;
3475  }
3476  /* We must unlock the private to avoid the possibility of a deadlock */
3477  DEADLOCK_AVOIDANCE(&pvt->lock);
3478  }
3479 }
3480 
3481 static void wakeup_sub(struct dahdi_pvt *p, int a)
3482 {
3483  dahdi_lock_sub_owner(p, a);
3484  if (p->subs[a].owner) {
3486  ast_channel_unlock(p->subs[a].owner);
3487  }
3488 }
3489 
3490 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
3491 {
3492  for (;;) {
3493  if (p->owner) {
3494  if (ast_channel_trylock(p->owner)) {
3495  DEADLOCK_AVOIDANCE(&p->lock);
3496  } else {
3497  ast_queue_frame(p->owner, f);
3499  break;
3500  }
3501  } else
3502  break;
3503  }
3504 }
3505 
3507 {
3508  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3509  RAII_VAR(struct ast_str *, dahdi_chan, ast_str_create(32), ast_free);
3510  if (!dahdi_chan) {
3511  return;
3512  }
3513 
3514  ast_str_set(&dahdi_chan, 0, "%d", channel);
3515  ast_log(LOG_NOTICE, "Alarm cleared on channel DAHDI/%d\n", channel);
3516  body = ast_json_pack("{s: s}", "DAHDIChannel", ast_str_buffer(dahdi_chan));
3517  if (!body) {
3518  return;
3519  }
3520 
3521  ast_manager_publish_event("AlarmClear", EVENT_FLAG_SYSTEM, body);
3522 }
3523 
3525 {
3526  RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
3527 
3528  ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", span);
3529  body = ast_json_pack("{s: i}", "Span", span);
3530  if (!body) {
3531  return;
3532  }
3533 
3534  ast_manager_publish_event("SpanAlarmClear", EVENT_FLAG_SYSTEM, body);
3535 }
3536 
3537 static void handle_clear_alarms(struct dahdi_pvt *p)
3538 {
3539 #if defined(HAVE_PRI)
3541  return;
3542  }
3543 #endif /* defined(HAVE_PRI) */
3544 
3547  }
3550  }
3551 }
3552 
3553 #ifdef HAVE_OPENR2
3554 static void mfcr2_queue_for_destruction(const struct dahdi_pvt *p)
3555 {
3556  const struct dahdi_mfcr2 *r2link = p->mfcr2;
3557  struct r2link_entry *cur;
3558  AST_LIST_LOCK(&r2links);
3559  AST_LIST_TRAVERSE_SAFE_BEGIN(&r2links, cur, list) {
3560  if (r2link == &cur->mfcr2) {
3561  ast_debug(3, "MFC/R2 channel %d queued for destruction\n", p->channel);
3562  AST_LIST_MOVE_CURRENT(&nodev_r2links, list);
3563  break;
3564  }
3565  }
3567  AST_LIST_UNLOCK(&r2links);
3568 }
3569 
3570 static int dahdi_r2_answer(struct dahdi_pvt *p)
3571 {
3572  int res = 0;
3573  /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
3574  * and does not has support for openr2_chan_answer_call_with_mode
3575  * */
3576 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3577  const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
3578  int wants_double_answer = ast_true(double_answer) ? 1 : 0;
3579  if (!double_answer) {
3580  /* this still can result in double answer if the channel context
3581  * was configured that way */
3582  res = openr2_chan_answer_call(p->r2chan);
3583  } else if (wants_double_answer) {
3584  res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3585  } else {
3586  res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3587  }
3588 #else
3589  res = openr2_chan_answer_call(p->r2chan);
3590 #endif
3591  return res;
3592 }
3593 
3594 
3595 
3596 /* should be called with the ast_channel locked */
3597 static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
3598 {
3599  openr2_calling_party_category_t cat;
3600  const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
3601  struct dahdi_pvt *p = ast_channel_tech_pvt(c);
3602  if (ast_strlen_zero(catstr)) {
3603  ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
3604  ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3605  return p->mfcr2_category;
3606  }
3607  if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3608  ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
3609  catstr, ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3610  return p->mfcr2_category;
3611  }
3612  ast_debug(1, "Using category %s\n", catstr);
3613  return cat;
3614 }
3615 
3616 static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3617 {
3618  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3619  ast_mutex_lock(&p->lock);
3620  if (p->mfcr2call) {
3621  ast_mutex_unlock(&p->lock);
3622  /* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
3623  interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
3624  can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
3625  the other end will see our seize as a forced release and drop the call, we will see an invalid
3626  pattern that will be seen and treated as protocol error. */
3627  ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3628  return;
3629  }
3630  p->mfcr2call = 1;
3631  /* better safe than sorry ... */
3632  p->cid_name[0] = '\0';
3633  p->cid_num[0] = '\0';
3634  p->cid_subaddr[0] = '\0';
3635  p->rdnis[0] = '\0';
3636  p->exten[0] = '\0';
3637  p->mfcr2_ani_index = '\0';
3638  p->mfcr2_dnis_index = '\0';
3639  p->mfcr2_dnis_matched = 0;
3640  p->mfcr2_answer_pending = 0;
3641  p->mfcr2_call_accepted = 0;
3642  ast_mutex_unlock(&p->lock);
3643  ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3644 }
3645 
3646 static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
3647 {
3648  int res;
3649  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3650  ast_mutex_lock(&p->lock);
3651  p->inalarm = alarm ? 1 : 0;
3652  if (p->inalarm) {
3653  res = get_alarms(p);
3654  if (res == DAHDI_ALARM_NOTOPEN) {
3655  mfcr2_queue_for_destruction(p);
3656  }
3657  handle_alarms(p, res);
3658  } else {
3660  }
3661  ast_mutex_unlock(&p->lock);
3662 }
3663 
3664 static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
3665 {
3666  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3667 
3668  ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3669  ast_mutex_lock(&p->lock);
3670  /* Disconnected? */
3671  if (errorcode == ENODEV) {
3672  struct dahdi_mfcr2 *r2link = p->mfcr2;
3673  p->mfcr2call = 0;
3674  if (r2link) {
3675  r2link->nodev = 1;
3676  }
3677  }
3678  ast_mutex_unlock(&p->lock);
3679 }
3680 
3681 static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3682 {
3683  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3684  ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
3685  if (p->owner) {
3688  }
3689  ast_mutex_lock(&p->lock);
3690  p->mfcr2call = 0;
3691  ast_mutex_unlock(&p->lock);
3692 }
3693 
3694 static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
3695 {
3696  if (openr2_chan_disconnect_call(p->r2chan, cause)) {
3697  ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
3698  p->channel, openr2_proto_get_disconnect_string(cause));
3699  /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
3700  openr2_chan_set_idle(p->r2chan);
3701  ast_mutex_lock(&p->lock);
3702  p->mfcr2call = 0;
3703  ast_mutex_unlock(&p->lock);
3704  }
3705 }
3706 
3707 static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
3708 {
3709  struct dahdi_pvt *p;
3710  struct ast_channel *c;
3711  ast_callid callid = 0;
3712  int callid_created = ast_callid_threadstorage_auto(&callid);
3713  ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
3714  openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
3715  openr2_proto_get_category_string(category));
3716  p = openr2_chan_get_client_data(r2chan);
3717  /* if collect calls are not allowed and this is a collect call, reject it! */
3718  if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
3719  ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
3720  dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
3721  goto dahdi_r2_on_call_offered_cleanup;
3722  }
3723  ast_mutex_lock(&p->lock);
3724  p->mfcr2_recvd_category = category;
3725  /* if we're not supposed to use CID, clear whatever we have */
3726  if (!p->use_callerid) {
3727  ast_debug(1, "No CID allowed in configuration, CID is being cleared!\n");
3728  p->cid_num[0] = 0;
3729  p->cid_name[0] = 0;
3730  }
3731  /* if we're supposed to answer immediately, clear DNIS and set 's' exten */
3732  if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
3733  ast_debug(1, "Setting exten => s because of immediate or 0 DNIS configured\n");
3734  p->exten[0] = 's';
3735  p->exten[1] = 0;
3736  }
3737  ast_mutex_unlock(&p->lock);
3738  if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
3739  ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
3740  p->channel, p->exten, p->context);
3741  dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
3742  goto dahdi_r2_on_call_offered_cleanup;
3743  }
3744  if (!p->mfcr2_accept_on_offer) {
3745  /* The user wants us to start the PBX thread right away without accepting the call first */
3746  c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
3747  if (c) {
3748  /* Done here, don't disable reading now since we still need to generate MF tones to accept
3749  the call or reject it and detect the tone off condition of the other end, all of this
3750  will be done in the PBX thread now */
3751  goto dahdi_r2_on_call_offered_cleanup;
3752  }
3753  ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
3754  dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
3755  } else if (p->mfcr2_charge_calls) {
3756  ast_debug(1, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
3757  openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
3758  } else {
3759  ast_debug(1, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
3760  openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
3761  }
3762 
3763 dahdi_r2_on_call_offered_cleanup:
3764  ast_callid_threadstorage_auto_clean(callid, callid_created);
3765 }
3766 
3767 static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
3768 {
3769  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3770  ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
3771  ast_mutex_lock(&p->lock);
3772  p->mfcr2call = 0;
3773  ast_mutex_unlock(&p->lock);
3774 }
3775 
3776 static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
3777 {
3778  struct dahdi_pvt *p = NULL;
3779  struct ast_channel *c = NULL;
3780  ast_callid callid = 0;
3781  int callid_created = ast_callid_threadstorage_auto(&callid);
3782  p = openr2_chan_get_client_data(r2chan);
3783  dahdi_ec_enable(p);
3784  p->mfcr2_call_accepted = 1;
3785  /* if it's an incoming call ... */
3786  if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
3787  ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
3788  /* If accept on offer is not set, it means at this point the PBX thread is already
3789  launched (was launched in the 'on call offered' handler) and therefore this callback
3790  is being executed already in the PBX thread rather than the monitor thread, don't launch
3791  any other thread, just disable the openr2 reading and answer the call if needed */
3792  if (!p->mfcr2_accept_on_offer) {
3793  openr2_chan_disable_read(r2chan);
3794  if (p->mfcr2_answer_pending) {
3795  ast_debug(1, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
3796  dahdi_r2_answer(p);
3797  }
3798  goto dahdi_r2_on_call_accepted_cleanup;
3799  }
3800  c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
3801  if (c) {
3802  /* chan_dahdi will take care of reading from now on in the PBX thread, tell the
3803  library to forget about it */
3804  openr2_chan_disable_read(r2chan);
3805  goto dahdi_r2_on_call_accepted_cleanup;
3806  }
3807  ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
3808  /* failed to create the channel, bail out and report it as an out of order line */
3809  dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
3810  goto dahdi_r2_on_call_accepted_cleanup;
3811  }
3812  /* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
3813  ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
3814  p->subs[SUB_REAL].needringing = 1;
3815  p->dialing = 0;
3816  /* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
3817  openr2_chan_disable_read(r2chan);
3818 
3819 dahdi_r2_on_call_accepted_cleanup:
3820  ast_callid_threadstorage_auto_clean(callid, callid_created);
3821 }
3822 
3823 static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
3824 {
3825  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3826  ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
3827  p->subs[SUB_REAL].needanswer = 1;
3828 }
3829 
3830 static void dahdi_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
3831 {
3832  /*ast_debug(1, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/
3833 }
3834 
3835 static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
3836 {
3837  switch (cause) {
3838  case OR2_CAUSE_BUSY_NUMBER:
3839  return AST_CAUSE_BUSY;
3840  case OR2_CAUSE_NETWORK_CONGESTION:
3841  return AST_CAUSE_CONGESTION;
3842  case OR2_CAUSE_OUT_OF_ORDER:
3844  case OR2_CAUSE_UNALLOCATED_NUMBER:
3845  return AST_CAUSE_UNREGISTERED;
3846  case OR2_CAUSE_NO_ANSWER:
3847  return AST_CAUSE_NO_ANSWER;
3848  case OR2_CAUSE_NORMAL_CLEARING:
3850  case OR2_CAUSE_UNSPECIFIED:
3851  default:
3852  return AST_CAUSE_NOTDEFINED;
3853  }
3854 }
3855 
3856 static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
3857 {
3858  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3859  char cause_str[50];
3860  struct ast_control_pvt_cause_code *cause_code;
3861  int datalen = sizeof(*cause_code);
3862 
3863  ast_verbose("MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
3864  ast_mutex_lock(&p->lock);
3865  if (!p->owner) {
3866  ast_mutex_unlock(&p->lock);
3867  /* no owner, therefore we can't use dahdi_hangup to disconnect, do it right now */
3868  dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
3869  return;
3870  }
3871 
3872  snprintf(cause_str, sizeof(cause_str), "R2 DISCONNECT (%s)", openr2_proto_get_disconnect_string(cause));
3873  datalen += strlen(cause_str);
3874  cause_code = ast_alloca(datalen);
3875  memset(cause_code, 0, datalen);
3876  cause_code->ast_cause = dahdi_r2_cause_to_ast_cause(cause);
3878  ast_copy_string(cause_code->code, cause_str, datalen + 1 - sizeof(*cause_code));
3879  ast_queue_control_data(p->owner, AST_CONTROL_PVT_CAUSE_CODE, cause_code, datalen);
3880  ast_channel_hangupcause_hash_set(p->owner, cause_code, datalen);
3881  ast_channel_hangupcause_set(p->owner, cause_code->ast_cause);
3882 
3883  /* when we have an owner we don't call dahdi_r2_disconnect_call here, that will
3884  be done in dahdi_hangup */
3885  if (ast_channel_state(p->owner) == AST_STATE_UP) {
3887  ast_mutex_unlock(&p->lock);
3888  } else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
3889  /* being the forward side we must report what happened to the call to whoever requested it */
3890  switch (cause) {
3891  case OR2_CAUSE_BUSY_NUMBER:
3892  p->subs[SUB_REAL].needbusy = 1;
3893  break;
3894  case OR2_CAUSE_NETWORK_CONGESTION:
3895  case OR2_CAUSE_OUT_OF_ORDER:
3896  case OR2_CAUSE_UNALLOCATED_NUMBER:
3897  case OR2_CAUSE_NO_ANSWER:
3898  case OR2_CAUSE_UNSPECIFIED:
3899  case OR2_CAUSE_NORMAL_CLEARING:
3900  p->subs[SUB_REAL].needcongestion = 1;
3901  break;
3902  default:
3904  }
3905  ast_mutex_unlock(&p->lock);
3906  } else {
3907  ast_mutex_unlock(&p->lock);
3908  /* being the backward side and not UP yet, we only need to request hangup */
3909  /* TODO: what about doing this same thing when were AST_STATE_UP? */
3910  ast_queue_hangup_with_cause(p->owner, dahdi_r2_cause_to_ast_cause(cause));
3911  }
3912 }
3913 
3914 static void dahdi_r2_write_log(openr2_log_level_t level, char *logmessage)
3915 {
3916  switch (level) {
3917  case OR2_LOG_NOTICE:
3918  ast_verbose("%s", logmessage);
3919  break;
3920  case OR2_LOG_WARNING:
3921  ast_log(LOG_WARNING, "%s", logmessage);
3922  break;
3923  case OR2_LOG_ERROR:
3924  ast_log(LOG_ERROR, "%s", logmessage);
3925  break;
3926  case OR2_LOG_STACK_TRACE:
3927  case OR2_LOG_MF_TRACE:
3928  case OR2_LOG_CAS_TRACE:
3929  case OR2_LOG_DEBUG:
3930  case OR2_LOG_EX_DEBUG:
3931  ast_debug(1, "%s", logmessage);
3932  break;
3933  default:
3934  ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level);
3935  ast_debug(1, "%s", logmessage);
3936  break;
3937  }
3938 }
3939 
3940 static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
3941 {
3942  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3943  ast_mutex_lock(&p->lock);
3944  p->remotelyblocked = 1;
3945  ast_mutex_unlock(&p->lock);
3946  ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
3947 }
3948 
3949 static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
3950 {
3951  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3952  ast_mutex_lock(&p->lock);
3953  p->remotelyblocked = 0;
3954  ast_mutex_unlock(&p->lock);
3955  ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
3956 }
3957 
3958 static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
3959  __attribute__((format (printf, 3, 0)));
3960 static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
3961 {
3962 #define CONTEXT_TAG "Context - "
3963  char logmsg[256];
3964  char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1];
3965  vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
3966  snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg);
3967  dahdi_r2_write_log(level, completemsg);
3968 #undef CONTEXT_TAG
3969 }
3970 
3971 static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
3972  __attribute__((format (printf, 3, 0)));
3973 static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
3974 {
3975 #define CHAN_TAG "Chan "
3976  char logmsg[256];
3977  char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1];
3978  vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
3979  snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d - %s", openr2_chan_get_number(r2chan), logmsg);
3980  dahdi_r2_write_log(level, completemsg);
3981 }
3982 
3983 static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
3984 {
3985  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3986  /* if 'immediate' is set, let's stop requesting DNIS */
3987  if (p->immediate) {
3988  return 0;
3989  }
3990  p->exten[p->mfcr2_dnis_index] = digit;
3991  p->rdnis[p->mfcr2_dnis_index] = digit;
3992  p->mfcr2_dnis_index++;
3993  p->exten[p->mfcr2_dnis_index] = 0;
3994  p->rdnis[p->mfcr2_dnis_index] = 0;
3995  /* if the DNIS is a match and cannot match more, stop requesting DNIS */
3996  if ((p->mfcr2_dnis_matched ||
3997  (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) &&
3998  !ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
3999  return 0;
4000  }
4001  /* otherwise keep going */
4002  return 1;
4003 }
4004 
4005 static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
4006 {
4007  struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4008  p->cid_num[p->mfcr2_ani_index] = digit;
4009  p->cid_name[p->mfcr2_ani_index] = digit;
4010  p->mfcr2_ani_index++;
4011  p->cid_num[p->mfcr2_ani_index] = 0;
4012  p->cid_name[p->mfcr2_ani_index] = 0;
4013 }
4014 
4015 static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
4016 {
4017  ast_verbose("MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
4018 }
4019 
4020 static openr2_event_interface_t dahdi_r2_event_iface = {
4021  .on_call_init = dahdi_r2_on_call_init,
4022  .on_call_offered = dahdi_r2_on_call_offered,
4023  .on_call_accepted = dahdi_r2_on_call_accepted,
4024  .on_call_answered = dahdi_r2_on_call_answered,
4025  .on_call_disconnect = dahdi_r2_on_call_disconnect,
4026  .on_call_end = dahdi_r2_on_call_end,
4027  .on_call_read = dahdi_r2_on_call_read,
4028  .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
4029  .on_os_error = dahdi_r2_on_os_error,
4030  .on_protocol_error = dahdi_r2_on_protocol_error,
4031  .on_line_blocked = dahdi_r2_on_line_blocked,
4032  .on_line_idle = dahdi_r2_on_line_idle,
4033  /* cast seems to be needed to get rid of the annoying warning regarding format attribute */
4034  .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
4035  .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
4036  .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
4037  /* so far we do nothing with billing pulses */
4038  .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
4039 };
4040 
4041 static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
4042 {
4043  return AST_ALAW(sample);
4044 }
4045 
4046 static inline uint8_t dahdi_r2_linear_to_alaw(int sample)
4047 {
4048  return AST_LIN2A(sample);
4049 }
4050 
4051 static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
4052  dahdi_r2_alaw_to_linear,
4053  dahdi_r2_linear_to_alaw
4054 };
4055 
4056 #endif /* HAVE_OPENR2 */
4057 
4058 static void swap_subs(struct dahdi_pvt *p, int a, int b)
4059 {
4060  int tchan;
4061  int tinthreeway;
4062  struct ast_channel *towner;
4063 
4064  ast_debug(1, "Swapping %d and %d\n", a, b);
4065 
4066  tchan = p->subs[a].chan;
4067  towner = p->subs[a].owner;
4068  tinthreeway = p->subs[a].inthreeway;
4069 
4070  p->subs[a].chan = p->subs[b].chan;
4071  p->subs[a].owner = p->subs[b].owner;
4072  p->subs[a].inthreeway = p->subs[b].inthreeway;
4073 
4074  p->subs[b].chan = tchan;
4075  p->subs[b].owner = towner;
4076  p->subs[b].inthreeway = tinthreeway;
4077 
4078  if (p->subs[a].owner)
4079  ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
4080  if (p->subs[b].owner)
4081  ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
4082  wakeup_sub(p, a);
4083  wakeup_sub(p, b);
4084 }
4085 
4086 static int dahdi_open(char *fn)
4087 {
4088  int fd;
4089  int isnum;
4090  int chan = 0;
4091  int bs;
4092  int x;
4093  isnum = 1;
4094  for (x = 0; x < strlen(fn); x++) {
4095  if (!isdigit(fn[x])) {
4096  isnum = 0;
4097  break;
4098  }
4099  }
4100  if (isnum) {
4101  chan = atoi(fn);
4102  if (chan < 1) {
4103  ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
4104  return -1;
4105  }
4106  fn = "/dev/dahdi/channel";
4107  }
4108  fd = open(fn, O_RDWR | O_NONBLOCK);
4109  if (fd < 0) {
4110  ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
4111  return -1;
4112  }
4113  if (chan) {
4114  if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4115  x = errno;
4116  close(fd);
4117  errno = x;
4118  ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
4119  return -1;
4120  }
4121  }
4122  bs = READ_SIZE;
4123  if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
4124  ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
4125  x = errno;
4126  close(fd);
4127  errno = x;
4128  return -1;
4129  }
4130  return fd;
4131 }
4132 
4133 static void dahdi_close(int fd)
4134 {
4135  if (fd > 0)
4136  close(fd);
4137 }
4138 
4139 static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
4140 {
4141  dahdi_close(chan_pvt->subs[sub_num].dfd);
4142  chan_pvt->subs[sub_num].dfd = -1;
4143 }
4144 
4145 #if defined(HAVE_PRI)
4146 static void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num)
4147 {
4148  dahdi_close(pri->pri.fds[fd_num]);
4149  pri->pri.fds[fd_num] = -1;
4150 }
4151 #endif /* defined(HAVE_PRI) */
4152 
4153 #if defined(HAVE_SS7)
4154 static void dahdi_close_ss7_fd(struct dahdi_ss7 *ss7, int fd_num)
4155 {
4156  dahdi_close(ss7->ss7.fds[fd_num]);
4157  ss7->ss7.fds[fd_num] = -1;
4158 }
4159 #endif /* defined(HAVE_SS7) */
4160 
4161 static int dahdi_setlinear(int dfd, int linear)
4162 {
4163  return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4164 }
4165 
4166 
4167 static int alloc_sub(struct dahdi_pvt *p, int x)
4168 {
4169  struct dahdi_bufferinfo bi;
4170  int res;
4171  if (p->subs[x].dfd >= 0) {
4172  ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
4173  return -1;
4174  }
4175 
4176  p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
4177  if (p->subs[x].dfd <= -1) {
4178  ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
4179  return -1;
4180  }
4181 
4182  res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
4183  if (!res) {
4184  bi.txbufpolicy = p->buf_policy;
4185  bi.rxbufpolicy = p->buf_policy;
4186  bi.numbufs = p->buf_no;
4187  res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
4188  if (res < 0) {
4189  ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
4190  }
4191  } else
4192  ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
4193 
4194  if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
4195  ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
4196  dahdi_close_sub(p, x);
4197  p->subs[x].dfd = -1;
4198  return -1;
4199  }
4200  ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
4201  return 0;
4202 }
4203 
4204 static int unalloc_sub(struct dahdi_pvt *p, int x)
4205 {
4206  if (!x) {
4207  ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
4208  return -1;
4209  }
4210  ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
4211  dahdi_close_sub(p, x);
4212  p->subs[x].linear = 0;
4213  p->subs[x].chan = 0;
4214  p->subs[x].owner = NULL;
4215  p->subs[x].inthreeway = 0;
4216  p->polarity = POLARITY_IDLE;
4217  memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
4218  return 0;
4219 }
4220 
4221 static int digit_to_dtmfindex(char digit)
4222 {
4223  if (isdigit(digit))
4224  return DAHDI_TONE_DTMF_BASE + (digit - '0');
4225  else if (digit >= 'A' && digit <= 'D')
4226  return DAHDI_TONE_DTMF_A + (digit - 'A');
4227  else if (digit >= 'a' && digit <= 'd')
4228  return DAHDI_TONE_DTMF_A + (digit - 'a');
4229  else if (digit == '*')
4230  return DAHDI_TONE_DTMF_s;
4231  else if (digit == '#')
4232  return DAHDI_TONE_DTMF_p;
4233  else
4234  return -1;
4235 }
4236 
4237 static int dahdi_digit_begin(struct ast_channel *chan, char digit)
4238 {
4239  struct dahdi_pvt *pvt;
4240  int idx;
4241  int dtmf;
4242  int res;
4243 
4244  pvt = ast_channel_tech_pvt(chan);
4245 
4246  ast_mutex_lock(&pvt->lock);
4247 
4248  idx = dahdi_get_index(chan, pvt, 0);
4249 
4250  if ((idx != SUB_REAL) || !pvt->owner)
4251  goto out;
4252 
4253 #ifdef HAVE_PRI
4254  switch (pvt->sig) {
4256  res = sig_pri_digit_begin(pvt->sig_pvt, chan, digit);
4257  if (!res)
4258  goto out;
4259  break;
4260  default:
4261  break;
4262  }
4263 #endif
4264  dtmf = digit_to_dtmfindex(digit);
4265  if (dtmf == -1) {
4266  /* Not a valid DTMF digit */
4267  goto out;
4268  }
4269 
4270  if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
4271  char dial_str[] = { 'T', digit, '\0' };
4272 
4273  res = dahdi_dial_str(pvt, DAHDI_DIAL_OP_APPEND, dial_str);
4274  if (!res) {
4275  pvt->dialing = 1;
4276  }
4277  } else {
4278  pvt->dialing = 1;
4279  pvt->begindigit = digit;
4280 
4281  /* Flush the write buffer in DAHDI to start sending the digit immediately. */
4282  dtmf = DAHDI_FLUSH_WRITE;
4283  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &dtmf);
4284  if (res) {
4285  ast_log(LOG_WARNING, "Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4286  pvt->channel, strerror(errno));
4287  }
4288 
4289  ast_debug(1, "Channel %s started VLDTMF digit '%c'\n",
4290  ast_channel_name(chan), digit);
4291  }
4292 
4293 out:
4294  ast_mutex_unlock(&pvt->lock);
4295 
4296  return 0;
4297 }
4298 
4299 static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
4300 {
4301  struct dahdi_pvt *pvt;
4302  int res = 0;
4303  int idx;
4304  int x;
4305 
4306  pvt = ast_channel_tech_pvt(chan);
4307 
4308  ast_mutex_lock(&pvt->lock);
4309 
4310  idx = dahdi_get_index(chan, pvt, 0);
4311 
4312  if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
4313  goto out;
4314 
4315 #ifdef HAVE_PRI
4316  /* This means that the digit was already sent via PRI signalling */
4317  if (dahdi_sig_pri_lib_handles(pvt->sig) && !pvt->begindigit) {
4318  goto out;
4319  }
4320 #endif
4321 
4322  if (pvt->begindigit) {
4323  x = -1;
4324  ast_debug(1, "Channel %s ending VLDTMF digit '%c'\n",
4325  ast_channel_name(chan), digit);
4326  res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
4327  pvt->dialing = 0;
4328  pvt->begindigit = 0;
4329  }
4330 
4331 out:
4332  ast_mutex_unlock(&pvt->lock);
4333 
4334  return res;
4335 }
4336 
4337 static const char * const events[] = {
4338  "No event",
4339  "On hook",
4340  "Ring/Answered",
4341  "Wink/Flash",
4342  "Alarm",
4343  "No more alarm",
4344  "HDLC Abort",
4345  "HDLC Overrun",
4346  "HDLC Bad FCS",
4347  "Dial Complete",
4348  "Ringer On",
4349  "Ringer Off",
4350  "Hook Transition Complete",
4351  "Bits Changed",
4352  "Pulse Start",
4353  "Timer Expired",
4354  "Timer Ping",
4355  "Polarity Reversal",
4356  "Ring Begin",
4357 };
4358 
4359 static struct {
4360  int alarm;
4361  char *name;
4362 } alarms[] = {
4363  { DAHDI_ALARM_RED, "Red Alarm" },
4364  { DAHDI_ALARM_YELLOW, "Yellow Alarm" },
4365  { DAHDI_ALARM_BLUE, "Blue Alarm" },
4366  { DAHDI_ALARM_RECOVER, "Recovering" },
4367  { DAHDI_ALARM_LOOPBACK, "Loopback" },
4368  { DAHDI_ALARM_NOTOPEN, "Not Open" },
4369  { DAHDI_ALARM_NONE, "None" },
4370 };
4371 
4372 static char *alarm2str(int alm)
4373 {
4374  int x;
4375  for (x = 0; x < ARRAY_LEN(alarms); x++) {
4376  if (alarms[x].alarm & alm)
4377  return alarms[x].name;
4378  }
4379  return alm ? "Unknown Alarm" : "No Alarm";
4380 }
4381 
4382 static const char *event2str(int event)
4383 {
4384  static char buf[256];
4385  if ((event > -1) && (event < (ARRAY_LEN(events))) )
4386  return events[event];
4387  sprintf(buf, "Event %d", event); /* safe */
4388  return buf;
4389 }
4390 
4391 static char *dahdi_sig2str(int sig)
4392 {
4393  static char buf[256];
4394  switch (sig) {
4395  case SIG_EM:
4396  return "E & M Immediate";
4397  case SIG_EMWINK:
4398  return "E & M Wink";
4399  case SIG_EM_E1:
4400  return "E & M E1";
4401  case SIG_FEATD:
4402  return "Feature Group D (DTMF)";
4403  case SIG_FEATDMF:
4404  return "Feature Group D (MF)";
4405  case SIG_FEATDMF_TA:
4406  return "Feature Groud D (MF) Tandem Access";
4407  case SIG_FEATB:
4408  return "Feature Group B (MF)";
4409  case SIG_E911:
4410  return "E911 (MF)";
4411  case SIG_FGC_CAMA:
4412  return "FGC/CAMA (Dialpulse)";
4413  case SIG_FGC_CAMAMF:
4414  return "FGC/CAMA (MF)";
4415  case SIG_FXSLS:
4416  return "FXS Loopstart";
4417  case SIG_FXSGS:
4418  return "FXS Groundstart";
4419  case SIG_FXSKS:
4420  return "FXS Kewlstart";
4421  case SIG_FXOLS:
4422  return "FXO Loopstart";
4423  case SIG_FXOGS:
4424  return "FXO Groundstart";
4425  case SIG_FXOKS:
4426  return "FXO Kewlstart";
4427  case SIG_PRI:
4428  return "ISDN PRI";
4429  case SIG_BRI:
4430  return "ISDN BRI Point to Point";
4431  case SIG_BRI_PTMP:
4432  return "ISDN BRI Point to MultiPoint";
4433  case SIG_SS7:
4434  return "SS7";
4435  case SIG_MFCR2:
4436  return "MFC/R2";
4437  case SIG_SF:
4438  return "SF (Tone) Immediate";
4439  case SIG_SFWINK:
4440  return "SF (Tone) Wink";
4441  case SIG_SF_FEATD:
4442  return "SF (Tone) with Feature Group D (DTMF)";
4443  case SIG_SF_FEATDMF:
4444  return "SF (Tone) with Feature Group D (MF)";
4445  case SIG_SF_FEATB:
4446  return "SF (Tone) with Feature Group B (MF)";
4447  case 0:
4448  return "Pseudo";
4449  default:
4450  snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
4451  return buf;
4452  }
4453 }
4454 
4455 #define sig2str dahdi_sig2str
4456 
4457 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx, int slavechannel)
4458 {
4459  /* If the conference already exists, and we're already in it
4460  don't bother doing anything */
4461  struct dahdi_confinfo zi;
4462 
4463  memset(&zi, 0, sizeof(zi));
4464  zi.chan = 0;
4465 
4466  if (slavechannel > 0) {
4467  /* If we have only one slave, do a digital mon */
4468  zi.confmode = DAHDI_CONF_DIGITALMON;
4469  zi.confno = slavechannel;
4470  } else {
4471  if (!idx) {
4472  /* Real-side and pseudo-side both participate in conference */
4473  zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4474  DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4475  } else
4476  zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4477  zi.confno = p->confno;
4478  }
4479  if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
4480  return 0;
4481  if (c->dfd < 0)
4482  return 0;
4483  if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4484  ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
4485  return -1;
4486  }
4487  if (slavechannel < 1) {
4488  p->confno = zi.confno;
4489  }
4490  c->curconf = zi;
4491  ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4492  return 0;
4493 }
4494 
4495 static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
4496 {
4497  /* If they're listening to our channel, they're ours */
4498  if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4499  return 1;
4500  /* If they're a talker on our (allocated) conference, they're ours */
4501  if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
4502  return 1;
4503  return 0;
4504 }
4505 
4506 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx)
4507 {
4508  struct dahdi_confinfo zi;
4509  if (/* Can't delete if there's no dfd */
4510  (c->dfd < 0) ||
4511  /* Don't delete from the conference if it's not our conference */
4512  !isourconf(p, c)
4513  /* Don't delete if we don't think it's conferenced at all (implied) */
4514  ) return 0;
4515  memset(&zi, 0, sizeof(zi));
4516  if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
4517  ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
4518  return -1;
4519  }
4520  ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
4521  memcpy(&c->curconf, &zi, sizeof(c->curconf));
4522  return 0;
4523 }
4524 
4525 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
4526 {
4527  int x;
4528  int useslavenative;
4529  struct dahdi_pvt *slave = NULL;
4530  /* Start out optimistic */
4531  useslavenative = 1;
4532  /* Update conference state in a stateless fashion */
4533  for (x = 0; x < 3; x++) {
4534  /* Any three-way calling makes slave native mode *definitely* out
4535  of the question */
4536  if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
4537  useslavenative = 0;
4538  }
4539  /* If we don't have any 3-way calls, check to see if we have
4540  precisely one slave */
4541  if (useslavenative) {
4542  for (x = 0; x < MAX_SLAVES; x++) {
4543  if (p->slaves[x]) {
4544  if (slave) {
4545  /* Whoops already have a slave! No
4546  slave native and stop right away */
4547  slave = NULL;
4548  useslavenative = 0;
4549  break;
4550  } else {
4551  /* We have one slave so far */
4552  slave = p->slaves[x];
4553  }
4554  }
4555  }
4556  }
4557  /* If no slave, slave native definitely out */
4558  if (!slave)
4559  useslavenative = 0;
4560  else if (slave->law != p->law) {
4561  useslavenative = 0;
4562  slave = NULL;
4563  }
4564  if (out)
4565  *out = slave;
4566  return useslavenative;
4567 }
4568 
4569 static int reset_conf(struct dahdi_pvt *p)
4570 {
4571  p->confno = -1;
4572  memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
4573  if (p->subs[SUB_REAL].dfd > -1) {
4574  struct dahdi_confinfo zi;
4575 
4576  memset(&zi, 0, sizeof(zi));
4577  if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
4578  ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
4579  }
4580  return 0;
4581 }
4582 
4584 {
4585  int needconf = 0;
4586  int x;
4587  int useslavenative;
4588  struct dahdi_pvt *slave = NULL;
4589 
4590  useslavenative = isslavenative(p, &slave);
4591  /* Start with the obvious, general stuff */
4592  for (x = 0; x < 3; x++) {
4593  /* Look for three way calls */
4594  if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
4595  conf_add(p, &p->subs[x], x, 0);
4596  needconf++;
4597  } else {
4598  conf_del(p, &p->subs[x], x);
4599  }
4600  }
4601  /* If we have a slave, add him to our conference now. or DAX
4602  if this is slave native */
4603  for (x = 0; x < MAX_SLAVES; x++) {
4604  if (p->slaves[x]) {
4605  if (useslavenative)
4606  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
4607  else {
4608  conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
4609  needconf++;
4610  }
4611  }
4612  }
4613  /* If we're supposed to be in there, do so now */
4614  if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
4615  if (useslavenative)
4616  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
4617  else {
4618  conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
4619  needconf++;
4620  }
4621  }
4622  /* If we have a master, add ourselves to his conference */
4623  if (p->master) {
4624  if (isslavenative(p->master, NULL)) {
4626  } else {
4627  conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
4628  }
4629  }
4630  if (!needconf) {
4631  /* Nobody is left (or should be left) in our conference.
4632  Kill it. */
4633  p->confno = -1;
4634  }
4635  ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
4636 }
4637 
4639 {
4640  int res;
4641  if (!p)
4642  return;
4643  if (p->echocanon) {
4644  ast_debug(1, "Echo cancellation already on\n");
4645  return;
4646  }
4647  if (p->digital) {
4648  ast_debug(1, "Echo cancellation isn't required on digital connection\n");
4649  return;
4650  }
4651  if (p->echocancel.head.tap_length) {
4652 #if defined(HAVE_PRI) || defined(HAVE_SS7)
4653  switch (p->sig) {
4654 #if defined(HAVE_PRI)
4656  if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
4657  /*
4658  * PRI nobch pseudo channel. Does not need ec anyway.
4659  * Does not handle ioctl(DAHDI_AUDIOMODE)
4660  */
4661  return;
4662  }
4663  /* Fall through */
4664 #endif /* defined(HAVE_PRI) */
4665 #if defined(HAVE_SS7)
4666  case SIG_SS7:
4667 #endif /* defined(HAVE_SS7) */
4668  {
4669  int x = 1;
4670 
4671  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
4672  if (res)
4674  "Unable to enable audio mode on channel %d (%s)\n",
4675  p->channel, strerror(errno));
4676  }
4677  break;
4678  default:
4679  break;
4680  }
4681 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
4682  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
4683  if (res) {
4684  ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
4685  } else {
4686  p->echocanon = 1;
4687  ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
4688  }
4689  } else
4690  ast_debug(1, "No echo cancellation requested\n");
4691 }
4692 
4693 static void dahdi_train_ec(struct dahdi_pvt *p)
4694 {
4695  int x;
4696  int res;
4697 
4698  if (p && p->echocanon && p->echotraining) {
4699  x = p->echotraining;
4700  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
4701  if (res)
4702  ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
4703  else
4704  ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
4705  } else {
4706  ast_debug(1, "No echo training requested\n");
4707  }
4708 }
4709 
4711 {
4712  int res;
4713 
4714  if (p->echocanon) {
4715  struct dahdi_echocanparams ecp = { .tap_length = 0 };
4716 
4717  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
4718 
4719  if (res)
4720  ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
4721  else
4722  ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
4723  }
4724 
4725  p->echocanon = 0;
4726 }
4727 
4728 static int set_hwgain(int fd, float gain, int tx_direction)
4729 {
4730  struct dahdi_hwgain hwgain;
4731 
4732  hwgain.newgain = gain * 10.0;
4733  hwgain.tx = tx_direction;
4734  return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
4735 }
4736 
4737 /* perform a dynamic range compression transform on the given sample */
4738 static int drc_sample(int sample, float drc)
4739 {
4740  float neg;
4741  float shallow, steep;
4742  float max = SHRT_MAX;
4743 
4744  neg = (sample < 0 ? -1 : 1);
4745  steep = drc*sample;
4746  shallow = neg*(max-max/drc)+(float)sample/drc;
4747  if (fabsf(steep) < fabsf(shallow)) {
4748  sample = steep;
4749  }
4750  else {
4751  sample = shallow;
4752  }
4753 
4754  return sample;
4755 }
4756 
4757 
4758 static void fill_txgain(struct dahdi_gains *g, float gain, float drc, int law)
4759 {
4760  int j;
4761  int k;
4762 
4763  float linear_gain = pow(10.0, gain / 20.0);
4764 
4765  switch (law) {
4766  case DAHDI_LAW_ALAW:
4767  for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
4768  if (gain || drc) {
4769  k = AST_ALAW(j);
4770  if (drc) {
4771  k = drc_sample(k, drc);
4772  }
4773  k = (float)k * linear_gain;
4774  if (k > 32767) {
4775  k = 32767;
4776  } else if (k < -32768) {
4777  k = -32768;
4778  }
4779  g->txgain[j] = AST_LIN2A(k);
4780  } else {
4781  g->txgain[j] = j;
4782  }
4783  }
4784  break;
4785  case DAHDI_LAW_MULAW:
4786  for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
4787  if (gain || drc) {
4788  k = AST_MULAW(j);
4789  if (drc) {
4790  k = drc_sample(k, drc);
4791  }
4792  k = (float)k * linear_gain;
4793  if (k > 32767) {
4794  k = 32767;
4795  } else if (k < -32768) {
4796  k = -32768;
4797  }
4798  g->txgain[j] = AST_LIN2MU(k);
4799 
4800  } else {
4801  g->txgain[j] = j;
4802  }
4803  }
4804  break;
4805  }
4806 }
4807 
4808 static void fill_rxgain(struct dahdi_gains *g, float gain, float drc, int law)
4809 {
4810  int j;
4811  int k;
4812  float linear_gain = pow(10.0, gain / 20.0);
4813 
4814  switch (law) {
4815  case DAHDI_LAW_ALAW:
4816  for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
4817  if (gain || drc) {
4818  k = AST_ALAW(j);
4819  if (drc) {
4820  k = drc_sample(k, drc);
4821  }
4822  k = (float)k * linear_gain;
4823  if (k > 32767) {
4824  k = 32767;
4825  } else if (k < -32768) {
4826  k = -32768;
4827  }
4828  g->rxgain[j] = AST_LIN2A(k);
4829  } else {
4830  g->rxgain[j] = j;
4831  }
4832  }
4833  break;
4834  case DAHDI_LAW_MULAW:
4835  for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
4836  if (gain || drc) {
4837  k = AST_MULAW(j);
4838  if (drc) {
4839  k = drc_sample(k, drc);
4840  }
4841  k = (float)k * linear_gain;
4842  if (k > 32767) {
4843  k = 32767;
4844  } else if (k < -32768) {
4845  k = -32768;
4846  }
4847  g->rxgain[j] = AST_LIN2MU(k);
4848  } else {
4849  g->rxgain[j] = j;
4850  }
4851  }
4852  break;
4853  }
4854 }
4855 
4856 static int set_actual_txgain(int fd, float gain, float drc, int law)
4857 {
4858  struct dahdi_gains g;
4859  int res;
4860 
4861  memset(&g, 0, sizeof(g));
4862  res = ioctl(fd, DAHDI_GETGAINS, &g);
4863  if (res) {
4864  ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
4865  return res;
4866  }
4867 
4868  fill_txgain(&g, gain, drc, law);
4869 
4870  return ioctl(fd, DAHDI_SETGAINS, &g);
4871 }
4872 
4873 static int set_actual_rxgain(int fd, float gain, float drc, int law)
4874 {
4875  struct dahdi_gains g;
4876  int res;
4877 
4878  memset(&g, 0, sizeof(g));
4879  res = ioctl(fd, DAHDI_GETGAINS, &g);
4880  if (res) {
4881  ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
4882  return res;
4883  }
4884 
4885  fill_rxgain(&g, gain, drc, law);
4886 
4887  return ioctl(fd, DAHDI_SETGAINS, &g);
4888 }
4889 
4890 static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law)
4891 {
4892  return set_actual_txgain(fd, txgain, txdrc, law) | set_actual_rxgain(fd, rxgain, rxdrc, law);
4893 }
4894 
4895 static int bump_gains(struct dahdi_pvt *p)
4896 {
4897  int res;
4898 
4899  /* Bump receive gain by value stored in cid_rxgain */
4900  res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain + p->cid_rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
4901  if (res) {
4902  ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
4903  return -1;
4904  }
4905 
4906  return 0;
4907 }
4908 
4909 static int restore_gains(struct dahdi_pvt *p)
4910 {
4911  int res;
4912 
4913  res = set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
4914  if (res) {
4915  ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
4916  return -1;
4917  }
4918 
4919  return 0;
4920 }
4921 
4922 static inline int dahdi_set_hook(int fd, int hs)
4923 {
4924  int x, res;
4925 
4926  x = hs;
4927  res = ioctl(fd, DAHDI_HOOK, &x);
4928 
4929  if (res < 0) {
4930  if (errno == EINPROGRESS)
4931  return 0;
4932  ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
4933  /* will expectedly fail if phone is off hook during operation, such as during a restart */
4934  }
4935 
4936  return res;
4937 }
4938 
4939 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
4940 {
4941  int x, res;
4942 
4943  x = muted;
4944 #if defined(HAVE_PRI) || defined(HAVE_SS7)
4945  switch (p->sig) {
4946 #if defined(HAVE_PRI)
4948  if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
4949  /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
4950  break;
4951  }
4952  /* Fall through */
4953 #endif /* defined(HAVE_PRI) */
4954 #if defined(HAVE_SS7)
4955  case SIG_SS7:
4956 #endif /* defined(HAVE_SS7) */
4957  {
4958  int y = 1;
4959 
4960  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
4961  if (res)
4962  ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n",
4963  p->channel, strerror(errno));
4964  }
4965  break;
4966  default:
4967  break;
4968  }
4969 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
4970  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
4971  if (res < 0)
4972  ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
4973  return res;
4974 }
4975 
4976 static int save_conference(struct dahdi_pvt *p)
4977 {
4978  struct dahdi_confinfo c;
4979  int res;
4980  if (p->saveconf.confmode) {
4981  ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
4982  return -1;
4983  }
4984  p->saveconf.chan = 0;
4985  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
4986  if (res) {
4987  ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
4988  p->saveconf.confmode = 0;
4989  return -1;
4990  }
4991  memset(&c, 0, sizeof(c));
4992  c.confmode = DAHDI_CONF_NORMAL;
4993  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
4994  if (res) {
4995  ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
4996  return -1;
4997  }
4998  ast_debug(1, "Disabled conferencing\n");
4999  return 0;
5000 }
5001 
5002 static int restore_conference(struct dahdi_pvt *p)
5003 {
5004  int res;
5005  if (p->saveconf.confmode) {
5006  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
5007  p->saveconf.confmode = 0;
5008  if (res) {
5009  ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
5010  return -1;
5011  }
5012  ast_debug(1, "Restored conferencing\n");
5013  }
5014  return 0;
5015 }
5016 
5017 static int send_cwcidspill(struct dahdi_pvt *p)
5018 {
5019  p->callwaitcas = 0;
5020  p->cidcwexpire = 0;
5021  p->cid_suppress_expire = 0;
5022  if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
5023  return -1;
5025  /* Make sure we account for the end */
5026  p->cidlen += READ_SIZE * 4;
5027  p->cidpos = 0;
5028  send_callerid(p);
5029  ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
5030  return 0;
5031 }
5032 
5033 static int has_voicemail(struct dahdi_pvt *p)
5034 {
5035  int new_msgs;
5036  RAII_VAR(struct stasis_message *, mwi_message, NULL, ao2_cleanup);
5037 
5039  if (mwi_message) {
5040  struct ast_mwi_state *mwi_state = stasis_message_data(mwi_message);
5041  new_msgs = mwi_state->new_msgs;
5042  } else {
5043  new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
5044  }
5045 
5046  return new_msgs;
5047 }
5048 
5049 
5050 
5051 static int send_callerid(struct dahdi_pvt *p)
5052 {
5053  /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
5054  int res;
5055  /* Take out of linear mode if necessary */
5056  if (p->subs[SUB_REAL].linear) {
5057  p->subs[SUB_REAL].linear = 0;
5058  dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
5059  }
5060  while (p->cidpos < p->cidlen) {
5061  res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
5062  ast_debug(4, "writing callerid at pos %d of %d, res = %d\n", p->cidpos, p->cidlen, res);
5063  if (res < 0) {
5064  if (errno == EAGAIN)
5065  return 0;
5066  else {
5067  ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
5068  return -1;
5069  }
5070  }
5071  if (!res)
5072  return 0;
5073  p->cidpos += res;
5074  }
5076  ast_free(p->cidspill);
5077  p->cidspill = NULL;
5078  if (p->callwaitcas) {
5079  /* Wait for CID/CW to expire */
5082  } else
5083  restore_conference(p);
5084  return 0;
5085 }
5086 
5087 static int dahdi_callwait(struct ast_channel *ast)
5088 {
5089  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5090 
5092  if (p->cidspill) {
5093  ast_log(LOG_WARNING, "Spill already exists?!?\n");
5094  ast_free(p->cidspill);
5095  }
5096 
5097  /*
5098  * SAS: Subscriber Alert Signal, 440Hz for 300ms
5099  * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
5100  */
5101  if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
5102  return -1;
5103  save_conference(p);
5104  /* Silence */
5105  memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
5106  if (!p->callwaitrings && p->callwaitingcallerid) {
5107  ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
5108  p->callwaitcas = 1;
5109  p->cidlen = 2400 + 680 + READ_SIZE * 4;
5110  } else {
5111  ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
5112  p->callwaitcas = 0;
5113  p->cidlen = 2400 + READ_SIZE * 4;
5114  }
5115  p->cidpos = 0;
5116  send_callerid(p);
5117 
5118  return 0;
5119 }
5120 
5121 static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout)
5122 {
5123  struct dahdi_pvt *p = ast_channel_tech_pvt(ast);
5124  int x, res, mysig;
5125  char *dest;
5127  AST_APP_ARG(group); /* channel/group token */
5128  AST_APP_ARG(ext); /* extension token */
5129  //AST_APP_ARG(opts); /* options token */
5130  AST_APP_ARG(other); /* Any remining unused arguments */
5131  );
5132 
5133  ast_mutex_lock(&p->lock);
5134  ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
5135 
5136  /* Split the dialstring */
5137  dest = ast_strdupa(rdest);
5138  AST_NONSTANDARD_APP_ARGS(args, dest, '/');
5139  if (!args.ext) {
5140  args.ext = "";
5141  }
5142 
5143 #if defined(HAVE_PRI)
5144  if (dahdi_sig_pri_lib_handles(p->sig)) {
5145  char *subaddr;
5146 
5147  sig_pri_extract_called_num_subaddr(p->sig_pvt, rdest, p->exten, sizeof(p->exten));
5148 
5149  /* Remove any subaddress for uniformity with incoming calls. */
5150  subaddr = strchr(p->exten, ':');
5151  if (subaddr) {
5152  *subaddr = '\0';
5153  }
5154  } else
5155 #endif /* defined(HAVE_PRI) */
5156  {
5157  ast_copy_string(p->exten, args.ext, sizeof(p->exten));
5158  }
5159 
5160  if ((ast_channel_state(ast) == AST_STATE_BUSY)) {
5161  p->subs[SUB_REAL].needbusy = 1;
5162  ast_mutex_unlock(&p->lock);
5163  return 0;
5164  }
5166  ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
5167  ast_mutex_unlock(&p->lock);
5168  return -1;
5169  }
5170  p->waitingfordt.tv_sec = 0;
5171  p->dialednone = 0;
5172  if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
5173  {
5174  /* Special pseudo -- automatically up */
5175  ast_setstate(ast, AST_STATE_UP);
5176  ast_mutex_unlock(&p->lock);
5177  return 0;
5178  }
5179  x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5180  res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
5181  if (res)
5182  ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
5183  p->outgoing = 1;
5184 
5186  set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, p->rxdrc, p->txdrc, p->law);
5187  } else {
5188  set_actual_gain(p->subs[SUB_REAL].dfd, p->rxgain, p->txgain, p->rxdrc, p->txdrc, p->law);
5189  }
5190 
5191 #ifdef HAVE_PRI
5192  if (dahdi_sig_pri_lib_handles(p->sig)) {
5193  res = sig_pri_call(p->sig_pvt, ast, rdest, timeout,
5194  (p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5195  ast_mutex_unlock(&p->lock);
5196  return res;
5197  }
5198 #endif
5199 
5200 #if defined(HAVE_SS7)
5201  if (p->sig == SIG_SS7) {
5202  res = sig_ss7_call(p->sig_pvt, ast, rdest);
5203  ast_mutex_unlock(&p->lock);
5204  return res;
5205  }
5206 #endif /* defined(HAVE_SS7) */
5207 
5208  /* If this is analog signalling we can exit here */
5209  if (dahdi_analog_lib_handles(p->sig, p->radio, p->oprmode)) {
5210  p->callwaitrings = 0;
5211  res = analog_call(p->sig_pvt, ast, rdest, timeout);
5212  ast_mutex_unlock(&p->lock);
5213  return res;
5214  }
5215 
5216  mysig = p->outsigmod > -1 ? p->outsigmod : p->sig;
5217  switch (mysig) {
5218  case 0:
5219  /* Special pseudo -- automatically up*/
5220  ast_setstate(ast, AST_STATE_UP);
5221  break;
5222  case SIG_MFCR2:
5223  break;
5224  default:
5225  ast_debug(1, "not yet implemented\n");
5226  ast_mutex_unlock(&p->lock);
5227  return -1;
5228  }
5229 
5230 #ifdef HAVE_OPENR2
5231  if (p->mfcr2) {
5232  openr2_calling_party_category_t chancat;
5233  int callres = 0;
5234  char *c, *l;
5235 
5236  /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
5237  p->dialdest[0] = '\0';
5238 
5239  c = args.ext;
5240  if (!p->hidecallerid) {
5242  } else {
5243  l = NULL;
5244  }
5245  if (strlen(c) < p->stripmsd) {
5246  ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
5247  ast_mutex_unlock(&p->lock);
5248  return -1;
5249  }
5250  p->dialing = 1;
5251  chancat = dahdi_r2_get_channel_category(ast);
5252  callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
5253  if (-1 == callres) {
5254  ast_mutex_unlock(&p->lock);
5255  ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
5256  return -1;
5257  }
5258  p->mfcr2_call_accepted = 0;
5259  p->mfcr2_progress_sent = 0;
5261  }
5262 #endif /* HAVE_OPENR2 */
5263  ast_mutex_unlock(&p->lock);
5264  return 0;
5265 }
5266 
5267 /*!
5268  * \internal
5269  * \brief Insert the given chan_dahdi interface structure into the interface list.
5270  * \since 1.8
5271  *
5272  * \param pvt chan_dahdi private interface structure to insert.
5273  *
5274  * \details
5275  * The interface list is a doubly linked list sorted by the chan_dahdi channel number.
5276  * Any duplicates are inserted after the existing entries.
5277  *
5278  * \note The new interface must not already be in the list.
5279  *
5280  * \return Nothing
5281  */
5282 static void dahdi_iflist_insert(struct dahdi_pvt *pvt)
5283 {
5284  struct dahdi_pvt *cur;
5285 
5287 
5288  /* Find place in middle of list for the new interface. */
5289  for (cur = iflist; cur; cur = cur->next) {
5290  if (pvt->channel < cur->channel) {
5291  /* New interface goes before the current interface. */
5292  pvt->prev = cur->prev;
5293  pvt->next = cur;
5294  if (cur->prev) {
5295  /* Insert into the middle of the list. */
5296  cur->prev->next = pvt;
5297  } else {
5298  /* Insert at head of list. */
5299  iflist = pvt;
5300  }
5301  cur->prev = pvt;
5302  return;
5303  }
5304  }
5305 
5306  /* New interface goes onto the end of the list */
5307  pvt->prev = ifend;
5308  pvt->next = NULL;
5309  if (ifend) {
5310  ifend->next = pvt;
5311  }
5312  ifend = pvt;
5313  if (!iflist) {
5314  /* List was empty */
5315  iflist = pvt;
5316  }
5317 }
5318 
5319 /*!
5320  * \internal
5321  * \brief Extract the given chan_dahdi interface structure from the interface list.
5322  * \since 1.8
5323  *
5324  * \param pvt chan_dahdi private interface structure to extract.
5325  *
5326  * \note
5327  * The given interface structure can be either in the interface list or a stand alone
5328  * structure that has not been put in the list if the next and prev pointers are NULL.
5329  *
5330  * \return Nothing
5331  */
5332 static void dahdi_iflist_extract(struct dahdi_pvt *pvt)
5333 {
5334  /* Extract from the forward chain. */
5335  if (pvt->prev) {
5336  pvt->prev->next = pvt->next;
5337  } else if (iflist == pvt) {
5338  /* Node is at the head of the list. */
5339  iflist = pvt->next;
5340  }
5341 
5342  /* Extract from the reverse chain. */
5343  if (pvt->next) {
5344  pvt->next->prev = pvt->prev;
5345  } else if (ifend == pvt) {
5346  /* Node is at the end of the list. */
5347  ifend = pvt->prev;
5348  }
5349 
5350  /* Node is no longer in the list. */
5352  pvt->prev = NULL;
5353  pvt->next = NULL;
5354 }
5355 
5356 #if defined(HAVE_PRI)
5357 /*!
5358  * \internal
5359  * \brief Insert the given chan_dahdi interface structure into the no B channel list.
5360  * \since 1.8
5361  *
5362  * \param pri sig_pri span control structure holding no B channel list.
5363  * \param pvt chan_dahdi private interface structure to insert.
5364  *
5365  * \details
5366  * The interface list is a doubly linked list sorted by the chan_dahdi channel number.
5367  * Any duplicates are inserted after the existing entries.
5368  *
5369  * \note The new interface must not already be in the list.
5370  *
5371  * \return Nothing
5372  */
5373 static void dahdi_nobch_insert(struct sig_pri_span *pri, struct dahdi_pvt *pvt)
5374 {
5375  struct dahdi_pvt *cur;
5376 
5377  pvt->which_iflist = DAHDI_IFLIST_NO_B_CHAN;
5378 
5379  /* Find place in middle of list for the new interface. */
5380  for (cur = pri->no_b_chan_iflist; cur; cur = cur->next) {
5381  if (pvt->channel < cur->channel) {
5382  /* New interface goes before the current interface. */
5383  pvt->prev = cur->prev;
5384  pvt->next = cur;
5385  if (cur->prev) {
5386  /* Insert into the middle of the list. */
5387  cur->prev->next = pvt;
5388  } else {
5389  /* Insert at head of list. */
5390  pri->no_b_chan_iflist = pvt;
5391  }
5392  cur->prev = pvt;
5393  return;
5394  }
5395  }
5396 
5397  /* New interface goes onto the end of the list */
5398  pvt->prev = pri->no_b_chan_end;
5399  pvt->next = NULL;
5400  if (pri->no_b_chan_end) {
5401  ((struct dahdi_pvt *) pri->no_b_chan_end)->next = pvt;
5402  }
5403  pri->no_b_chan_end = pvt;
5404  if (!pri->no_b_chan_iflist) {
5405  /* List was empty */
5406  pri->no_b_chan_iflist = pvt;
5407  }
5408 }
5409 #endif /* defined(HAVE_PRI) */
5410 
5411 #if defined(HAVE_PRI)
5412 /*!
5413  * \internal
5414  * \brief Extract the given chan_dahdi interface structure from the no B channel list.
5415  * \since 1.8
5416  *
5417  * \param pri sig_pri span control structure holding no B channel list.
5418  * \param pvt chan_dahdi private interface structure to extract.
5419  *
5420  * \note
5421  * The given interface structure can be either in the interface list or a stand alone
5422  * structure that has not been put in the list if the next and prev pointers are NULL.
5423  *
5424  * \return Nothing
5425