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 The channel chan_dahdi 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
#include <dahdi/user.h>
#include <dahdi/tonezone.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 "Your installed libss7 is not compatible"
#endif
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 */
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/cdr.h"
#include "asterisk/cel.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"
/*** 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>
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 Driver"
#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";
#define SIG_EM DAHDI_SIG_EM
#define SIG_EMWINK (0x0100000 | DAHDI_SIG_EM)
#define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
#define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
#define SIG_FEATB (0x0800000 | DAHDI_SIG_EM)
#define SIG_E911 (0x1000000 | DAHDI_SIG_EM)
#define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
#define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM)
#define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
#define SIG_FXSLS DAHDI_SIG_FXSLS
#define SIG_FXSGS DAHDI_SIG_FXSGS
#define SIG_FXSKS DAHDI_SIG_FXSKS
#define SIG_FXOLS DAHDI_SIG_FXOLS
#define SIG_FXOGS DAHDI_SIG_FXOGS
#define SIG_FXOKS DAHDI_SIG_FXOKS
#define SIG_PRI DAHDI_SIG_CLEAR
#define SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR)
#define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR)
#define SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR)
#define SIG_SF DAHDI_SIG_SF
#define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF)
#define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
#define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
#define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF)
#define SIG_EM_E1 DAHDI_SIG_EM_E1
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)
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
#define NUM_CADENCE_MAX 25
static int num_cadence = 4;
static int user_has_defined_cadences = 0;
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
#define REPORT_SPAN_ALARMS 2
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 enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
static int dahdi_sendtext(struct ast_channel *c, const char *text);
static void mwi_event_cb(const struct ast_event *event, void *userdata)
{
/* 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 */
struct dahdi_pvt;
/*!
* \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_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 {
pthread_t r2master; /*!< Thread of master */
openr2_context_t *protocol_context; /*!< OpenR2 context handle */
Richard Mudgett
committed
struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
int numchans; /*!< Number of channels in this R2 block */
int monitored_count; /*!< Number of channels being monitored */
};
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;
};
/* 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;
#define SUB_REAL 0 /*!< Active call */
#define SUB_CALLWAIT 1 /*!< Call-Waiting call on hold */
#define SUB_THREEWAY 2 /*!< Three-way call */
/* Polarity states */
#define POLARITY_IDLE 0
#define POLARITY_REV 1
struct distRingData {
int ring[3];
char contextData[AST_MAX_CONTEXT];
struct dahdi_distRings {
struct distRingData ringnum[3];
struct ringContextData ringContext[3];
};
static const char * const subnames[] = {
struct dahdi_subchannel {
Jeff Peeler
committed
int dfd;
struct ast_channel *owner;
int chan;
short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
struct ast_frame f; /*!< One frame for each channel. How did this ever work before? */
unsigned int needringing:1;
unsigned int needbusy:1;
unsigned int needcongestion:1;
unsigned int needanswer:1;
unsigned int needflash:1;
Mark Spencer
committed
unsigned int needhold:1;
unsigned int needunhold:1;
unsigned int linear:1;
unsigned int inthreeway:1;
Kevin P. Fleming
committed
struct dahdi_confinfo curconf;
};
#define CONF_USER_REAL (1 << 0)
#define CONF_USER_THIRDCALL (1 << 1)
#define MAX_SLAVES 4
Doug Bailey
committed
/* States for sending MWI message
* First three states are required for send Ring Pulse Alert Signal
Doug Bailey
committed
*/
typedef enum {
MWI_SEND_NULL = 0,
MWI_SEND_SA,
MWI_SEND_SA_WAIT,
MWI_SEND_PAUSE,
MWI_SEND_SPILL,
MWI_SEND_CLEANUP,
MWI_SEND_DONE,
} mwisend_states;
Doug Bailey
committed
struct mwisend_info {
struct timeval pause;
mwisend_states mwisend_current;
};
/*! Specify the lists dahdi_pvt can be put in. */
enum DAHDI_IFLIST {
DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */
DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */
Richard Mudgett
committed
#if defined(HAVE_PRI)
DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */
#endif /* defined(HAVE_PRI) */
ast_mutex_t lock; /*!< Channel private lock. */
struct callerid_state *cs;
struct ast_channel *owner; /*!< Our current active owner (if applicable) */
/*!< Up to three channels can be associated with this call */
struct dahdi_subchannel sub_unused; /*!< Just a safety precaution */
struct dahdi_subchannel subs[3]; /*!< Sub-channels */
struct dahdi_confinfo saveconf; /*!< Saved conference info */
struct dahdi_pvt *slaves[MAX_SLAVES]; /*!< Slave to us (follows our conferencing) */
struct dahdi_pvt *master; /*!< Master to us (we follow their conferencing) */
int inconference; /*!< If our real should be in the conference */
int bufsize; /*!< Size of the buffers */
int buf_no; /*!< Number of buffers */
int buf_policy; /*!< Buffer policy */
int faxbuf_no; /*!< Number of Fax buffers */
int faxbuf_policy; /*!< Fax buffer policy */
/*!
* \brief Nonzero if the signaling type is sent over a radio.
* \note Set to a couple of nonzero values but it is only tested like a boolean.
*/
int radio;
int outsigmod; /*!< Outbound Signalling style (modifier) */
int oprmode; /*!< "Operator Services" mode */
struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */
/*! \brief Amount of gain to increase during caller id */
float cid_rxgain;
/*! \brief Rx gain set by chan_dahdi.conf */
float txdrc; /*!< Dynamic Range Compression factor. a number between 1 and 6ish */
float rxdrc;
int tonezone; /*!< tone zone for this chan, or -1 for default */
enum DAHDI_IFLIST which_iflist; /*!< Which interface list is this structure listed? */
struct dahdi_pvt *next; /*!< Next channel in list */
struct dahdi_pvt *prev; /*!< Prev channel in list */
/* flags */
/*!
* \brief TRUE if ADSI (Analog Display Services Interface) available
* \note Set from the "adsi" value read in from chan_dahdi.conf
*/
unsigned int adsi:1;
/*!
* \brief TRUE if we can use a polarity reversal to mark when an outgoing
* call is answered by the remote party.
* \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
*/
unsigned int answeronpolarityswitch:1;
/*!
* \brief TRUE if busy detection is enabled.
* (Listens for the beep-beep busy pattern.)
* \note Set from the "busydetect" value read in from chan_dahdi.conf
*/
unsigned int busydetect:1;
/*!
* \brief TRUE if call return is enabled.
* (*69, if your dialplan doesn't catch this first)
* \note Set from the "callreturn" value read in from chan_dahdi.conf
*/
unsigned int callreturn:1;
/*!
* \brief TRUE if busy extensions will hear the call-waiting tone
* and can use hook-flash to switch between callers.
* \note Can be disabled by dialing *70.
* \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
*/
unsigned int callwaiting:1;
/*!
* \brief TRUE if send caller ID for Call Waiting
* \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
*/
unsigned int callwaitingcallerid:1;
/*!
* \brief TRUE if support for call forwarding enabled.
* Dial *72 to enable call forwarding.
* Dial *73 to disable call forwarding.
* \note Set from the "cancallforward" value read in from chan_dahdi.conf
*/
unsigned int cancallforward:1;
/*!
* \brief TRUE if support for call parking is enabled.
* \note Set from the "canpark" value read in from chan_dahdi.conf
*/
unsigned int canpark:1;
/*! \brief TRUE if to wait for a DTMF digit to confirm answer */
unsigned int confirmanswer:1;
/*!
* \brief TRUE if the channel is to be destroyed on hangup.
* (Used by pseudo channels.)
*/
unsigned int destroy:1;
unsigned int didtdd:1; /*!< flag to say its done it once */
/*! \brief TRUE if analog type line dialed no digits in Dial() */
unsigned int dialednone:1;
/*!
* \brief TRUE if in the process of dialing digits or sending something.
* \note This is used as a receive squelch for ISDN until connected.
*/
unsigned int dialing:1;
/*! \brief TRUE if the transfer capability of the call is digital. */
unsigned int digital:1;
/*! \brief TRUE if Do-Not-Disturb is enabled, present only for non sig_analog */
unsigned int dnd:1;
unsigned int echobreak:1;
/*!
* \brief TRUE if echo cancellation enabled when bridged.
* \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
* \note Disabled if the echo canceller is not setup.
*/
unsigned int echocanbridged:1;
/*! \brief TRUE if echo cancellation is turned on. */
unsigned int echocanon:1;
/*! \brief TRUE if a fax tone has already been handled. */
unsigned int faxhandled:1;
Kevin P. Fleming
committed
/*! TRUE if dynamic faxbuffers are configured for use, default is OFF */
unsigned int usefaxbuffers:1;
Kevin P. Fleming
committed
/*! TRUE while buffer configuration override is in use */
unsigned int bufferoverrideinuse:1;
/*! \brief TRUE if over a radio and dahdi_read() has been called. */
unsigned int firstradio:1;
/*!
* \brief TRUE if the call will be considered "hung up" on a polarity reversal.
* \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
*/
unsigned int hanguponpolarityswitch:1;
/*! \brief TRUE if DTMF detection needs to be done by hardware. */
unsigned int hardwaredtmf:1;
/*!
* \brief TRUE if the outgoing caller ID is blocked/hidden.
* \note Caller ID can be disabled by dialing *67.
* \note Caller ID can be enabled by dialing *82.
* \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
*/
Matthew Fredrickson
committed
unsigned int hidecallerid:1;
/*!
* \brief TRUE if hide just the name not the number for legacy PBX use.
* \note Only applies to PRI channels.
* \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
*/
unsigned int hidecalleridname:1;
/*! \brief TRUE if DTMF detection is disabled. */
unsigned int ignoredtmf:1;
/*!
* \brief TRUE if the channel should be answered immediately
* without attempting to gather any digits.
* \note Set from the "immediate" value read in from chan_dahdi.conf
*/
unsigned int immediate:1;
/*! \brief TRUE if in an alarm condition. */
unsigned int inalarm:1;
/*! \brief TRUE if TDD in MATE mode */
unsigned int mate:1;
/*! \brief TRUE if we originated the call leg. */
unsigned int outgoing:1;
/* unsigned int overlapdial:1; unused and potentially confusing */
/*!
* \brief TRUE if busy extensions will hear the call-waiting tone
* and can use hook-flash to switch between callers.
* \note Set from the "callwaiting" value read in from chan_dahdi.conf
*/
unsigned int permcallwaiting:1;
/*!
* \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
* \note Set from the "hidecallerid" value read in from chan_dahdi.conf
*/
unsigned int permhidecallerid:1;
/*!
* \brief TRUE if PRI congestion/busy indications are sent out-of-band.
* \note Set from the "priindication" value read in from chan_dahdi.conf
*/
unsigned int priindication_oob:1;
/*!
* \brief TRUE if PRI B channels are always exclusively selected.
* \note Set from the "priexclusive" value read in from chan_dahdi.conf
*/
Matthew Fredrickson
committed
unsigned int priexclusive:1;
/*!
* \brief TRUE if we will pulse dial.
* \note Set from the "pulsedial" value read in from chan_dahdi.conf
*/
unsigned int pulse:1;
/*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
unsigned int pulsedial:1;
unsigned int restartpending:1; /*!< flag to ensure counted only once for restart */
/*!
* \brief TRUE if caller ID is restricted.
* \note Set but not used. Should be deleted. Redundant with permhidecallerid.
* \note Set from the "restrictcid" value read in from chan_dahdi.conf
*/
unsigned int restrictcid:1;
/*!
* \brief TRUE if three way calling is enabled
* \note Set from the "threewaycalling" value read in from chan_dahdi.conf
*/
unsigned int threewaycalling:1;
/*!
* \brief TRUE if call transfer is enabled
* \note For FXS ports (either direct analog or over T1/E1):
* Support flash-hook call transfer
* \note For digital ports using ISDN PRI protocols:
* Support switch-side transfer (called 2BCT, RLT or other names)
* \note Set from the "transfer" value read in from chan_dahdi.conf
*/
unsigned int transfer:1;
/*!
* \brief TRUE if caller ID is used on this channel.
* \note PRI and SS7 spans will save caller ID from the networking peer.
* \note FXS ports will generate the caller ID spill.
* \note FXO ports will listen for the caller ID spill.
* \note Set from the "usecallerid" value read in from chan_dahdi.conf
*/
unsigned int use_callerid:1;
/*!
* \brief TRUE if we will use the calling presentation setting
* from the Asterisk channel for outgoing calls.
* \note Only applies to PRI and SS7 channels.
* \note Set from the "usecallingpres" value read in from chan_dahdi.conf
*/
unsigned int use_callingpres:1;
/*!
* \brief TRUE if distinctive rings are to be detected.
* \note For FXO lines
* \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
*/
unsigned int usedistinctiveringdetection:1;
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
/*!
* \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
* \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
*/
unsigned int dahditrcallerid:1;
/*!
* \brief TRUE if allowed to flash-transfer to busy channels.
* \note Set from the "transfertobusy" value read in from chan_dahdi.conf
*/
unsigned int transfertobusy:1;
/*!
* \brief TRUE if the FXO port monitors for neon type MWI indications from the other end.
* \note Set if the "mwimonitor" value read in contains "neon" from chan_dahdi.conf
*/
unsigned int mwimonitor_neon:1;
/*!
* \brief TRUE if the FXO port monitors for fsk type MWI indications from the other end.
* \note Set if the "mwimonitor" value read in contains "fsk" from chan_dahdi.conf
*/
unsigned int mwimonitor_fsk:1;
/*!
* \brief TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
* \note RPAS - Ring Pulse Alert Signal
* \note Set if the "mwimonitor" value read in contains "rpas" from chan_dahdi.conf
*/
unsigned int mwimonitor_rpas:1;
/*! \brief TRUE if an MWI monitor thread is currently active */
unsigned int mwimonitoractive:1;
/*! \brief TRUE if a MWI message sending thread is active */
unsigned int mwisendactive:1;
/*!
* \brief TRUE if channel is out of reset and ready
* \note Set but not used.
*/
Matthew Fredrickson
committed
unsigned int inservice:1;
/*!
* \brief TRUE if the channel is locally blocked.
* \note Applies to SS7 and MFCR2 channels.
Matthew Fredrickson
committed
unsigned int locallyblocked:1;
/*!
* \brief TRUE if the channel is remotely blocked.
* \note Applies to SS7 and MFCR2 channels.
Matthew Fredrickson
committed
unsigned int remotelyblocked:1;