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"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <pthread.h>
#include <signal.h>
#else
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/app.h"
#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/astobj.h"
#include "asterisk/data.h"
#include "asterisk/features_config.h"
#include "asterisk/parking.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>
<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>
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
<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>
344
345
346
347
348
349
350
351
352
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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
<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="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;
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
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 Wait up to 16 seconds for first digit (FXO logic) */
/*! \brief How long to wait for following digits (FXO logic) */
/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
/*! \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);
static void mwi_event_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
{
/* This module does not handle MWI in an event-based manner. However, it
* subscribes to MWI for each mailbox that is configured so that the core
* knows that we care about it. Then, chan_dahdi will get the MWI from the
* event cache instead of checking the mailbox directly. */
}
/*! \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 */
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[] = {
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
#define DATA_EXPORT_DAHDI_PVT(MEMBER) \
MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE) \
MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE) \
MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE) \
MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE) \
MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE) \
MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, locallyblocked, AST_DATA_UNSIGNED_INTEGER) \
MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_UNSIGNED_INTEGER) \
MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN) \
MEMBER(dahdi_pvt, context, AST_DATA_STRING) \
MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING) \
MEMBER(dahdi_pvt, description, AST_DATA_STRING) \
MEMBER(dahdi_pvt, exten, AST_DATA_STRING) \
MEMBER(dahdi_pvt, language, AST_DATA_STRING) \
MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING) \
MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING) \
MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
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,