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