Newer
Older
* Asterisk -- An open source telephony toolkit.
* Copyright (C) 1999 - 2008, Digium, Inc.
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
*
* \brief DAHDI for Pseudo TDM
*
* \author Mark Spencer <markster@digium.com>
*
* Connects to the DAHDI telephony library as well as
* libpri. Libpri is optional and needed only if you are
* going to use ISDN connections.
*
* You need to install libraries before you attempt to compile
* and install the DAHDI channel.
Olle Johansson
committed
*
Kevin P. Fleming
committed
* \todo Deprecate the "musiconhold" configuration option post 1.4
/*! \li \ref chan_dahdi.c uses the configuration file \ref chan_dahdi.conf
* \addtogroup configuration_file
*/
/*! \page chan_dahdi.conf chan_dahdi.conf
* \verbinclude chan_dahdi.conf.sample
*/
Kevin P. Fleming
committed
/*** MODULEINFO
<use type="module">res_smdi</use>
<depend>dahdi</depend>
<depend>tonezone</depend>
<use type="external">pri</use>
<use type="external">ss7</use>
<use type="external">openr2</use>
<support_level>core</support_level>
Kevin P. Fleming
committed
***/
Kevin P. Fleming
committed
#include "asterisk.h"
#if defined(__NetBSD__) || defined(__FreeBSD__)
#else
#include <sys/sysmacros.h>
Richard Mudgett
committed
#include <sys/stat.h>
#include "sig_analog.h"
/* Analog signaling is currently still present in chan_dahdi for use with
* radio. Sig_analog does not currently handle any radio operations. If
* radio only uses analog signaling, then the radio handling logic could
* be placed in sig_analog and the duplicated code could be removed.
*/
Kevin P. Fleming
committed
#if defined(HAVE_PRI)
#include "sig_pri.h"
#ifndef PRI_RESTART
#error "Upgrade your libpri"
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_SS7)
#include "sig_ss7.h"
#if !defined(LIBSS7_ABI_COMPATIBILITY)
#error "Upgrade your libss7"
#elif LIBSS7_ABI_COMPATIBILITY != 2
#error "Your installed libss7 is not compatible"
#endif
#if defined(HAVE_OPENR2)
Richard Mudgett
committed
/* put this here until sig_mfcr2 comes along */
#define SIG_MFCR2_MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
#endif /* defined(HAVE_OPENR2) */
Kevin P. Fleming
committed
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/adsi.h"
#include "asterisk/cli.h"
#include "asterisk/pickup.h"
Kevin P. Fleming
committed
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/say.h"
#include "asterisk/tdd.h"
#include "asterisk/mwi.h"
Kevin P. Fleming
committed
#include "asterisk/dsp.h"
#include "asterisk/astdb.h"
#include "asterisk/manager.h"
#include "asterisk/causes.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/transcap.h"
#include "asterisk/stringfields.h"
Russell Bryant
committed
#include "asterisk/abstract_jb.h"
Matthew Fredrickson
committed
#include "asterisk/smdi.h"
#include "asterisk/features_config.h"
#include "asterisk/parking.h"
#include "asterisk/format_cache.h"
#include "chan_dahdi.h"
#include "dahdi/bridge_native_dahdi.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
<synopsis>
Send digits out of band over a PRI.
</synopsis>
<syntax>
<parameter name="digits" required="true" />
</syntax>
<description>
<para>This application will send the given string of digits in a Keypad
Facility IE over the current channel.</para>
</description>
</application>
<application name="DAHDISendCallreroutingFacility" language="en_US">
<synopsis>
Send an ISDN call rerouting/deflection facility message.
Tilghman Lesher
committed
<syntax argsep=",">
<parameter name="destination" required="true">
</parameter>
<parameter name="original">
<para>Original called number.</para>
</parameter>
<parameter name="reason">
<para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
</parameter>
</syntax>
<description>
<para>This application will send an ISDN switch specific call
rerouting/deflection facility message over the current channel.
Supported switches depend upon the version of libpri in use.</para>
<application name="DAHDIAcceptR2Call" language="en_US">
<synopsis>
Accept an R2 call if its not already accepted (you still need to answer it)
</synopsis>
<syntax>
<parameter name="charge" required="true">
<para>Yes or No.</para>
<para>Whether you want to accept the call with charge or without charge.</para>
</parameter>
</syntax>
<description>
<para>This application will Accept the R2 call either with charge or no charge.</para>
</description>
</application>
<info name="CHANNEL" language="en_US" tech="DAHDI">
<enumlist>
<enum name="dahdi_channel">
<para>R/O DAHDI channel related to this channel.</para>
</enum>
<enum name="dahdi_span">
<para>R/O DAHDI span related to this channel.</para>
</enum>
<enum name="dahdi_group">
<para>R/O DAHDI logical group related to this channel.</para>
</enum>
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<enum name="dahdi_type">
<para>R/O DAHDI channel type, one of:</para>
<enumlist>
<enum name="analog" />
<enum name="mfc/r2" />
<enum name="pri" />
<enum name="pseudo" />
<enum name="ss7" />
</enumlist>
</enum>
<enum name="keypad_digits">
<para>R/O PRI Keypad digits that came in with the SETUP message.</para>
</enum>
<enum name="reversecharge">
<para>R/O PRI Reverse Charging Indication, one of:</para>
<enumlist>
<enum name="-1"> <para>None</para></enum>
<enum name=" 1"> <para>Reverse Charging Requested</para></enum>
</enumlist>
</enum>
<enum name="no_media_path">
<para>R/O PRI Nonzero if the channel has no B channel.
The channel is either on hold or a call waiting call.</para>
</enum>
<enum name="buffers">
<para>W/O Change the channel's buffer policy (for the current call only)</para>
<para>This option takes two arguments:</para>
<para> Number of buffers,</para>
<para> Buffer policy being one of:</para>
<para> <literal>full</literal></para>
<para> <literal>immediate</literal></para>
<para> <literal>half</literal></para>
</enum>
<enum name="echocan_mode">
<para>W/O Change the configuration of the active echo
canceller on the channel (if any), for the current call
only.</para>
<para>Possible values are:</para>
<para> <literal>on</literal> Normal mode (the echo canceller is actually reinitalized)</para>
<para> <literal>off</literal> Disabled</para>
<para> <literal>fax</literal> FAX/data mode (NLP disabled if possible, otherwise
completely disabled)</para>
<para> <literal>voice</literal> Voice mode (returns from FAX mode, reverting the changes that were made)</para>
</enum>
</enumlist>
</info>
<manager name="DAHDITransfer" language="en_US">
<synopsis>
Transfer DAHDI Channel.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel" required="true">
<para>DAHDI channel number to transfer.</para>
</parameter>
</syntax>
<description>
<para>Simulate a flash hook event by the user connected to the channel.</para>
<note><para>Valid only for analog channels.</para></note>
</description>
</manager>
<manager name="DAHDIHangup" language="en_US">
<synopsis>
Hangup DAHDI Channel.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel" required="true">
<para>DAHDI channel number to hangup.</para>
</parameter>
</syntax>
<description>
<para>Simulate an on-hook event by the user connected to the channel.</para>
<note><para>Valid only for analog channels.</para></note>
</description>
</manager>
<manager name="DAHDIDialOffhook" language="en_US">
<synopsis>
Dial over DAHDI channel while offhook.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel" required="true">
<para>DAHDI channel number to dial digits.</para>
</parameter>
<parameter name="Number" required="true">
<para>Digits to dial.</para>
</parameter>
</syntax>
<description>
<para>Generate DTMF control frames to the bridged peer.</para>
</description>
</manager>
<manager name="DAHDIDNDon" language="en_US">
<synopsis>
Toggle DAHDI channel Do Not Disturb status ON.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel" required="true">
<para>DAHDI channel number to set DND on.</para>
</parameter>
</syntax>
<description>
<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
<note><para>Feature only supported by analog channels.</para></note>
</description>
</manager>
<manager name="DAHDIDNDoff" language="en_US">
<synopsis>
Toggle DAHDI channel Do Not Disturb status OFF.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel" required="true">
<para>DAHDI channel number to set DND off.</para>
</parameter>
</syntax>
<description>
<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
<note><para>Feature only supported by analog channels.</para></note>
</description>
</manager>
<manager name="DAHDIShowChannels" language="en_US">
<synopsis>
Show status of DAHDI channels.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="DAHDIChannel">
<para>Specify the specific channel number to show. Show all channels if zero or not present.</para>
</syntax>
<description>
<para>Similar to the CLI command "dahdi show channels".</para>
</description>
</manager>
<manager name="DAHDIRestart" language="en_US">
<synopsis>
Fully Restart DAHDI channels (terminates calls).
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
</syntax>
<description>
<para>Equivalent to the CLI command "dahdi restart".</para>
</description>
</manager>
<manager name="PRIShowSpans" language="en_US">
<synopsis>
Show status of PRI spans.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="Span">
<para>Specify the specific span to show. Show all spans if zero or not present.</para>
</parameter>
</syntax>
<description>
<para>Similar to the CLI command "pri show spans".</para>
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
<manager name="PRIDebugSet" language="en_US">
<synopsis>
Set PRI debug levels for a span
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="Span" required="true">
<para>Which span to affect.</para>
</parameter>
<parameter name="Level" required="true">
<para>What debug level to set. May be a numerical value or a text value from the list below</para>
<enumlist>
<enum name="off" />
<enum name="on" />
<enum name="hex" />
<enum name="intense" />
</enumlist>
</parameter>
</syntax>
<description>
<para>Equivalent to the CLI command "pri set debug <level> span <span>".</para>
</description>
</manager>
<manager name="PRIDebugFileSet" language="en_US">
<synopsis>
Set the file used for PRI debug message output
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="File" required="true">
<para>Path of file to write debug output.</para>
</parameter>
</syntax>
<description>
<para>Equivalent to the CLI command "pri set debug file <output-file>"</para>
</description>
</manager>
<manager name="PRIDebugFileUnset" language="en_US">
<synopsis>
Disables file output for PRI debug messages
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
</syntax>
</manager>
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
<managerEvent language="en_US" name="AlarmClear">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<synopsis>Raised when an alarm is cleared on a DAHDI channel.</synopsis>
<syntax>
<parameter name="DAHDIChannel">
<para>The DAHDI channel on which the alarm was cleared.</para>
<note><para>This is not an Asterisk channel identifier.</para></note>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="SpanAlarmClear">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<synopsis>Raised when an alarm is cleared on a DAHDI span.</synopsis>
<syntax>
<parameter name="Span">
<para>The span on which the alarm was cleared.</para>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="DNDState">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<synopsis>Raised when the Do Not Disturb state is changed on a DAHDI channel.</synopsis>
<syntax>
<parameter name="DAHDIChannel">
<para>The DAHDI channel on which DND status changed.</para>
<note><para>This is not an Asterisk channel identifier.</para></note>
</parameter>
<parameter name="Status">
<enumlist>
<enum name="enabled"/>
<enum name="disabled"/>
</enumlist>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="Alarm">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<synopsis>Raised when an alarm is set on a DAHDI channel.</synopsis>
<syntax>
<parameter name="DAHDIChannel">
<para>The channel on which the alarm occurred.</para>
<note><para>This is not an Asterisk channel identifier.</para></note>
</parameter>
<parameter name="Alarm">
<para>A textual description of the alarm that occurred.</para>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="SpanAlarm">
<managerEventInstance class="EVENT_FLAG_SYSTEM">
<synopsis>Raised when an alarm is set on a DAHDI span.</synopsis>
<syntax>
<parameter name="Span">
<para>The span on which the alarm occurred.</para>
</parameter>
<parameter name="Alarm">
<para>A textual description of the alarm that occurred.</para>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="DAHDIChannel">
<managerEventInstance class="EVENT_FLAG_CALL">
<synopsis>Raised when a DAHDI channel is created or an underlying technology is associated with a DAHDI channel.</synopsis>
<syntax>
<parameter name="DAHDIGroup">
<para>The DAHDI logical group associated with this channel.</para>
</parameter>
<parameter name="DAHDISpan">
<para>The DAHDI span associated with this channel.</para>
</parameter>
<parameter name="DAHDIChannel">
<para>The DAHDI channel associated with this channel.</para>
</parameter>
</syntax>
</managerEventInstance>
</managerEvent>
Matthew Fredrickson
committed
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
Kevin P. Fleming
committed
static const char * const lbostr[] = {
"0 db (CSU)/0-133 feet (DSX-1)",
"133-266 feet (DSX-1)",
"266-399 feet (DSX-1)",
"399-533 feet (DSX-1)",
"533-655 feet (DSX-1)",
"-7.5db (CSU)",
"-15db (CSU)",
"-22.5db (CSU)"
};
/*! Global jitterbuffer configuration - by default, jb is disabled
* \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
Russell Bryant
committed
static struct ast_jb_conf default_jbconf =
{
.flags = 0,
.max_size = 200,
.resync_threshold = 1000,
.impl = "fixed",
.target_extra = 40,
Russell Bryant
committed
};
static struct ast_jb_conf global_jbconf;
* \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
* the user hangs up to reset the state machine so ring works properly.
* This is used to be able to support kewlstart by putting the zhone in
* groundstart mode since their forward disconnect supervision is entirely
* broken even though their documentation says it isn't and their support
* is entirely unwilling to provide any assistance with their channel banks
* even though their web site says they support their products for life.
*/
/*! \brief Typically, how many rings before we should send Caller*ID */
#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
Kevin P. Fleming
committed
/*! \brief Signaling types that need to use MF detection should be placed in this macro */
#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))
static const char tdesc[] = "DAHDI Telephony"
#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
" w/"
#if defined(HAVE_PRI)
"PRI"
#endif /* defined(HAVE_PRI) */
#if defined(HAVE_SS7)
#if defined(HAVE_PRI)
" & "
#endif /* defined(HAVE_PRI) */
"SS7"
#endif /* defined(HAVE_SS7) */
#if defined(HAVE_OPENR2)
#if defined(HAVE_PRI) || defined(HAVE_SS7)
" & "
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
"MFC/R2"
#endif /* defined(HAVE_OPENR2) */
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
static const char config[] = "chan_dahdi.conf";
Tilghman Lesher
committed
#ifdef LOTS_OF_SPANS
#define NUM_SPANS DAHDI_MAX_SPANS
Tilghman Lesher
committed
#else
#define NUM_SPANS 32
Tilghman Lesher
committed
#endif
Tilghman Lesher
committed
#define CALLPROGRESS_PROGRESS 1
#define CALLPROGRESS_FAX_OUTGOING 2
#define CALLPROGRESS_FAX_INCOMING 4
#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
#define NUM_CADENCE_MAX 25
static int num_cadence = 4;
static int user_has_defined_cadences = 0;
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
{ { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
{ { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
{ { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
{ { 1000, 500, 2500, 5000 } }, /*!< Long ring */
};
/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
* is 1, the second pause is 2 and so on.
*/
static int cidrings[NUM_CADENCE_MAX] = {
2, /*!< Right after first long ring */
4, /*!< Right after long part */
3, /*!< After third chirp */
2, /*!< Second spell */
};
/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
Matthew Fredrickson
committed
static char defaultcic[64] = "";
static char defaultozz[64] = "";
/*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
static char mwimonitornotify[PATH_MAX] = "";
#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
static int mwisend_rpas = 0;
Doug Bailey
committed
#endif
static char progzone[10] = "";
static int usedistinctiveringdetection = 0;
Joshua Colp
committed
static int distinctiveringaftercid = 0;
Kevin P. Fleming
committed
static int mwilevel = 512;
static int dtmfcid_level = 256;
Kevin P. Fleming
committed
#define REPORT_CHANNEL_ALARMS 1
static int report_alarms = REPORT_CHANNEL_ALARMS;
static char pridebugfilename[1024] = "";
#endif
/*! \brief Protect the interface list (of dahdi_pvt's) */
Matthew Fredrickson
committed
Matthew Fredrickson
committed
AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
Matthew Fredrickson
committed
/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
AST_MUTEX_DEFINE_STATIC(monlock);
/*! \brief This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
static pthread_t monitor_thread = AST_PTHREADT_NULL;
static ast_cond_t ss_thread_complete;
AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
AST_MUTEX_DEFINE_STATIC(restart_lock);
static int ss_thread_count = 0;
static int num_restart_pending = 0;
static int dahdi_sendtext(struct ast_channel *c, const char *text);
/*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
static inline int dahdi_get_event(int fd)
if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
/*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
static inline int dahdi_wait_event(int fd)
i = DAHDI_IOMUX_SIGEVENT;
if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
/*! Chunk size to read -- we use 20ms chunks to make things happy. */
#define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
#define MASK_INUSE (1 << 1) /*!< Channel currently in use */
#define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE) /*!< 300 ms */
#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
#define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE) /*!< 100 ms */
#define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE) /*!< 500 ms */
#define MIN_MS_SINCE_FLASH ((2000) ) /*!< 2000 ms */
#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
#define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
/*!
* \brief Configured ring timeout base.
* \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
*/
static int ringt_base = DEFAULT_RINGT;
Matthew Fredrickson
committed
struct dahdi_ss7 {
static struct dahdi_ss7 linksets[NUM_SPANS];
static int cur_ss7type = -1;
static int cur_slc = -1;
static int cur_linkset = -1;
static int cur_pointcode = -1;
static int cur_cicbeginswith = -1;
static int cur_adjpointcode = -1;
static int cur_networkindicator = -1;
static int cur_defaultdpc = -1;
#ifdef HAVE_OPENR2
struct dahdi_mfcr2_conf {
openr2_variant_t variant;
int mfback_timeout;
int metering_pulse_timeout;
int max_ani;
int max_dnis;
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
int dtmf_time_on;
int dtmf_time_off;
#endif
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
int dtmf_end_timeout;
#endif
signed int get_ani_first:2;
Moises Silva
committed
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
signed int skip_category_request:2;
Moises Silva
committed
#endif
unsigned int call_files:1;
unsigned int allow_collect_calls:1;
unsigned int charge_calls:1;
unsigned int accept_on_offer:1;
unsigned int forced_release:1;
unsigned int double_answer:1;
signed int immediate_accept:2;
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
signed int dtmf_dialing:2;
signed int dtmf_detection:2;
#endif
char logdir[OR2_MAX_PATH];
char r2proto_file[OR2_MAX_PATH];
openr2_log_level_t loglevel;
openr2_calling_party_category_t category;
};
/* MFC-R2 pseudo-link structure */
struct dahdi_mfcr2 {
pthread_t r2master; /*!< Thread of master */
openr2_context_t *protocol_context; /*!< OpenR2 context handle */
struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
int numchans; /*!< Number of channels in this R2 block */
Tzafrir Cohen
committed
int nodev; /*!< Link disconnected? */
struct dahdi_mfcr2_conf conf; /*!< Configuration used to setup this pseudo-link */
};
/* malloc'd array of malloc'd r2links */
Richard Mudgett
committed
static struct dahdi_mfcr2 **r2links;
/* how many r2links have been malloc'd */
Richard Mudgett
committed
static int r2links_count = 0;
Mark Spencer
committed
struct dahdi_pri {
Richard Mudgett
committed
int dchannels[SIG_PRI_NUM_DCHANS]; /*!< What channel are the dchannels on */
int mastertrunkgroup; /*!< What trunk group is our master */
int prilogicalspan; /*!< Logical span number within trunk group */
struct sig_pri_span pri;
static struct dahdi_pri pris[NUM_SPANS];
#if defined(HAVE_PRI_CCSS)
/*! DAHDI PRI CCSS agent and monitor type name. */
static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
#endif /* defined(HAVE_PRI_CCSS) */
struct dahdi_pri;
/* Polarity states */
#define POLARITY_IDLE 0
#define POLARITY_REV 1
const char * const subnames[] = {
static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
Richard Mudgett
committed
#if defined(HAVE_PRI)
struct doomed_pri {
struct sig_pri_span *pri;
AST_LIST_ENTRY(doomed_pri) list;
};
static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
static void pri_destroy_span(struct sig_pri_span *pri);
Richard Mudgett
committed
static struct dahdi_parms_pseudo {
int buf_no; /*!< Number of buffers */
int buf_policy; /*!< Buffer policy */
int faxbuf_no; /*!< Number of Fax buffers */
int faxbuf_policy; /*!< Fax buffer policy */
} dahdi_pseudo_parms;
#endif /* defined(HAVE_PRI) */
/*! \brief Channel configuration from chan_dahdi.conf .
* This struct is used for parsing the [channels] section of chan_dahdi.conf.
* Generally there is a field here for every possible configuration item.
*
* The state of fields is saved along the parsing and whenever a 'channel'
* statement is reached, the current dahdi_chan_conf is used to configure the
* channel (struct dahdi_pvt)
* \see dahdi_chan_init for the default values.
struct dahdi_chan_conf {
struct dahdi_pvt chan;
struct dahdi_pri pri;
Matthew Fredrickson
committed
struct dahdi_ss7 ss7;
#ifdef HAVE_OPENR2
struct dahdi_mfcr2_conf mfcr2;
#endif
Kevin P. Fleming
committed
struct dahdi_params timing;
int is_sig_auto; /*!< Use channel signalling from DAHDI? */
/*! Continue configuration even if a channel is not there. */
int ignore_failed_channels;
/*!
* \brief The serial port to listen for SMDI data on
* \note Set from the "smdiport" string read in from chan_dahdi.conf
*/
char smdi_port[SMDI_MAX_FILENAME_LEN];
/*!
* \brief Don't create channels below this number
* \note by default is 0 (no limit)
*/
int wanted_channels_start;
/*!
* \brief Don't create channels above this number (infinity by default)
* \note by default is 0 (special value that means "no limit").
*/
int wanted_channels_end;
/*! returns a new dahdi_chan_conf with default values (by-value) */
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
{
/* recall that if a field is not included here it is initialized
* to 0 or equivalent
*/
struct dahdi_chan_conf conf = {
.pri.pri = {
.nsf = PRI_NSF_NONE,
.switchtype = PRI_SWITCH_NI2,
Tilghman Lesher
committed
.dialplan = PRI_UNKNOWN + 1,
.localdialplan = PRI_NATIONAL_ISDN + 1,
.nodetype = PRI_CPE,
.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
#if defined(HAVE_PRI_CCSS)
.cc_ptmp_recall_mode = 1,/* specificRecall */
.cc_qsig_signaling_link_req = 1,/* retain */
.cc_qsig_signaling_link_rsp = 1,/* retain */
#endif /* defined(HAVE_PRI_CCSS) */
.minunused = 2,
.idleext = "",
.idledial = "",
.internationalprefix = "",
.nationalprefix = "",
.localprefix = "",
.privateprefix = "",
.unknownprefix = "",
.colp_send = SIG_PRI_COLP_UPDATE,
.resetinterval = -1,
Matthew Fredrickson
committed
#endif
#if defined(HAVE_SS7)
.ss7.ss7 = {
Matthew Fredrickson
committed
.called_nai = SS7_NAI_NATIONAL,
.calling_nai = SS7_NAI_NATIONAL,
.internationalprefix = "",
.nationalprefix = "",
.subscriberprefix = "",
.unknownprefix = "",
.networkroutedprefix = ""
Matthew Fredrickson
committed
},
#ifdef HAVE_OPENR2
.mfcr2 = {
.variant = OR2_VAR_ITU,
.mfback_timeout = -1,
.metering_pulse_timeout = -1,
.max_ani = 10,
.max_dnis = 4,
.get_ani_first = -1,
Moises Silva
committed
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
.skip_category_request = -1,
Moises Silva
committed
#endif
.call_files = 0,
.allow_collect_calls = 0,
.charge_calls = 1,
.accept_on_offer = 1,
.forced_release = 0,
.double_answer = 0,
.immediate_accept = -1,
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
.dtmf_dialing = -1,
.dtmf_detection = -1,
.dtmf_time_on = OR2_DEFAULT_DTMF_ON,
.dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
#endif
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
.dtmf_end_timeout = -1,
#endif
.logdir = "",
.r2proto_file = "",
.loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
},
.chan = {
.context = "default",
.cid_num = "",
.cid_name = "",
.mohinterpret = "default",
.mohsuggest = "",
.transfertobusy = 1,
.cid_signalling = CID_SIG_BELL,
.cid_start = CID_START_RING,
.dahditrcallerid = 0,
.use_callerid = 1,
.sig = -1,
.outsigmod = -1,
Doug Bailey
committed
.cid_rxgain = +5.0,
Kevin P. Fleming
committed
.echocancel.head.tap_length = 1,
.busycount = 3,
.accountcode = "",
.mailbox = "",
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
.mwisend_fsk = 1,
Doug Bailey
committed
#endif
.polarityonanswerdelay = 600,
.sendcalleridafter = DEFAULT_CIDRINGS,
.buf_policy = DAHDI_POLICY_IMMEDIATE,
.buf_no = numbufs,
.usefaxbuffers = 0,
.cc_params = ast_cc_config_params_init(),
.firstdigit_timeout = ANALOG_FIRST_DIGIT_TIMEOUT,
.interdigit_timeout = ANALOG_INTER_DIGIT_TIMEOUT,
.matchdigit_timeout = ANALOG_MATCH_DIGIT_TIMEOUT,
},
.timing = {
.prewinktime = -1,
.preflashtime = -1,
.winktime = -1,
.flashtime = -1,
.starttime = -1,
.rxwinktime = -1,
.rxflashtime = -1,
.debouncetime = -1
},
.ignore_failed_channels = 1,
.smdi_port = "/dev/ttyS0",
};
return conf;
}