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