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