2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief DAHDI for Pseudo TDM
23 * \author Mark Spencer <markster@digium.com>
25 * Connects to the DAHDI telephony library as well as
26 * libpri. Libpri is optional and needed only if you are
27 * going to use ISDN connections.
29 * You need to install libraries before you attempt to compile
30 * and install the DAHDI channel.
33 * \arg \ref Config_dahdi
35 * \ingroup channel_drivers
37 * \todo Deprecate the "musiconhold" configuration option post 1.4
41 <depend>res_smdi</depend>
42 <depend>dahdi</depend>
43 <depend>tonezone</depend>
51 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
53 #if defined(__NetBSD__) || defined(__FreeBSD__)
57 #include <sys/signal.h>
59 #include <sys/ioctl.h>
64 #include <dahdi/user.h>
65 #include <dahdi/tonezone.h>
66 #include "sig_analog.h"
67 /* Analog signaling is currently still present in chan_dahdi for use with
68 * radio. Sig_analog does not currently handle any radio operations. If
69 * radio only uses analog signaling, then the radio handling logic could
70 * be placed in sig_analog and the duplicated code could be removed.
79 #endif /* defined(HAVE_SS7) */
82 /* put this here until sig_mfcr2 comes along */
83 #define SIG_MFCR2_MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
87 #include "asterisk/lock.h"
88 #include "asterisk/channel.h"
89 #include "asterisk/config.h"
90 #include "asterisk/module.h"
91 #include "asterisk/pbx.h"
92 #include "asterisk/file.h"
93 #include "asterisk/ulaw.h"
94 #include "asterisk/alaw.h"
95 #include "asterisk/callerid.h"
96 #include "asterisk/adsi.h"
97 #include "asterisk/cli.h"
98 #include "asterisk/cdr.h"
99 #include "asterisk/cel.h"
100 #include "asterisk/features.h"
101 #include "asterisk/musiconhold.h"
102 #include "asterisk/say.h"
103 #include "asterisk/tdd.h"
104 #include "asterisk/app.h"
105 #include "asterisk/dsp.h"
106 #include "asterisk/astdb.h"
107 #include "asterisk/manager.h"
108 #include "asterisk/causes.h"
109 #include "asterisk/term.h"
110 #include "asterisk/utils.h"
111 #include "asterisk/transcap.h"
112 #include "asterisk/stringfields.h"
113 #include "asterisk/abstract_jb.h"
114 #include "asterisk/smdi.h"
115 #include "asterisk/astobj.h"
116 #include "asterisk/event.h"
117 #include "asterisk/devicestate.h"
118 #include "asterisk/paths.h"
119 #include "asterisk/ccss.h"
120 #include "asterisk/data.h"
123 <application name="DAHDISendKeypadFacility" language="en_US">
125 Send digits out of band over a PRI.
128 <parameter name="digits" required="true" />
131 <para>This application will send the given string of digits in a Keypad
132 Facility IE over the current channel.</para>
135 <application name="DAHDISendCallreroutingFacility" language="en_US">
137 Send QSIG call rerouting facility over a PRI.
140 <parameter name="destination" required="true">
141 <para>Destination number.</para>
143 <parameter name="original">
144 <para>Original called number.</para>
146 <parameter name="reason">
147 <para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
151 <para>This application will send a Callrerouting Facility IE over the
152 current channel.</para>
155 <application name="DAHDIAcceptR2Call" language="en_US">
157 Accept an R2 call if its not already accepted (you still need to answer it)
160 <parameter name="charge" required="true">
161 <para>Yes or No.</para>
162 <para>Whether you want to accept the call with charge or without charge.</para>
166 <para>This application will Accept the R2 call either with charge or no charge.</para>
169 <manager name="DAHDITransfer" language="en_US">
171 Transfer DAHDI Channel.
174 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
175 <parameter name="DAHDIChannel" required="true">
176 <para>DAHDI channel name to transfer.</para>
180 <para>Transfer a DAHDI channel.</para>
183 <manager name="DAHDIHangup" language="en_US">
185 Hangup DAHDI Channel.
188 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
189 <parameter name="DAHDIChannel" required="true">
190 <para>DAHDI channel name to hangup.</para>
194 <para>Hangup a DAHDI channel.</para>
197 <manager name="DAHDIDialOffhook" language="en_US">
199 Dial over DAHDI channel while offhook.
202 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
203 <parameter name="DAHDIChannel" required="true" />
204 <parameter name="Number" required="true" />
209 <manager name="DAHDIDNDon" language="en_US">
211 Toggle DAHDI channel Do Not Disturb status ON.
214 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
215 <parameter name="DAHDIChannel" required="true" />
220 <manager name="DAHDIDNDoff" language="en_US">
222 Toggle DAHDI channel Do Not Disturb status OFF.
225 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
226 <parameter name="DAHDIChannel" required="true" />
231 <manager name="DAHDIShowChannels" language="en_US">
233 Show status DAHDI channels.
236 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
237 <parameter name="DAHDIChannel" required="true" />
242 <manager name="DAHDIRestart" language="en_US">
244 Fully Restart DAHDI channels (terminates calls).
247 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
254 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
256 static const char * const lbostr[] = {
257 "0 db (CSU)/0-133 feet (DSX-1)",
258 "133-266 feet (DSX-1)",
259 "266-399 feet (DSX-1)",
260 "399-533 feet (DSX-1)",
261 "533-655 feet (DSX-1)",
267 /*! Global jitterbuffer configuration - by default, jb is disabled */
268 static struct ast_jb_conf default_jbconf =
272 .resync_threshold = -1,
276 static struct ast_jb_conf global_jbconf;
279 * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
280 * the user hangs up to reset the state machine so ring works properly.
281 * This is used to be able to support kewlstart by putting the zhone in
282 * groundstart mode since their forward disconnect supervision is entirely
283 * broken even though their documentation says it isn't and their support
284 * is entirely unwilling to provide any assistance with their channel banks
285 * even though their web site says they support their products for life.
287 /* #define ZHONE_HACK */
290 * Define if you want to check the hook state for an FXO (FXS signalled) interface
291 * before dialing on it. Certain FXO interfaces always think they're out of
292 * service with this method however.
294 /* #define DAHDI_CHECK_HOOKSTATE */
296 /*! \brief Typically, how many rings before we should send Caller*ID */
297 #define DEFAULT_CIDRINGS 1
299 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
302 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
303 #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))
305 static const char tdesc[] = "DAHDI Telephony Driver"
306 #if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
308 #if defined(HAVE_PRI)
310 #endif /* defined(HAVE_PRI) */
311 #if defined(HAVE_SS7)
312 #if defined(HAVE_PRI)
314 #endif /* defined(HAVE_PRI) */
316 #endif /* defined(HAVE_SS7) */
317 #if defined(HAVE_OPENR2)
318 #if defined(HAVE_PRI) || defined(HAVE_SS7)
320 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
322 #endif /* defined(HAVE_OPENR2) */
323 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
326 static const char config[] = "chan_dahdi.conf";
328 #define SIG_EM DAHDI_SIG_EM
329 #define SIG_EMWINK (0x0100000 | DAHDI_SIG_EM)
330 #define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
331 #define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
332 #define SIG_FEATB (0x0800000 | DAHDI_SIG_EM)
333 #define SIG_E911 (0x1000000 | DAHDI_SIG_EM)
334 #define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
335 #define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM)
336 #define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
337 #define SIG_FXSLS DAHDI_SIG_FXSLS
338 #define SIG_FXSGS DAHDI_SIG_FXSGS
339 #define SIG_FXSKS DAHDI_SIG_FXSKS
340 #define SIG_FXOLS DAHDI_SIG_FXOLS
341 #define SIG_FXOGS DAHDI_SIG_FXOGS
342 #define SIG_FXOKS DAHDI_SIG_FXOKS
343 #define SIG_PRI DAHDI_SIG_CLEAR
344 #define SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR)
345 #define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR)
346 #define SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR)
347 #define SIG_MFCR2 DAHDI_SIG_CAS
348 #define SIG_SF DAHDI_SIG_SF
349 #define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF)
350 #define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
351 #define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
352 #define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF)
353 #define SIG_EM_E1 DAHDI_SIG_EM_E1
356 #define NUM_SPANS DAHDI_MAX_SPANS
361 #define CHAN_PSEUDO -2
363 #define CALLPROGRESS_PROGRESS 1
364 #define CALLPROGRESS_FAX_OUTGOING 2
365 #define CALLPROGRESS_FAX_INCOMING 4
366 #define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
368 #define NUM_CADENCE_MAX 25
369 static int num_cadence = 4;
370 static int user_has_defined_cadences = 0;
372 static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
373 { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
374 { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
375 { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
376 { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
379 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
380 * is 1, the second pause is 2 and so on.
383 static int cidrings[NUM_CADENCE_MAX] = {
384 2, /*!< Right after first long ring */
385 4, /*!< Right after long part */
386 3, /*!< After third chirp */
387 2, /*!< Second spell */
390 /* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
391 static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
393 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
394 (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
396 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
397 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
399 static char defaultcic[64] = "";
400 static char defaultozz[64] = "";
402 static char parkinglot[AST_MAX_EXTENSION] = ""; /*!< Default parking lot for this channel */
404 /*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
405 static char mwimonitornotify[PATH_MAX] = "";
406 #ifndef HAVE_DAHDI_LINEREVERSE_VMWI
407 static int mwisend_rpas = 0;
410 static char progzone[10] = "";
412 static int usedistinctiveringdetection = 0;
413 static int distinctiveringaftercid = 0;
415 static int numbufs = 4;
417 static int mwilevel = 512;
418 static int dtmfcid_level = 256;
420 #define REPORT_CHANNEL_ALARMS 1
421 #define REPORT_SPAN_ALARMS 2
422 static int report_alarms = REPORT_CHANNEL_ALARMS;
425 static int pridebugfd = -1;
426 static char pridebugfilename[1024] = "";
429 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
430 static int firstdigittimeout = 16000;
432 /*! \brief How long to wait for following digits (FXO logic) */
433 static int gendigittimeout = 8000;
435 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
436 static int matchdigittimeout = 3000;
438 /*! \brief Protect the interface list (of dahdi_pvt's) */
439 AST_MUTEX_DEFINE_STATIC(iflock);
442 static int ifcount = 0;
445 AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
448 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
449 when it's doing something critical. */
450 AST_MUTEX_DEFINE_STATIC(monlock);
452 /*! \brief This is the thread for the monitor which checks for input on the channels
453 which are not currently in use. */
454 static pthread_t monitor_thread = AST_PTHREADT_NULL;
455 static ast_cond_t ss_thread_complete;
456 AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
457 AST_MUTEX_DEFINE_STATIC(restart_lock);
458 static int ss_thread_count = 0;
459 static int num_restart_pending = 0;
461 static int restart_monitor(void);
463 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);
465 static int dahdi_sendtext(struct ast_channel *c, const char *text);
467 static void mwi_event_cb(const struct ast_event *event, void *userdata)
469 /* This module does not handle MWI in an event-based manner. However, it
470 * subscribes to MWI for each mailbox that is configured so that the core
471 * knows that we care about it. Then, chan_dahdi will get the MWI from the
472 * event cache instead of checking the mailbox directly. */
475 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
476 static inline int dahdi_get_event(int fd)
479 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
484 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
485 static inline int dahdi_wait_event(int fd)
488 i = DAHDI_IOMUX_SIGEVENT;
489 if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
491 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
496 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
497 #define READ_SIZE 160
499 #define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
500 #define MASK_INUSE (1 << 1) /*!< Channel currently in use */
502 #define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) /*!< 300 ms */
503 #define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
504 #define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) /*!< 500 ms */
505 #define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
506 #define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
511 * \brief Configured ring timeout base.
512 * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
514 static int ringt_base = DEFAULT_RINGT;
516 #if defined(HAVE_SS7)
519 struct sig_ss7_linkset ss7;
522 static struct dahdi_ss7 linksets[NUM_SPANS];
524 static int cur_ss7type = -1;
525 static int cur_linkset = -1;
526 static int cur_pointcode = -1;
527 static int cur_cicbeginswith = -1;
528 static int cur_adjpointcode = -1;
529 static int cur_networkindicator = -1;
530 static int cur_defaultdpc = -1;
531 #endif /* defined(HAVE_SS7) */
535 pthread_t r2master; /*!< Thread of master */
536 openr2_context_t *protocol_context; /*!< OpenR2 context handle */
537 struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS]; /*!< Member channel pvt structs */
538 int numchans; /*!< Number of channels in this R2 block */
539 int monitored_count; /*!< Number of channels being monitored */
542 struct dahdi_mfcr2_conf {
543 openr2_variant_t variant;
545 int metering_pulse_timeout;
548 signed int get_ani_first:2;
549 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
550 signed int skip_category_request:2;
552 unsigned int call_files:1;
553 unsigned int allow_collect_calls:1;
554 unsigned int charge_calls:1;
555 unsigned int accept_on_offer:1;
556 unsigned int forced_release:1;
557 unsigned int double_answer:1;
558 signed int immediate_accept:2;
559 char logdir[OR2_MAX_PATH];
560 char r2proto_file[OR2_MAX_PATH];
561 openr2_log_level_t loglevel;
562 openr2_calling_party_category_t category;
565 /* malloc'd array of malloc'd r2links */
566 static struct dahdi_mfcr2 **r2links;
567 /* how many r2links have been malloc'd */
568 static int r2links_count = 0;
570 #endif /* HAVE_OPENR2 */
575 int dchannels[SIG_PRI_NUM_DCHANS]; /*!< What channel are the dchannels on */
576 int mastertrunkgroup; /*!< What trunk group is our master */
577 int prilogicalspan; /*!< Logical span number within trunk group */
578 struct sig_pri_pri pri;
581 static struct dahdi_pri pris[NUM_SPANS];
583 #if defined(HAVE_PRI_CCSS)
584 /*! DAHDI PRI CCSS agent and monitor type name. */
585 static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
586 #endif /* defined(HAVE_PRI_CCSS) */
589 /*! Shut up the compiler */
593 #define SUB_REAL 0 /*!< Active call */
594 #define SUB_CALLWAIT 1 /*!< Call-Waiting call on hold */
595 #define SUB_THREEWAY 2 /*!< Three-way call */
597 /* Polarity states */
598 #define POLARITY_IDLE 0
599 #define POLARITY_REV 1
602 struct distRingData {
606 struct ringContextData {
607 char contextData[AST_MAX_CONTEXT];
609 struct dahdi_distRings {
610 struct distRingData ringnum[3];
611 struct ringContextData ringContext[3];
614 static const char * const subnames[] = {
620 struct dahdi_subchannel {
622 struct ast_channel *owner;
624 short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
625 struct ast_frame f; /*!< One frame for each channel. How did this ever work before? */
626 unsigned int needringing:1;
627 unsigned int needbusy:1;
628 unsigned int needcongestion:1;
629 unsigned int needanswer:1;
630 unsigned int needflash:1;
631 unsigned int needhold:1;
632 unsigned int needunhold:1;
633 unsigned int linear:1;
634 unsigned int inthreeway:1;
635 struct dahdi_confinfo curconf;
638 #define CONF_USER_REAL (1 << 0)
639 #define CONF_USER_THIRDCALL (1 << 1)
643 /* States for sending MWI message
644 * First three states are required for send Ring Pulse Alert Signal
656 struct mwisend_info {
657 struct timeval pause;
658 mwisend_states mwisend_current;
661 /*! Specify the lists dahdi_pvt can be put in. */
663 DAHDI_IFLIST_NONE, /*!< The dahdi_pvt is not in any list. */
664 DAHDI_IFLIST_MAIN, /*!< The dahdi_pvt is in the main interface list */
665 #if defined(HAVE_PRI)
666 DAHDI_IFLIST_NO_B_CHAN, /*!< The dahdi_pvt is in a no B channel interface list */
667 #endif /* defined(HAVE_PRI) */
671 ast_mutex_t lock; /*!< Channel private lock. */
672 struct callerid_state *cs;
673 struct ast_channel *owner; /*!< Our current active owner (if applicable) */
674 /*!< Up to three channels can be associated with this call */
676 struct dahdi_subchannel sub_unused; /*!< Just a safety precaution */
677 struct dahdi_subchannel subs[3]; /*!< Sub-channels */
678 struct dahdi_confinfo saveconf; /*!< Saved conference info */
680 struct dahdi_pvt *slaves[MAX_SLAVES]; /*!< Slave to us (follows our conferencing) */
681 struct dahdi_pvt *master; /*!< Master to us (we follow their conferencing) */
682 int inconference; /*!< If our real should be in the conference */
684 int bufsize; /*!< Size of the buffers */
685 int buf_no; /*!< Number of buffers */
686 int buf_policy; /*!< Buffer policy */
687 int faxbuf_no; /*!< Number of Fax buffers */
688 int faxbuf_policy; /*!< Fax buffer policy */
689 int sig; /*!< Signalling style */
691 * \brief Nonzero if the signaling type is sent over a radio.
692 * \note Set to a couple of nonzero values but it is only tested like a boolean.
695 int outsigmod; /*!< Outbound Signalling style (modifier) */
696 int oprmode; /*!< "Operator Services" mode */
697 struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */
698 /*! \brief Amount of gain to increase during caller id */
700 /*! \brief Rx gain set by chan_dahdi.conf */
702 /*! \brief Tx gain set by chan_dahdi.conf */
705 float txdrc; /*!< Dynamic Range Compression factor. a number between 1 and 6ish */
708 int tonezone; /*!< tone zone for this chan, or -1 for default */
709 enum DAHDI_IFLIST which_iflist; /*!< Which interface list is this structure listed? */
710 struct dahdi_pvt *next; /*!< Next channel in list */
711 struct dahdi_pvt *prev; /*!< Prev channel in list */
716 * \brief TRUE if ADSI (Analog Display Services Interface) available
717 * \note Set from the "adsi" value read in from chan_dahdi.conf
721 * \brief TRUE if we can use a polarity reversal to mark when an outgoing
722 * call is answered by the remote party.
723 * \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
725 unsigned int answeronpolarityswitch:1;
727 * \brief TRUE if busy detection is enabled.
728 * (Listens for the beep-beep busy pattern.)
729 * \note Set from the "busydetect" value read in from chan_dahdi.conf
731 unsigned int busydetect:1;
733 * \brief TRUE if call return is enabled.
734 * (*69, if your dialplan doesn't catch this first)
735 * \note Set from the "callreturn" value read in from chan_dahdi.conf
737 unsigned int callreturn:1;
739 * \brief TRUE if busy extensions will hear the call-waiting tone
740 * and can use hook-flash to switch between callers.
741 * \note Can be disabled by dialing *70.
742 * \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
744 unsigned int callwaiting:1;
746 * \brief TRUE if send caller ID for Call Waiting
747 * \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
749 unsigned int callwaitingcallerid:1;
751 * \brief TRUE if support for call forwarding enabled.
752 * Dial *72 to enable call forwarding.
753 * Dial *73 to disable call forwarding.
754 * \note Set from the "cancallforward" value read in from chan_dahdi.conf
756 unsigned int cancallforward:1;
758 * \brief TRUE if support for call parking is enabled.
759 * \note Set from the "canpark" value read in from chan_dahdi.conf
761 unsigned int canpark:1;
762 /*! \brief TRUE if to wait for a DTMF digit to confirm answer */
763 unsigned int confirmanswer:1;
765 * \brief TRUE if the channel is to be destroyed on hangup.
766 * (Used by pseudo channels.)
768 unsigned int destroy:1;
769 unsigned int didtdd:1; /*!< flag to say its done it once */
770 /*! \brief TRUE if analog type line dialed no digits in Dial() */
771 unsigned int dialednone:1;
773 * \brief TRUE if in the process of dialing digits or sending something.
774 * \note This is used as a receive squelch for ISDN until connected.
776 unsigned int dialing:1;
777 /*! \brief TRUE if the transfer capability of the call is digital. */
778 unsigned int digital:1;
779 /*! \brief TRUE if Do-Not-Disturb is enabled, present only for non sig_analog */
781 /*! \brief XXX BOOLEAN Purpose??? */
782 unsigned int echobreak:1;
784 * \brief TRUE if echo cancellation enabled when bridged.
785 * \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
786 * \note Disabled if the echo canceller is not setup.
788 unsigned int echocanbridged:1;
789 /*! \brief TRUE if echo cancellation is turned on. */
790 unsigned int echocanon:1;
791 /*! \brief TRUE if a fax tone has already been handled. */
792 unsigned int faxhandled:1;
793 /*! TRUE if dynamic faxbuffers are configured for use, default is OFF */
794 unsigned int usefaxbuffers:1;
795 /*! TRUE while buffer configuration override is in use */
796 unsigned int bufferoverrideinuse:1;
797 /*! \brief TRUE if over a radio and dahdi_read() has been called. */
798 unsigned int firstradio:1;
800 * \brief TRUE if the call will be considered "hung up" on a polarity reversal.
801 * \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
803 unsigned int hanguponpolarityswitch:1;
804 /*! \brief TRUE if DTMF detection needs to be done by hardware. */
805 unsigned int hardwaredtmf:1;
807 * \brief TRUE if the outgoing caller ID is blocked/hidden.
808 * \note Caller ID can be disabled by dialing *67.
809 * \note Caller ID can be enabled by dialing *82.
810 * \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
812 unsigned int hidecallerid:1;
814 * \brief TRUE if hide just the name not the number for legacy PBX use.
815 * \note Only applies to PRI channels.
816 * \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
818 unsigned int hidecalleridname:1;
819 /*! \brief TRUE if DTMF detection is disabled. */
820 unsigned int ignoredtmf:1;
822 * \brief TRUE if the channel should be answered immediately
823 * without attempting to gather any digits.
824 * \note Set from the "immediate" value read in from chan_dahdi.conf
826 unsigned int immediate:1;
827 /*! \brief TRUE if in an alarm condition. */
828 unsigned int inalarm:1;
829 /*! \brief TRUE if TDD in MATE mode */
831 /*! \brief TRUE if we originated the call leg. */
832 unsigned int outgoing:1;
833 /* unsigned int overlapdial:1; unused and potentially confusing */
835 * \brief TRUE if busy extensions will hear the call-waiting tone
836 * and can use hook-flash to switch between callers.
837 * \note Set from the "callwaiting" value read in from chan_dahdi.conf
839 unsigned int permcallwaiting:1;
841 * \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
842 * \note Set from the "hidecallerid" value read in from chan_dahdi.conf
844 unsigned int permhidecallerid:1;
846 * \brief TRUE if PRI congestion/busy indications are sent out-of-band.
847 * \note Set from the "priindication" value read in from chan_dahdi.conf
849 unsigned int priindication_oob:1;
851 * \brief TRUE if PRI B channels are always exclusively selected.
852 * \note Set from the "priexclusive" value read in from chan_dahdi.conf
854 unsigned int priexclusive:1;
856 * \brief TRUE if we will pulse dial.
857 * \note Set from the "pulsedial" value read in from chan_dahdi.conf
859 unsigned int pulse:1;
860 /*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
861 unsigned int pulsedial:1;
862 unsigned int restartpending:1; /*!< flag to ensure counted only once for restart */
864 * \brief TRUE if caller ID is restricted.
865 * \note Set but not used. Should be deleted. Redundant with permhidecallerid.
866 * \note Set from the "restrictcid" value read in from chan_dahdi.conf
868 unsigned int restrictcid:1;
870 * \brief TRUE if three way calling is enabled
871 * \note Set from the "threewaycalling" value read in from chan_dahdi.conf
873 unsigned int threewaycalling:1;
875 * \brief TRUE if call transfer is enabled
876 * \note For FXS ports (either direct analog or over T1/E1):
877 * Support flash-hook call transfer
878 * \note For digital ports using ISDN PRI protocols:
879 * Support switch-side transfer (called 2BCT, RLT or other names)
880 * \note Set from the "transfer" value read in from chan_dahdi.conf
882 unsigned int transfer:1;
884 * \brief TRUE if caller ID is used on this channel.
885 * \note PRI and SS7 spans will save caller ID from the networking peer.
886 * \note FXS ports will generate the caller ID spill.
887 * \note FXO ports will listen for the caller ID spill.
888 * \note Set from the "usecallerid" value read in from chan_dahdi.conf
890 unsigned int use_callerid:1;
892 * \brief TRUE if we will use the calling presentation setting
893 * from the Asterisk channel for outgoing calls.
894 * \note Only applies to PRI and SS7 channels.
895 * \note Set from the "usecallingpres" value read in from chan_dahdi.conf
897 unsigned int use_callingpres:1;
899 * \brief TRUE if distinctive rings are to be detected.
900 * \note For FXO lines
901 * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
903 unsigned int usedistinctiveringdetection:1;
905 * \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
906 * \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
908 unsigned int dahditrcallerid:1;
910 * \brief TRUE if allowed to flash-transfer to busy channels.
911 * \note Set from the "transfertobusy" value read in from chan_dahdi.conf
913 unsigned int transfertobusy:1;
915 * \brief TRUE if the FXO port monitors for neon type MWI indications from the other end.
916 * \note Set if the "mwimonitor" value read in contains "neon" from chan_dahdi.conf
918 unsigned int mwimonitor_neon:1;
920 * \brief TRUE if the FXO port monitors for fsk type MWI indications from the other end.
921 * \note Set if the "mwimonitor" value read in contains "fsk" from chan_dahdi.conf
923 unsigned int mwimonitor_fsk:1;
925 * \brief TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
926 * \note RPAS - Ring Pulse Alert Signal
927 * \note Set if the "mwimonitor" value read in contains "rpas" from chan_dahdi.conf
929 unsigned int mwimonitor_rpas:1;
930 /*! \brief TRUE if an MWI monitor thread is currently active */
931 unsigned int mwimonitoractive:1;
932 /*! \brief TRUE if a MWI message sending thread is active */
933 unsigned int mwisendactive:1;
935 * \brief TRUE if channel is out of reset and ready
936 * \note Set but not used.
938 unsigned int inservice:1;
940 * \brief TRUE if the channel is locally blocked.
941 * \note Applies to SS7 and MFCR2 channels.
943 unsigned int locallyblocked:1;
945 * \brief TRUE if the channel is remotely blocked.
946 * \note Applies to SS7 and MFCR2 channels.
948 unsigned int remotelyblocked:1;
950 * \brief TRUE if the channel alarms will be managed also as Span ones
951 * \note Applies to all channels
953 unsigned int manages_span_alarms:1;
955 #if defined(HAVE_PRI)
956 struct sig_pri_pri *pri;
960 * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
961 * \note Set from the "usesmdi" value read in from chan_dahdi.conf
963 unsigned int use_smdi:1;
964 struct mwisend_info mwisend_data;
965 /*! \brief The serial port to listen for SMDI data on */
966 struct ast_smdi_interface *smdi_iface;
968 /*! \brief Distinctive Ring data */
969 struct dahdi_distRings drings;
972 * \brief The configured context for incoming calls.
973 * \note The "context" string read in from chan_dahdi.conf
975 char context[AST_MAX_CONTEXT];
977 * \brief Saved context string.
979 char defcontext[AST_MAX_CONTEXT];
980 /*! \brief Extension to use in the dialplan. */
981 char exten[AST_MAX_EXTENSION];
983 * \brief Language configured for calls.
984 * \note The "language" string read in from chan_dahdi.conf
986 char language[MAX_LANGUAGE];
988 * \brief The configured music-on-hold class to use for calls.
989 * \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
991 char mohinterpret[MAX_MUSICCLASS];
993 * \brief Suggested music-on-hold class for peer channel to use for calls.
994 * \note The "mohsuggest" string read in from chan_dahdi.conf
996 char mohsuggest[MAX_MUSICCLASS];
997 char parkinglot[AST_MAX_EXTENSION]; /*!< Parking lot for this channel */
998 #if defined(HAVE_PRI) || defined(HAVE_SS7)
999 /*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
1000 char cid_ani[AST_MAX_EXTENSION];
1001 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
1002 /*! \brief Automatic Number Identification code from PRI */
1004 /*! \brief Caller ID number from an incoming call. */
1005 char cid_num[AST_MAX_EXTENSION];
1007 * \brief Caller ID tag from incoming call
1008 * \note the "cid_tag" string read in from chan_dahdi.conf
1010 char cid_tag[AST_MAX_EXTENSION];
1011 /*! \brief Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise. */
1013 /*! \brief Caller ID name from an incoming call. */
1014 char cid_name[AST_MAX_EXTENSION];
1015 /*! \brief Caller ID subaddress from an incoming call. */
1016 char cid_subaddr[AST_MAX_EXTENSION];
1017 char *origcid_num; /*!< malloced original callerid */
1018 char *origcid_name; /*!< malloced original callerid */
1019 /*! \brief Call waiting number. */
1020 char callwait_num[AST_MAX_EXTENSION];
1021 /*! \brief Call waiting name. */
1022 char callwait_name[AST_MAX_EXTENSION];
1023 /*! \brief Redirecting Directory Number Information Service (RDNIS) number */
1024 char rdnis[AST_MAX_EXTENSION];
1025 /*! \brief Dialed Number Identifier */
1026 char dnid[AST_MAX_EXTENSION];
1028 * \brief Bitmapped groups this belongs to.
1029 * \note The "group" bitmapped group string read in from chan_dahdi.conf
1032 /*! \brief Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW. */
1034 /*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
1036 int confno; /*!< Our conference */
1037 int confusers; /*!< Who is using our conference */
1038 int propconfno; /*!< Propagated conference number */
1040 * \brief Bitmapped call groups this belongs to.
1041 * \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
1043 ast_group_t callgroup;
1045 * \brief Bitmapped pickup groups this belongs to.
1046 * \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
1048 ast_group_t pickupgroup;
1050 * \brief Channel variable list with associated values to set when a channel is created.
1051 * \note The "setvar" strings read in from chan_dahdi.conf
1053 struct ast_variable *vars;
1054 int channel; /*!< Channel Number */
1055 int span; /*!< Span number */
1056 time_t guardtime; /*!< Must wait this much time before using for new call */
1057 int cid_signalling; /*!< CID signalling type bell202 or v23 */
1058 int cid_start; /*!< CID start indicator, polarity or ring or DTMF without warning event */
1059 int dtmfcid_holdoff_state; /*!< State indicator that allows for line to settle before checking for dtmf energy */
1060 struct timeval dtmfcid_delay; /*!< Time value used for allow line to settle */
1061 int callingpres; /*!< The value of calling presentation that we're going to use when placing a PRI call */
1062 int callwaitingrepeat; /*!< How many samples to wait before repeating call waiting */
1063 int cidcwexpire; /*!< When to expire our muting for CID/CW */
1064 /*! \brief Analog caller ID waveform sample buffer */
1065 unsigned char *cidspill;
1066 /*! \brief Position in the cidspill buffer to send out next. */
1068 /*! \brief Length of the cidspill buffer containing samples. */
1070 /*! \brief Ring timeout timer?? */
1073 * \brief Ring timeout base.
1074 * \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
1078 * \brief Number of most significant digits/characters to strip from the dialed number.
1079 * \note Feature is deprecated. Use dialplan logic.
1080 * \note The characters are stripped before the PRI TON/NPI prefix
1081 * characters are processed.
1084 /*! \brief BOOLEAN. XXX Meaning what?? */
1086 /*! \brief Number of call waiting rings. */
1088 /*! \brief Echo cancel parameters. */
1090 struct dahdi_echocanparams head;
1091 struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS];
1094 * \brief Echo training time. 0 = disabled
1095 * \note Set from the "echotraining" value read in from chan_dahdi.conf
1098 /*! \brief Filled with 'w'. XXX Purpose?? */
1101 * \brief Number of times to see "busy" tone before hanging up.
1102 * \note Set from the "busycount" value read in from chan_dahdi.conf
1106 * \brief Length of "busy" tone on time.
1107 * \note Set from the "busypattern" value read in from chan_dahdi.conf
1109 int busy_tonelength;
1111 * \brief Length of "busy" tone off time.
1112 * \note Set from the "busypattern" value read in from chan_dahdi.conf
1114 int busy_quietlength;
1116 * \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
1117 * \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
1121 * \brief Number of milliseconds to wait for dialtone.
1122 * \note Set from the "waitfordialtone" value read in from chan_dahdi.conf
1124 int waitfordialtone;
1125 struct timeval waitingfordt; /*!< Time we started waiting for dialtone */
1126 struct timeval flashtime; /*!< Last flash-hook time */
1127 /*! \brief Opaque DSP configuration structure. */
1128 struct ast_dsp *dsp;
1129 /*! \brief DAHDI dial operation command struct for ioctl() call. */
1130 struct dahdi_dialoperation dop;
1131 int whichwink; /*!< SIG_FEATDMF_TA Which wink are we on? */
1132 /*! \brief Second part of SIG_FEATDMF_TA wink operation. */
1134 char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
1135 int amaflags; /*!< AMA Flags */
1136 struct tdd_state *tdd; /*!< TDD flag */
1137 /*! \brief Accumulated call forwarding number. */
1138 char call_forward[AST_MAX_EXTENSION];
1140 * \brief Voice mailbox location.
1141 * \note Set from the "mailbox" string read in from chan_dahdi.conf
1143 char mailbox[AST_MAX_EXTENSION];
1144 /*! \brief Opaque event subscription parameters for message waiting indication support. */
1145 struct ast_event_sub *mwi_event_sub;
1146 /*! \brief Delayed dialing for E911. Overlap digits for ISDN. */
1148 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1149 struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */
1150 unsigned int mwisend_fsk: 1; /*! Variable for enabling FSK MWI handling in chan_dahdi */
1151 unsigned int mwisend_rpas:1; /*! Variable for enabling Ring Pulse Alert before MWI FSK Spill */
1153 int distinctivering; /*!< Which distinctivering to use */
1154 int dtmfrelax; /*!< whether to run in relaxed DTMF mode */
1155 /*! \brief Holding place for event injected from outside normal operation. */
1158 * \brief Minimal time period (ms) between the answer polarity
1159 * switch and hangup polarity switch.
1161 int polarityonanswerdelay;
1162 /*! \brief Start delay time if polarityonanswerdelay is nonzero. */
1163 struct timeval polaritydelaytv;
1165 * \brief Send caller ID on FXS after this many rings. Set to 1 for US.
1166 * \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
1168 int sendcalleridafter;
1169 /*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
1171 /*! \brief DSP feature flags: DSP_FEATURE_xxx */
1173 #if defined(HAVE_SS7)
1174 /*! \brief SS7 control parameters */
1175 struct sig_ss7_linkset *ss7;
1176 #endif /* defined(HAVE_SS7) */
1178 struct dahdi_mfcr2 *mfcr2;
1179 openr2_chan_t *r2chan;
1180 openr2_calling_party_category_t mfcr2_recvd_category;
1181 openr2_calling_party_category_t mfcr2_category;
1182 int mfcr2_dnis_index;
1183 int mfcr2_ani_index;
1185 int mfcr2_answer_pending:1;
1186 int mfcr2_charge_calls:1;
1187 int mfcr2_allow_collect_calls:1;
1188 int mfcr2_forced_release:1;
1189 int mfcr2_dnis_matched:1;
1190 int mfcr2_call_accepted:1;
1191 int mfcr2_accept_on_offer:1;
1193 /*! \brief DTMF digit in progress. 0 when no digit in progress. */
1195 /*! \brief TRUE if confrence is muted. */
1198 struct ast_cc_config_params *cc_params;
1199 /* DAHDI channel names may differ greatly from the
1200 * string that was provided to an app such as Dial. We
1201 * need to save the original string passed to dahdi_request
1202 * for call completion purposes. This way, we can replicate
1203 * the original dialed string later.
1205 char dialstring[AST_CHANNEL_NAME];
1208 #define DATA_EXPORT_DAHDI_PVT(MEMBER) \
1209 MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE) \
1210 MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE) \
1211 MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE) \
1212 MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE) \
1213 MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE) \
1214 MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN) \
1215 MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN) \
1216 MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN) \
1217 MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN) \
1218 MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN) \
1219 MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN) \
1220 MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN) \
1221 MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN) \
1222 MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN) \
1223 MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN) \
1224 MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN) \
1225 MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN) \
1226 MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN) \
1227 MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN) \
1228 MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN) \
1229 MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN) \
1230 MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN) \
1231 MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN) \
1232 MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN) \
1233 MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN) \
1234 MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN) \
1235 MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN) \
1236 MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN) \
1237 MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN) \
1238 MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN) \
1239 MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN) \
1240 MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN) \
1241 MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN) \
1242 MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN) \
1243 MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN) \
1244 MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN) \
1245 MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN) \
1246 MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN) \
1247 MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN) \
1248 MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN) \
1249 MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN) \
1250 MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN) \
1251 MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN) \
1252 MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN) \
1253 MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN) \
1254 MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN) \
1255 MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN) \
1256 MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN) \
1257 MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN) \
1258 MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN) \
1259 MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN) \
1260 MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN) \
1261 MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN) \
1262 MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN) \
1263 MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN) \
1264 MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN) \
1265 MEMBER(dahdi_pvt, locallyblocked, AST_DATA_BOOLEAN) \
1266 MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_BOOLEAN) \
1267 MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN) \
1268 MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN) \
1269 MEMBER(dahdi_pvt, context, AST_DATA_STRING) \
1270 MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING) \
1271 MEMBER(dahdi_pvt, exten, AST_DATA_STRING) \
1272 MEMBER(dahdi_pvt, language, AST_DATA_STRING) \
1273 MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING) \
1274 MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING) \
1275 MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
1277 AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
1279 static struct dahdi_pvt *iflist = NULL; /*!< Main interface list start */
1280 static struct dahdi_pvt *ifend = NULL; /*!< Main interface list end */
1282 #if defined(HAVE_PRI)
1283 static struct dahdi_parms_pseudo {
1284 int buf_no; /*!< Number of buffers */
1285 int buf_policy; /*!< Buffer policy */
1286 int faxbuf_no; /*!< Number of Fax buffers */
1287 int faxbuf_policy; /*!< Fax buffer policy */
1288 } dahdi_pseudo_parms;
1289 #endif /* defined(HAVE_PRI) */
1291 /*! \brief Channel configuration from chan_dahdi.conf .
1292 * This struct is used for parsing the [channels] section of chan_dahdi.conf.
1293 * Generally there is a field here for every possible configuration item.
1295 * The state of fields is saved along the parsing and whenever a 'channel'
1296 * statement is reached, the current dahdi_chan_conf is used to configure the
1297 * channel (struct dahdi_pvt)
1299 * \see dahdi_chan_init for the default values.
1301 struct dahdi_chan_conf {
1302 struct dahdi_pvt chan;
1304 struct dahdi_pri pri;
1307 #if defined(HAVE_SS7)
1308 struct dahdi_ss7 ss7;
1309 #endif /* defined(HAVE_SS7) */
1312 struct dahdi_mfcr2_conf mfcr2;
1314 struct dahdi_params timing;
1315 int is_sig_auto; /*!< Use channel signalling from DAHDI? */
1316 /*! Continue configuration even if a channel is not there. */
1317 int ignore_failed_channels;
1320 * \brief The serial port to listen for SMDI data on
1321 * \note Set from the "smdiport" string read in from chan_dahdi.conf
1323 char smdi_port[SMDI_MAX_FILENAME_LEN];
1326 /*! returns a new dahdi_chan_conf with default values (by-value) */
1327 static struct dahdi_chan_conf dahdi_chan_conf_default(void)
1329 /* recall that if a field is not included here it is initialized
1330 * to 0 or equivalent
1332 struct dahdi_chan_conf conf = {
1335 .nsf = PRI_NSF_NONE,
1336 .switchtype = PRI_SWITCH_NI2,
1337 .dialplan = PRI_UNKNOWN + 1,
1338 .localdialplan = PRI_NATIONAL_ISDN + 1,
1339 .nodetype = PRI_CPE,
1340 .qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
1342 #if defined(HAVE_PRI_CCSS)
1343 .cc_ptmp_recall_mode = 1,/* specificRecall */
1344 .cc_qsig_signaling_link_req = 1,/* retain */
1345 .cc_qsig_signaling_link_rsp = 1,/* retain */
1346 #endif /* defined(HAVE_PRI_CCSS) */
1351 .internationalprefix = "",
1352 .nationalprefix = "",
1354 .privateprefix = "",
1355 .unknownprefix = "",
1356 .resetinterval = -1,
1359 #if defined(HAVE_SS7)
1361 .called_nai = SS7_NAI_NATIONAL,
1362 .calling_nai = SS7_NAI_NATIONAL,
1363 .internationalprefix = "",
1364 .nationalprefix = "",
1365 .subscriberprefix = "",
1368 #endif /* defined(HAVE_SS7) */
1371 .variant = OR2_VAR_ITU,
1372 .mfback_timeout = -1,
1373 .metering_pulse_timeout = -1,
1376 .get_ani_first = -1,
1377 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1378 .skip_category_request = -1,
1381 .allow_collect_calls = 0,
1383 .accept_on_offer = 1,
1384 .forced_release = 0,
1386 .immediate_accept = -1,
1389 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1390 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1394 .context = "default",
1398 .mohinterpret = "default",
1401 .transfertobusy = 1,
1403 .cid_signalling = CID_SIG_BELL,
1404 .cid_start = CID_START_RING,
1405 .dahditrcallerid = 0,
1414 .echocancel.head.tap_length = 1,
1422 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1425 .polarityonanswerdelay = 600,
1427 .sendcalleridafter = DEFAULT_CIDRINGS,
1429 .buf_policy = DAHDI_POLICY_IMMEDIATE,
1432 .cc_params = ast_cc_config_params_init(),
1445 .smdi_port = "/dev/ttyS0",
1452 static struct ast_channel *dahdi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
1453 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
1454 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
1455 static int dahdi_sendtext(struct ast_channel *c, const char *text);
1456 static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
1457 static int dahdi_hangup(struct ast_channel *ast);
1458 static int dahdi_answer(struct ast_channel *ast);
1459 static struct ast_frame *dahdi_read(struct ast_channel *ast);
1460 static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
1461 static struct ast_frame *dahdi_exception(struct ast_channel *ast);
1462 static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
1463 static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1464 static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1465 static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
1466 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
1467 static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
1468 static int dahdi_devicestate(void *data);
1469 static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
1471 static const struct ast_channel_tech dahdi_tech = {
1473 .description = tdesc,
1474 .capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
1475 .requester = dahdi_request,
1476 .send_digit_begin = dahdi_digit_begin,
1477 .send_digit_end = dahdi_digit_end,
1478 .send_text = dahdi_sendtext,
1480 .hangup = dahdi_hangup,
1481 .answer = dahdi_answer,
1483 .write = dahdi_write,
1484 .bridge = dahdi_bridge,
1485 .exception = dahdi_exception,
1486 .indicate = dahdi_indicate,
1487 .fixup = dahdi_fixup,
1488 .setoption = dahdi_setoption,
1489 .queryoption = dahdi_queryoption,
1490 .func_channel_read = dahdi_func_read,
1491 .func_channel_write = dahdi_func_write,
1492 .devicestate = dahdi_devicestate,
1493 .cc_callback = dahdi_cc_callback,
1496 #define GET_CHANNEL(p) ((p)->channel)
1498 #define SIG_PRI_LIB_HANDLE_CASES \
1505 * \brief Determine if sig_pri handles the signaling.
1508 * \param signaling Signaling to determine if is for sig_pri.
1510 * \return TRUE if the signaling is for sig_pri.
1512 static inline int dahdi_sig_pri_lib_handles(int signaling)
1516 switch (signaling) {
1517 case SIG_PRI_LIB_HANDLE_CASES:
1528 static enum analog_sigtype dahdisig_to_analogsig(int sig)
1532 return ANALOG_SIG_FXOLS;
1534 return ANALOG_SIG_FXOGS;
1536 return ANALOG_SIG_FXOKS;
1538 return ANALOG_SIG_FXSLS;
1540 return ANALOG_SIG_FXSGS;
1542 return ANALOG_SIG_FXSKS;
1544 return ANALOG_SIG_EMWINK;
1546 return ANALOG_SIG_EM;
1548 return ANALOG_SIG_EM_E1;
1550 return ANALOG_SIG_FEATD;
1552 return ANALOG_SIG_FEATDMF;
1556 return ANALOG_SIG_FGC_CAMA;
1557 case SIG_FGC_CAMAMF:
1558 return ANALOG_SIG_FGC_CAMAMF;
1560 return ANALOG_SIG_FEATB;
1562 return ANALOG_SIG_SFWINK;
1564 return ANALOG_SIG_SF;
1566 return ANALOG_SIG_SF_FEATD;
1567 case SIG_SF_FEATDMF:
1568 return ANALOG_SIG_SF_FEATDMF;
1569 case SIG_FEATDMF_TA:
1570 return ANALOG_SIG_FEATDMF_TA;
1572 return ANALOG_SIG_FEATB;
1579 static int analog_tone_to_dahditone(enum analog_tone tone)
1582 case ANALOG_TONE_RINGTONE:
1583 return DAHDI_TONE_RINGTONE;
1584 case ANALOG_TONE_STUTTER:
1585 return DAHDI_TONE_STUTTER;
1586 case ANALOG_TONE_CONGESTION:
1587 return DAHDI_TONE_CONGESTION;
1588 case ANALOG_TONE_DIALTONE:
1589 return DAHDI_TONE_DIALTONE;
1590 case ANALOG_TONE_DIALRECALL:
1591 return DAHDI_TONE_DIALRECALL;
1592 case ANALOG_TONE_INFO:
1593 return DAHDI_TONE_INFO;
1599 static int analogsub_to_dahdisub(enum analog_sub analogsub)
1603 switch (analogsub) {
1604 case ANALOG_SUB_REAL:
1607 case ANALOG_SUB_CALLWAIT:
1608 index = SUB_CALLWAIT;
1610 case ANALOG_SUB_THREEWAY:
1611 index = SUB_THREEWAY;
1614 ast_log(LOG_ERROR, "Unidentified sub!\n");
1621 static enum analog_event dahdievent_to_analogevent(int event);
1622 static int bump_gains(struct dahdi_pvt *p);
1623 static int dahdi_setlinear(int dfd, int linear);
1625 static int my_start_cid_detect(void *pvt, int cid_signalling)
1627 struct dahdi_pvt *p = pvt;
1628 int index = SUB_REAL;
1629 p->cs = callerid_new(cid_signalling);
1631 ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1635 dahdi_setlinear(p->subs[index].dfd, 0);
1640 static int my_stop_cid_detect(void *pvt)
1642 struct dahdi_pvt *p = pvt;
1643 int index = SUB_REAL;
1645 callerid_free(p->cs);
1646 dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1650 static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
1652 struct dahdi_pvt *p = pvt;
1653 struct analog_pvt *analog_p = p->sig_pvt;
1654 struct pollfd poller;
1656 int index = SUB_REAL;
1658 unsigned char buf[256];
1661 poller.fd = p->subs[SUB_REAL].dfd;
1662 poller.events = POLLPRI | POLLIN;
1665 res = poll(&poller, 1, timeout);
1667 if (poller.revents & POLLPRI) {
1668 *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
1672 if (poller.revents & POLLIN) {
1674 /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1675 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1676 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1677 * a failure and die, and returning 2 means no event was received. */
1678 res = read(p->subs[index].dfd, buf, sizeof(buf));
1680 if (errno != ELAST) {
1681 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1682 callerid_free(p->cs);
1687 if (analog_p->ringt > 0) {
1688 if (!(--analog_p->ringt)) {
1689 /* only return if we timeout from a ring event */
1694 if (p->cid_signalling == CID_SIG_V23_JP) {
1695 res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
1697 res = callerid_feed(p->cs, buf, res, AST_LAW(p));
1701 * The previous diagnostic message output likely
1702 * explains why it failed.
1704 ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1709 callerid_get(p->cs, &name, &num, &flags);
1711 ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1713 ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1715 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1720 *ev = ANALOG_EVENT_NONE;
1724 static const char *event2str(int event);
1725 static int restore_gains(struct dahdi_pvt *p);
1727 static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
1729 unsigned char buf[256];
1731 int curRingData[RING_PATTERNS];
1737 int checkaftercid = 0;
1739 struct dahdi_pvt *p = pvt;
1740 struct analog_pvt *analog_p = p->sig_pvt;
1742 if (ringdata == NULL) {
1743 ringdata = curRingData;
1748 /* We must have a ring by now, so, if configured, lets try to listen for
1749 * distinctive ringing */
1750 if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1751 /* Clear the current ring data array so we don't have old data in it. */
1752 for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1753 ringdata[receivedRingT] = 0;
1755 if (checkaftercid && distinctiveringaftercid)
1756 ast_verb(3, "Detecting post-CID distinctive ring\n");
1757 /* Check to see if context is what it should be, if not set to be. */
1758 else if (strcmp(p->context,p->defcontext) != 0) {
1759 ast_copy_string(p->context, p->defcontext, sizeof(p->context));
1760 ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
1764 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1765 if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
1766 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1770 if (i & DAHDI_IOMUX_SIGEVENT) {
1771 res = dahdi_get_event(p->subs[idx].dfd);
1772 if (res == DAHDI_EVENT_NOALARM) {
1774 analog_p->inalarm = 0;
1776 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
1778 /* Let us detect distinctive ring */
1780 ringdata[receivedRingT] = analog_p->ringt;
1782 if (analog_p->ringt < analog_p->ringt_base/2)
1784 /* Increment the ringT counter so we can match it against
1785 values in chan_dahdi.conf for distinctive ring */
1786 if (++receivedRingT == RING_PATTERNS)
1788 } else if (i & DAHDI_IOMUX_READ) {
1789 res = read(p->subs[idx].dfd, buf, sizeof(buf));
1791 if (errno != ELAST) {
1792 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1798 if (analog_p->ringt > 0) {
1799 if (!(--analog_p->ringt)) {
1807 if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
1808 /* this only shows up if you have n of the dring patterns filled in */
1809 ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
1810 for (counter = 0; counter < 3; counter++) {
1811 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1813 /* this only shows up if you have n of the dring patterns filled in */
1814 ast_verb(3, "Checking %d,%d,%d\n",
1815 p->drings.ringnum[counter].ring[0],
1816 p->drings.ringnum[counter].ring[1],
1817 p->drings.ringnum[counter].ring[2]);
1818 for (counter1 = 0; counter1 < 3; counter1++) {
1819 ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
1820 if (p->drings.ringnum[counter].ring[counter1] == -1) {
1821 ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1822 ringdata[counter1]);
1824 } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
1825 ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
1826 ast_verb(3, "Ring pattern matched in range: %d to %d\n",
1827 (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
1828 (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
1833 if (distMatches == 3) {
1834 /* The ring matches, set the context to whatever is for distinctive ring.. */
1835 ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
1836 ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
1837 ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
1842 /* Restore linear mode (if appropriate) for Caller*ID processing */
1843 dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
1849 static int send_callerid(struct dahdi_pvt *p);
1851 static int my_stop_callwait(void *pvt)
1853 struct dahdi_pvt *p = pvt;
1854 p->callwaitingrepeat = 0;
1860 static int save_conference(struct dahdi_pvt *p);
1862 static int my_callwait(void *pvt)
1864 struct dahdi_pvt *p = pvt;
1865 p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
1867 ast_log(LOG_WARNING, "Spill already exists?!?\n");
1868 ast_free(p->cidspill);
1870 if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1874 memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1875 if (!p->callwaitrings && p->callwaitingcallerid) {
1876 ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
1878 p->cidlen = 2400 + 680 + READ_SIZE * 4;
1880 ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
1882 p->cidlen = 2400 + READ_SIZE * 4;
1890 static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
1892 struct dahdi_pvt *p = pvt;
1894 ast_debug(2, "Starting cid spill\n");
1897 ast_log(LOG_WARNING, "cidspill already exists??\n");
1898 ast_free(p->cidspill);
1901 if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1903 p->cidlen = ast_callerid_generate(p->cidspill,
1904 caller->id.name.str,
1905 caller->id.number.str,
1910 p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
1911 caller->id.name.str,
1912 caller->id.number.str,
1914 p->cidlen += READ_SIZE * 4;
1922 static int my_dsp_reset_and_flush_digits(void *pvt)
1924 struct dahdi_pvt *p = pvt;
1926 ast_dsp_digitreset(p->dsp);
1931 static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
1933 struct dahdi_pvt *p = pvt;
1935 if (p->channel == CHAN_PSEUDO)
1936 ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
1938 if (mode == ANALOG_DIGITMODE_DTMF) {
1939 /* If we do hardware dtmf, no need for a DSP */
1940 if (p->hardwaredtmf) {
1942 ast_dsp_free(p->dsp);
1949 p->dsp = ast_dsp_new();
1951 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1956 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
1957 } else if (mode == ANALOG_DIGITMODE_MF) {
1959 p->dsp = ast_dsp_new();
1961 ast_log(LOG_ERROR, "Unable to allocate DSP\n");
1965 ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
1970 static int dahdi_wink(struct dahdi_pvt *p, int index);
1972 static int my_wink(void *pvt, enum analog_sub sub)
1974 struct dahdi_pvt *p = pvt;
1975 int index = analogsub_to_dahdisub(sub);
1976 if (index != SUB_REAL) {
1977 ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1979 return dahdi_wink(p, index);
1982 static void wakeup_sub(struct dahdi_pvt *p, int a);
1984 static int reset_conf(struct dahdi_pvt *p);
1986 static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
1988 static void my_handle_dtmfup(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
1990 struct ast_frame *f = *dest;
1991 struct dahdi_pvt *p = pvt;
1992 int idx = analogsub_to_dahdisub(analog_index);
1994 ast_debug(1, "DTMF digit: %c on %s\n", f->subclass.integer, ast->name);
1996 if (f->subclass.integer == 'f') {
1997 /* Fax tone -- Handle and return NULL */
1998 if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
1999 /* If faxbuffers are configured, use them for the fax transmission */
2000 if (p->usefaxbuffers && !p->bufferoverrideinuse) {
2001 struct dahdi_bufferinfo bi = {
2002 .txbufpolicy = p->faxbuf_policy,
2003 .bufsize = p->bufsize,
2004 .numbufs = p->faxbuf_no
2008 if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
2009 ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno));
2011 p->bufferoverrideinuse = 1;
2015 if (strcmp(ast->exten, "fax")) {
2016 const char *target_context = S_OR(ast->macrocontext, ast->context);
2018 /* We need to unlock 'ast' here because ast_exists_extension has the
2019 * potential to start autoservice on the channel. Such action is prone
2022 ast_mutex_unlock(&p->lock);
2023 ast_channel_unlock(ast);
2024 if (ast_exists_extension(ast, target_context, "fax", 1,
2025 S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
2026 ast_channel_lock(ast);
2027 ast_mutex_lock(&p->lock);
2028 ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
2029 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
2030 pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
2031 if (ast_async_goto(ast, target_context, "fax", 1))
2032 ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
2034 ast_channel_lock(ast);
2035 ast_mutex_lock(&p->lock);
2036 ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
2039 ast_debug(1, "Already in a fax extension, not redirecting\n");
2042 ast_debug(1, "Fax already handled\n");
2044 dahdi_confmute(p, 0);
2045 p->subs[idx].f.frametype = AST_FRAME_NULL;
2046 p->subs[idx].f.subclass.integer = 0;
2047 *dest = &p->subs[idx].f;
2051 static void my_lock_private(void *pvt)
2053 struct dahdi_pvt *p = pvt;
2054 ast_mutex_lock(&p->lock);
2057 static void my_unlock_private(void *pvt)
2059 struct dahdi_pvt *p = pvt;
2060 ast_mutex_unlock(&p->lock);
2063 /* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
2064 * returns the last value of the linear setting
2066 static int my_set_linear_mode(void *pvt, int idx, int linear_mode)
2068 struct dahdi_pvt *p = pvt;
2071 if (0 > linear_mode || !dahdi_setlinear(p->subs[idx].dfd, linear_mode)) {
2074 oldval = p->subs[idx].linear;
2075 p->subs[idx].linear = linear_mode;
2079 static int get_alarms(struct dahdi_pvt *p);
2080 static void handle_alarms(struct dahdi_pvt *p, int alms);
2081 static void my_get_and_handle_alarms(void *pvt)
2084 struct dahdi_pvt *p = pvt;
2086 res = get_alarms(p);
2087 handle_alarms(p, res);
2090 static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
2092 struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt;
2099 static int my_get_sub_fd(void *pvt, enum analog_sub sub)
2101 struct dahdi_pvt *p = pvt;
2102 int dahdi_sub = analogsub_to_dahdisub(sub);
2103 return p->subs[dahdi_sub].dfd;
2106 static void my_set_cadence(void *pvt, int *cidrings, struct ast_channel *ast)
2108 struct dahdi_pvt *p = pvt;
2110 /* Choose proper cadence */
2111 if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
2112 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
2113 ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
2114 *cidrings = cidrings[p->distinctivering - 1];
2116 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
2117 ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
2118 *cidrings = p->sendcalleridafter;
2122 static void my_set_alarm(void *pvt, int in_alarm)
2124 struct dahdi_pvt *p = pvt;
2126 p->inalarm = in_alarm;
2129 static void my_set_dialing(void *pvt, int is_dialing)
2131 struct dahdi_pvt *p = pvt;
2133 p->dialing = is_dialing;
2136 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2137 static void my_set_digital(void *pvt, int is_digital)
2139 struct dahdi_pvt *p = pvt;
2141 p->digital = is_digital;
2143 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2145 #if defined(HAVE_SS7)
2146 static void my_set_inservice(void *pvt, int is_inservice)
2148 struct dahdi_pvt *p = pvt;
2150 p->inservice = is_inservice;
2152 #endif /* defined(HAVE_SS7) */
2154 #if defined(HAVE_SS7)
2155 static void my_set_locallyblocked(void *pvt, int is_blocked)
2157 struct dahdi_pvt *p = pvt;
2159 p->locallyblocked = is_blocked;
2161 #endif /* defined(HAVE_SS7) */
2163 #if defined(HAVE_SS7)
2164 static void my_set_remotelyblocked(void *pvt, int is_blocked)
2166 struct dahdi_pvt *p = pvt;
2168 p->remotelyblocked = is_blocked;
2170 #endif /* defined(HAVE_SS7) */
2172 static void my_set_ringtimeout(void *pvt, int ringt)
2174 struct dahdi_pvt *p = pvt;
2178 static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
2180 struct dahdi_pvt *p = pvt;
2182 if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
2183 ast_log(LOG_DEBUG, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
2184 gettimeofday(&p->waitingfordt, NULL);
2185 ast_setstate(ast, AST_STATE_OFFHOOK);
2189 static int my_check_waitingfordt(void *pvt)
2191 struct dahdi_pvt *p = pvt;
2193 if (p->waitingfordt.tv_usec) {
2200 static void my_set_confirmanswer(void *pvt, int flag)
2202 struct dahdi_pvt *p = pvt;
2203 p->confirmanswer = flag;
2206 static int my_check_confirmanswer(void *pvt)
2208 struct dahdi_pvt *p = pvt;
2209 if (p->confirmanswer) {
2216 static void my_cancel_cidspill(void *pvt)
2218 struct dahdi_pvt *p = pvt;
2220 ast_free(p->cidspill);
2225 static int my_confmute(void *pvt, int mute)
2227 struct dahdi_pvt *p = pvt;
2228 return dahdi_confmute(p, mute);
2231 static void my_set_pulsedial(void *pvt, int flag)
2233 struct dahdi_pvt *p = pvt;
2234 p->pulsedial = flag;
2237 static const char *my_get_orig_dialstring(void *pvt)
2239 struct dahdi_pvt *p = pvt;
2241 return p->dialstring;
2244 static void my_increase_ss_count(void)
2246 ast_mutex_lock(&ss_thread_lock);
2248 ast_mutex_unlock(&ss_thread_lock);
2251 static void my_decrease_ss_count(void)
2253 ast_mutex_lock(&ss_thread_lock);
2255 ast_cond_signal(&ss_thread_complete);
2256 ast_mutex_unlock(&ss_thread_lock);
2259 static void my_all_subchannels_hungup(void *pvt)
2261 struct dahdi_pvt *p = pvt;
2268 ast_dsp_free(p->dsp);
2272 p->law = p->law_default;
2273 law = p->law_default;
2274 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2276 ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2278 dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2284 /* Cleanup owners here */
2285 for (i = 0; i < 3; i++) {
2286 p->subs[i].owner = NULL;
2292 if (num_restart_pending == 0) {
2297 static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
2299 static int my_conf_del(void *pvt, enum analog_sub sub)
2301 struct dahdi_pvt *p = pvt;
2302 int x = analogsub_to_dahdisub(sub);
2304 return conf_del(p, &p->subs[x], x);
2307 static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
2309 static int my_conf_add(void *pvt, enum analog_sub sub)
2311 struct dahdi_pvt *p = pvt;
2312 int x = analogsub_to_dahdisub(sub);
2314 return conf_add(p, &p->subs[x], x, 0);
2317 static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
2319 static int my_complete_conference_update(void *pvt, int needconference)
2321 struct dahdi_pvt *p = pvt;
2322 int needconf = needconference;
2325 struct dahdi_pvt *slave = NULL;
2327 useslavenative = isslavenative(p, &slave);
2329 /* If we have a slave, add him to our conference now. or DAX
2330 if this is slave native */
2331 for (x = 0; x < MAX_SLAVES; x++) {
2334 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2336 conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2341 /* If we're supposed to be in there, do so now */
2342 if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2344 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2346 conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2350 /* If we have a master, add ourselves to his conference */
2352 if (isslavenative(p->master, NULL)) {
2353 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
2355 conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2359 /* Nobody is left (or should be left) in our conference.
2367 static int check_for_conference(struct dahdi_pvt *p);
2369 static int my_check_for_conference(void *pvt)
2371 struct dahdi_pvt *p = pvt;
2372 return check_for_conference(p);
2375 static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a, enum analog_sub b, struct ast_channel *ast_b)
2377 struct dahdi_pvt *p = pvt;
2381 da = analogsub_to_dahdisub(a);
2382 db = analogsub_to_dahdisub(b);
2384 tchan = p->subs[da].chan;
2386 p->subs[da].chan = p->subs[db].chan;
2388 p->subs[db].chan = tchan;
2391 ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2393 ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2395 p->subs[da].owner = ast_a;
2396 p->subs[db].owner = ast_b;
2404 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid);
2406 static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
2408 struct dahdi_pvt *p = pvt;
2409 int dsub = analogsub_to_dahdisub(sub);
2411 return dahdi_new(p, state, startpbx, dsub, 0, requestor ? requestor->linkedid : "");
2414 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2415 static int dahdi_setlaw(int dfd, int law)
2418 res = ioctl(dfd, DAHDI_SETLAW, &law);
2423 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2425 #if defined(HAVE_PRI)
2426 static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor)
2428 struct dahdi_pvt *p = pvt;
2433 case SIG_PRI_LIB_HANDLE_CASES:
2434 if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
2435 /* PRI nobch pseudo channel. Does not handle ioctl(DAHDI_AUDIOMODE) */
2440 /* Set to audio mode at this point */
2442 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
2443 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
2444 p->channel, audio, strerror(errno));
2449 if (law != SIG_PRI_DEFLAW) {
2450 dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
2453 ast_copy_string(p->exten, exten, sizeof(p->exten));
2456 case SIG_PRI_DEFLAW:
2460 newlaw = DAHDI_LAW_ALAW;
2463 newlaw = DAHDI_LAW_MULAW;
2466 return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? requestor->linkedid : "");
2468 #endif /* defined(HAVE_PRI) */
2470 static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
2472 #if defined(HAVE_PRI)
2475 * \brief Open the PRI channel media path.
2478 * \param p Channel private control structure.
2482 static void my_pri_open_media(void *p)
2484 struct dahdi_pvt *pvt = p;
2489 dfd = pvt->subs[SUB_REAL].dfd;
2491 /* Open the media path. */
2493 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2495 ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
2496 pvt->channel, strerror(errno));
2499 /* Set correct companding law for this call. */
2500 res = dahdi_setlaw(dfd, pvt->law);
2502 ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
2505 /* Set correct gain for this call. */
2507 res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
2509 res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
2513 ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
2516 #endif /* defined(HAVE_PRI) */
2518 static int unalloc_sub(struct dahdi_pvt *p, int x);
2520 static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
2522 struct dahdi_pvt *p = pvt;
2524 return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2527 static int alloc_sub(struct dahdi_pvt *p, int x);
2529 static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
2531 struct dahdi_pvt *p = pvt;
2533 return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2536 static int has_voicemail(struct dahdi_pvt *p);
2538 static int my_has_voicemail(void *pvt)
2540 struct dahdi_pvt *p = pvt;
2542 return has_voicemail(p);
2545 static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
2547 struct dahdi_pvt *p = pvt;
2550 index = analogsub_to_dahdisub(sub);
2552 return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2555 static enum analog_event dahdievent_to_analogevent(int event)
2557 enum analog_event res;
2560 case DAHDI_EVENT_ONHOOK:
2561 res = ANALOG_EVENT_ONHOOK;
2563 case DAHDI_EVENT_RINGOFFHOOK:
2564 res = ANALOG_EVENT_RINGOFFHOOK;
2566 case DAHDI_EVENT_WINKFLASH:
2567 res = ANALOG_EVENT_WINKFLASH;
2569 case DAHDI_EVENT_ALARM:
2570 res = ANALOG_EVENT_ALARM;
2572 case DAHDI_EVENT_NOALARM:
2573 res = ANALOG_EVENT_NOALARM;
2575 case DAHDI_EVENT_DIALCOMPLETE:
2576 res = ANALOG_EVENT_DIALCOMPLETE;
2578 case DAHDI_EVENT_RINGERON:
2579 res = ANALOG_EVENT_RINGERON;
2581 case DAHDI_EVENT_RINGEROFF:
2582 res = ANALOG_EVENT_RINGEROFF;
2584 case DAHDI_EVENT_HOOKCOMPLETE:
2585 res = ANALOG_EVENT_HOOKCOMPLETE;
2587 case DAHDI_EVENT_PULSE_START:
2588 res = ANALOG_EVENT_PULSE_START;
2590 case DAHDI_EVENT_POLARITY:
2591 res = ANALOG_EVENT_POLARITY;
2593 case DAHDI_EVENT_RINGBEGIN:
2594 res = ANALOG_EVENT_RINGBEGIN;
2596 case DAHDI_EVENT_EC_DISABLED:
2597 res = ANALOG_EVENT_EC_DISABLED;
2599 case DAHDI_EVENT_REMOVED:
2600 res = ANALOG_EVENT_REMOVED;
2602 case DAHDI_EVENT_NEONMWI_ACTIVE:
2603 res = ANALOG_EVENT_NEONMWI_ACTIVE;
2605 case DAHDI_EVENT_NEONMWI_INACTIVE:
2606 res = ANALOG_EVENT_NEONMWI_INACTIVE;
2608 #ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2609 case DAHDI_EVENT_TX_CED_DETECTED:
2610 res = ANALOG_EVENT_TX_CED_DETECTED;
2612 case DAHDI_EVENT_RX_CED_DETECTED:
2613 res = ANALOG_EVENT_RX_CED_DETECTED;
2615 case DAHDI_EVENT_EC_NLP_DISABLED:
2616 res = ANALOG_EVENT_EC_NLP_DISABLED;
2618 case DAHDI_EVENT_EC_NLP_ENABLED:
2619 res = ANALOG_EVENT_EC_NLP_ENABLED;
2622 case DAHDI_EVENT_PULSEDIGIT:
2623 res = ANALOG_EVENT_PULSEDIGIT;
2625 case DAHDI_EVENT_DTMFDOWN:
2626 res = ANALOG_EVENT_DTMFDOWN;
2628 case DAHDI_EVENT_DTMFUP:
2629 res = ANALOG_EVENT_DTMFUP;
2632 switch(event & 0xFFFF0000) {
2633 case DAHDI_EVENT_PULSEDIGIT:
2634 case DAHDI_EVENT_DTMFDOWN:
2635 case DAHDI_EVENT_DTMFUP:
2636 /* The event includes a digit number in the low word.
2637 * Converting it to a 'enum analog_event' would remove
2638 * that information. Thus it is returned as-is.
2643 res = ANALOG_EVENT_ERROR;
2650 static inline int dahdi_wait_event(int fd);
2652 static int my_wait_event(void *pvt)
2654 struct dahdi_pvt *p = pvt;
2656 return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2659 static int my_get_event(void *pvt)
2661 struct dahdi_pvt *p = pvt;
2664 if (p->fake_event) {
2665 res = p->fake_event;
2668 res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2670 return dahdievent_to_analogevent(res);
2673 static int my_is_off_hook(void *pvt)
2675 struct dahdi_pvt *p = pvt;
2677 struct dahdi_params par;
2679 memset(&par, 0, sizeof(par));
2681 if (p->subs[SUB_REAL].dfd > -1)
2682 res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2684 /* Assume not off hook on CVRS */
2686 par.rxisoffhook = 0;
2689 ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2692 if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2693 /* When "onhook" that means no battery on the line, and thus
2694 it is out of service..., if it's on a TDM card... If it's a channel
2695 bank, there is no telling... */
2696 return (par.rxbits > -1) || par.rxisoffhook;
2699 return par.rxisoffhook;
2702 static void dahdi_enable_ec(struct dahdi_pvt *p);
2703 static void dahdi_disable_ec(struct dahdi_pvt *p);
2705 static int my_set_echocanceller(void *pvt, int enable)
2707 struct dahdi_pvt *p = pvt;
2712 dahdi_disable_ec(p);
2717 static int dahdi_ring_phone(struct dahdi_pvt *p);
2719 static int my_ring(void *pvt)
2721 struct dahdi_pvt *p = pvt;
2723 return dahdi_ring_phone(p);
2726 static int my_flash(void *pvt)
2728 struct dahdi_pvt *p = pvt;
2729 int func = DAHDI_FLASH;
2730 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2733 static inline int dahdi_set_hook(int fd, int hs);
2735 static int my_off_hook(void *pvt)
2737 struct dahdi_pvt *p = pvt;
2738 return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2741 static void my_set_needringing(void *pvt, int value)
2743 struct dahdi_pvt *p = pvt;
2744 p->subs[SUB_REAL].needringing = value;
2747 static int my_start(void *pvt)
2749 struct dahdi_pvt *p = pvt;
2750 int x = DAHDI_START;
2752 return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2755 static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
2757 int index = analogsub_to_dahdisub(sub);
2759 struct dahdi_pvt *p = pvt;
2760 struct dahdi_dialoperation ddop;
2762 if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2763 ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2767 if (sub != ANALOG_SUB_REAL)
2768 printf("Trying to dial digits on sub %d\n", sub);
2770 ddop.op = DAHDI_DIAL_OP_REPLACE;
2771 strncpy(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr));
2773 printf("Dialing %s on %d\n", ddop.dialstr, p->channel);
2775 res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop);
2778 ast_log(LOG_DEBUG, "DAHDI_DIAL ioctl failed on %s: %s\n", p->owner->name, strerror(errno));
2783 static void dahdi_train_ec(struct dahdi_pvt *p);
2785 static int my_train_echocanceller(void *pvt)
2787 struct dahdi_pvt *p = pvt;
2794 static int my_is_dialing(void *pvt, enum analog_sub sub)
2796 struct dahdi_pvt *p = pvt;
2800 index = analogsub_to_dahdisub(sub);
2802 if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
2803 ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed!\n");
2810 static int my_on_hook(void *pvt)
2812 struct dahdi_pvt *p = pvt;
2813 return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
2816 #if defined(HAVE_PRI)
2817 static void my_pri_fixup_chans(void *chan_old, void *chan_new)
2819 struct dahdi_pvt *old_chan = chan_old;
2820 struct dahdi_pvt *new_chan = chan_new;
2822 new_chan->owner = old_chan->owner;
2823 old_chan->owner = NULL;
2824 if (new_chan->owner) {
2825 new_chan->owner->tech_pvt = new_chan;
2826 new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd;
2827 new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
2828 old_chan->subs[SUB_REAL].owner = NULL;
2830 /* Copy any DSP that may be present */
2831 new_chan->dsp = old_chan->dsp;
2832 new_chan->dsp_features = old_chan->dsp_features;
2833 old_chan->dsp = NULL;
2834 old_chan->dsp_features = 0;
2836 /* Transfer flags from the old channel. */
2837 new_chan->dialing = old_chan->dialing;
2838 new_chan->digital = old_chan->digital;
2839 new_chan->outgoing = old_chan->outgoing;
2840 old_chan->dialing = 0;
2841 old_chan->digital = 0;
2842 old_chan->outgoing = 0;
2844 /* More stuff to transfer to the new channel. */
2845 new_chan->law = old_chan->law;
2847 #endif /* defined(HAVE_PRI) */
2849 #if defined(HAVE_PRI)
2850 static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
2853 case SIG_PRI_TONE_RINGTONE:
2854 return DAHDI_TONE_RINGTONE;
2855 case SIG_PRI_TONE_STUTTER:
2856 return DAHDI_TONE_STUTTER;
2857 case SIG_PRI_TONE_CONGESTION:
2858 return DAHDI_TONE_CONGESTION;
2859 case SIG_PRI_TONE_DIALTONE:
2860 return DAHDI_TONE_DIALTONE;
2861 case SIG_PRI_TONE_DIALRECALL:
2862 return DAHDI_TONE_DIALRECALL;
2863 case SIG_PRI_TONE_INFO:
2864 return DAHDI_TONE_INFO;
2865 case SIG_PRI_TONE_BUSY:
2866 return DAHDI_TONE_BUSY;
2871 #endif /* defined(HAVE_PRI) */
2873 #if defined(HAVE_PRI)
2874 static void my_handle_dchan_exception(struct sig_pri_pri *pri, int index)
2878 res = ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
2880 ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span);
2882 /* Keep track of alarm state */
2884 case DAHDI_EVENT_ALARM:
2885 pri_event_alarm(pri, index, 0);
2887 case DAHDI_EVENT_NOALARM:
2888 pri_event_noalarm(pri, index, 0);
2894 #endif /* defined(HAVE_PRI) */
2896 #if defined(HAVE_PRI)
2897 static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
2899 struct dahdi_pvt *p = pvt;
2901 return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
2903 #endif /* defined(HAVE_PRI) */
2905 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2908 * \brief Set the caller id information.
2911 * \param pvt DAHDI private structure
2912 * \param caller Caller-id information to set.
2916 static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
2918 struct dahdi_pvt *p = pvt;
2920 ast_copy_string(p->cid_num,
2921 S_COR(caller->id.number.valid, caller->id.number.str, ""),
2922 sizeof(p->cid_num));
2923 ast_copy_string(p->cid_name,
2924 S_COR(caller->id.name.valid, caller->id.name.str, ""),
2925 sizeof(p->cid_name));
2926 ast_copy_string(p->cid_subaddr,
2927 S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
2928 sizeof(p->cid_subaddr));
2929 p->cid_ton = caller->id.number.plan;
2930 p->callingpres = ast_party_id_presentation(&caller->id);
2931 if (caller->id.tag) {
2932 ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
2934 ast_copy_string(p->cid_ani,
2935 S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
2936 sizeof(p->cid_ani));
2937 p->cid_ani2 = caller->ani2;
2939 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2941 #if defined(HAVE_PRI) || defined(HAVE_SS7)
2944 * \brief Set the Dialed Number Identifier.
2947 * \param pvt DAHDI private structure
2948 * \param dnid Dialed Number Identifier string.
2952 static void my_set_dnid(void *pvt, const char *dnid)
2954 struct dahdi_pvt *p = pvt;
2956 ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
2958 #endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
2960 #if defined(HAVE_PRI)
2963 * \brief Set the Redirecting Directory Number Information Service (RDNIS).
2966 * \param pvt DAHDI private structure
2967 * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
2971 static void my_set_rdnis(void *pvt, const char *rdnis)
2973 struct dahdi_pvt *p = pvt;
2975 ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
2977 #endif /* defined(HAVE_PRI) */
2979 #if defined(HAVE_PRI)
2982 * \brief Make a dialstring for native ISDN CC to recall properly.
2985 * \param priv Channel private control structure.
2986 * \param buf Where to put the modified dialstring.
2987 * \param buf_size Size of modified dialstring buffer.
2990 * original dialstring:
2991 * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2993 * The modified dialstring will have prefixed the channel-group section
2994 * with the ISDN channel restriction.
2997 * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
2999 * The routine will check to see if the ISDN channel restriction is already
3000 * in the original dialstring.
3004 static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
3007 struct dahdi_pvt *pvt;
3008 AST_DECLARE_APP_ARGS(args,
3009 AST_APP_ARG(tech); /* channel technology token */
3010 AST_APP_ARG(group); /* channel/group token */
3011 //AST_APP_ARG(ext); /* extension token */
3012 //AST_APP_ARG(opts); /* options token */
3013 //AST_APP_ARG(other); /* Any remining unused arguments */
3017 dial = ast_strdupa(pvt->dialstring);
3018 AST_NONSTANDARD_APP_ARGS(args, dial, '/');
3020 ast_copy_string(buf, pvt->dialstring, buf_size);
3024 /* Append the ISDN span channel restriction to the dialstring. */
3025 snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
3028 if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
3029 /* The ISDN span channel restriction is not needed or already
3030 * in the dialstring. */
3031 ast_copy_string(buf, pvt->dialstring, buf_size);
3034 /* Insert the ISDN span channel restriction into the dialstring. */
3035 snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
3037 #endif /* defined(HAVE_PRI) */
3039 #if defined(HAVE_PRI)
3042 * \brief Reevaluate the PRI span device state.
3045 * \param pri Asterisk D channel control structure.
3049 * \note Assumes the pri->lock is already obtained.
3051 static void dahdi_pri_update_span_devstate(struct sig_pri_pri *pri)
3054 unsigned num_b_chans; /* Number of B channels provisioned on the span. */
3055 unsigned in_use; /* Number of B channels in use on the span. */
3056 unsigned in_alarm; /* TRUE if the span is in alarm condition. */
3057 enum ast_device_state new_state;
3059 /* Count the number of B channels and the number of B channels in use. */
3063 for (idx = pri->numchans; idx--;) {
3064 if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
3065 /* This is a B channel interface. */
3067 if (pri->pvts[idx]->owner
3068 #if defined(HAVE_PRI_SERVICE_MESSAGES)
3069 /* Out-of-service B channels are "in-use". */
3070 && pri->pvts[idx]->service_status
3071 #endif /* defined(HAVE_PRI_SERVICE_MESSAGES) */
3075 if (!pri->pvts[idx]->inalarm) {
3076 /* There is a channel that is not in alarm. */
3082 /* Update the span congestion device state and report any change. */
3084 new_state = AST_DEVICE_UNAVAILABLE;
3086 new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
3088 if (pri->congestion_devstate != new_state) {
3089 pri->congestion_devstate = new_state;
3090 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
3092 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3093 /* Update the span threshold device state and report any change. */
3095 new_state = AST_DEVICE_UNAVAILABLE;
3096 } else if (!in_use) {
3097 new_state = AST_DEVICE_NOT_INUSE;
3098 } else if (!pri->user_busy_threshold) {
3099 new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
3101 new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
3104 if (pri->threshold_devstate != new_state) {
3105 pri->threshold_devstate = new_state;
3106 ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
3108 #endif /* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
3110 #endif /* defined(HAVE_PRI) */
3112 #if defined(HAVE_PRI)
3115 * \brief Reference this module.
3120 static void my_module_ref(void)
3122 ast_module_ref(ast_module_info->self);
3124 #endif /* defined(HAVE_PRI) */
3126 #if defined(HAVE_PRI)
3129 * \brief Unreference this module.
3134 static void my_module_unref(void)
3136 ast_module_unref(ast_module_info->self);
3138 #endif /* defined(HAVE_PRI) */
3140 #if defined(HAVE_PRI)
3141 #if defined(HAVE_PRI_CALL_WAITING)
3142 static void my_pri_init_config(void *priv, struct sig_pri_pri *pri);
3143 #endif /* defined(HAVE_PRI_CALL_WAITING) */
3144 static int dahdi_new_pri_nobch_channel(struct sig_pri_pri *pri);
3146 static struct sig_pri_callback dahdi_pri_callbacks =
3148 .handle_dchan_exception = my_handle_dchan_exception,
3149 .play_tone = my_pri_play_tone,
3150 .set_echocanceller = my_set_echocanceller,
3151 .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3152 .lock_private = my_lock_private,
3153 .unlock_private = my_unlock_private,
3154 .new_ast_channel = my_new_pri_ast_channel,
3155 .fixup_chans = my_pri_fixup_chans,
3156 .set_alarm = my_set_alarm,
3157 .set_dialing = my_set_dialing,
3158 .set_digital = my_set_digital,
3159 .set_callerid = my_set_callerid,
3160 .set_dnid = my_set_dnid,
3161 .set_rdnis = my_set_rdnis,
3162 .new_nobch_intf = dahdi_new_pri_nobch_channel,
3163 #if defined(HAVE_PRI_CALL_WAITING)
3164 .init_config = my_pri_init_config,
3165 #endif /* defined(HAVE_PRI_CALL_WAITING) */
3166 .get_orig_dialstring = my_get_orig_dialstring,
3167 .make_cc_dialstring = my_pri_make_cc_dialstring,
3168 .update_span_devstate = dahdi_pri_update_span_devstate,
3169 .module_ref = my_module_ref,
3170 .module_unref = my_module_unref,
3171 .open_media = my_pri_open_media,
3173 #endif /* defined(HAVE_PRI) */
3175 #if defined(HAVE_SS7)
3178 * \brief Handle the SS7 link exception.
3181 * \param linkset Controlling linkset for the channel.
3182 * \param which Link index of the signaling channel.
3186 static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
3190 if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
3191 ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
3192 linkset->span, which);
3196 case DAHDI_EVENT_NONE:
3198 case DAHDI_EVENT_ALARM:
3199 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3200 event2str(event), event, linkset->span, which);
3201 sig_ss7_link_alarm(linkset, which);
3203 case DAHDI_EVENT_NOALARM:
3204 ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3205 event2str(event), event, linkset->span, which);
3206 sig_ss7_link_noalarm(linkset, which);
3209 ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
3210 event2str(event), event, linkset->span, which);
3214 #endif /* defined(HAVE_SS7) */
3216 #if defined(HAVE_SS7)
3217 static void my_ss7_set_loopback(void *pvt, int enable)
3219 struct dahdi_pvt *p = pvt;
3221 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
3222 ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
3226 #endif /* defined(HAVE_SS7) */
3228 #if defined(HAVE_SS7)
3231 * \brief Create a new asterisk channel structure for SS7.
3234 * \param pvt Private channel structure.
3235 * \param state Initial state of new channel.
3236 * \param law Combanding law to use.
3237 * \param exten Dialplan extension for incoming call.
3238 * \param requestor Channel requesting this new channel.
3240 * \retval ast_channel on success.
3241 * \retval NULL on error.
3243 static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor)
3245 struct dahdi_pvt *p = pvt;
3249 /* Set to audio mode at this point */
3251 if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
3252 ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
3253 p->channel, audio, strerror(errno));
3255 if (law != SIG_SS7_DEFLAW) {
3256 dahdi_setlaw(p->subs[SUB_REAL].dfd,
3257 (law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
3260 ast_copy_string(p->exten, exten, sizeof(p->exten));
3264 case SIG_SS7_DEFLAW:
3268 newlaw = DAHDI_LAW_ALAW;
3271 newlaw = DAHDI_LAW_MULAW;
3274 return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? requestor->linkedid : "");
3276 #endif /* defined(HAVE_SS7) */
3278 #if defined(HAVE_SS7)
3279 static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
3282 case SIG_SS7_TONE_RINGTONE:
3283 return DAHDI_TONE_RINGTONE;
3284 case SIG_SS7_TONE_STUTTER:
3285 return DAHDI_TONE_STUTTER;
3286 case SIG_SS7_TONE_CONGESTION:
3287 return DAHDI_TONE_CONGESTION;
3288 case SIG_SS7_TONE_DIALTONE:
3289 return DAHDI_TONE_DIALTONE;
3290 case SIG_SS7_TONE_DIALRECALL:
3291 return DAHDI_TONE_DIALRECALL;
3292 case SIG_SS7_TONE_INFO:
3293 return DAHDI_TONE_INFO;
3294 case SIG_SS7_TONE_BUSY:
3295 return DAHDI_TONE_BUSY;
3300 #endif /* defined(HAVE_SS7) */
3302 #if defined(HAVE_SS7)
3303 static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
3305 struct dahdi_pvt *p = pvt;
3307 return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
3309 #endif /* defined(HAVE_SS7) */
3311 #if defined(HAVE_SS7)
3312 static struct sig_ss7_callback dahdi_ss7_callbacks =
3314 .lock_private = my_lock_private,
3315 .unlock_private = my_unlock_private,
3317 .set_echocanceller = my_set_echocanceller,
3318 .set_loopback = my_ss7_set_loopback,
3320 .new_ast_channel = my_new_ss7_ast_channel,
3321 .play_tone = my_ss7_play_tone,
3323 .handle_link_exception = my_handle_link_exception,
3324 .set_alarm = my_set_alarm,
3325 .set_dialing = my_set_dialing,
3326 .set_digital = my_set_digital,
3327 .set_inservice = my_set_inservice,
3328 .set_locallyblocked = my_set_locallyblocked,
3329 .set_remotelyblocked = my_set_remotelyblocked,
3330 .set_callerid = my_set_callerid,
3331 .set_dnid = my_set_dnid,
3333 #endif /* defined(HAVE_SS7) */
3336 * \brief Send MWI state change
3338 * \arg mailbox_full This is the mailbox associated with the FXO line that the
3339 * MWI state has changed on.
3340 * \arg thereornot This argument should simply be set to 1 or 0, to indicate
3341 * whether there are messages waiting or not.
3345 * This function does two things:
3347 * 1) It generates an internal Asterisk event notifying any other module that
3348 * cares about MWI that the state of a mailbox has changed.
3350 * 2) It runs the script specified by the mwimonitornotify option to allow
3351 * some custom handling of the state change.
3353 static void notify_message(char *mailbox_full, int thereornot)
3355 char s[sizeof(mwimonitornotify) + 80];
3356 struct ast_event *event;
3357 char *mailbox, *context;
3359 /* Strip off @default */
3360 context = mailbox = ast_strdupa(mailbox_full);
3361 strsep(&context, "@");
3362 if (ast_strlen_zero(context))
3363 context = "default";
3365 if (!(event = ast_event_new(AST_EVENT_MWI,
3366 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
3367 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
3368 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3369 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3370 AST_EVENT_IE_END))) {
3374 ast_event_queue_and_cache(event);
3376 if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
3377 snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3382 static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
3384 struct dahdi_pvt *p = pvt;
3386 if (neon_mwievent > -1 && !p->mwimonitor_neon)
3389 if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3390 ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3391 notify_message(p->mailbox, 1);
3392 } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3393 ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3394 notify_message(p->mailbox, 0);
3396 /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3397 /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3398 if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3406 static struct analog_callback dahdi_analog_callbacks =
3408 .play_tone = my_play_tone,
3409 .get_event = my_get_event,
3410 .wait_event = my_wait_event,
3411 .is_off_hook = my_is_off_hook,
3412 .set_echocanceller = my_set_echocanceller,
3415 .off_hook = my_off_hook,
3416 .dial_digits = my_dial_digits,
3417 .train_echocanceller = my_train_echocanceller,
3418 .on_hook = my_on_hook,
3419 .is_dialing = my_is_dialing,
3420 .allocate_sub = my_allocate_sub,
3421 .unallocate_sub = my_unallocate_sub,
3422 .swap_subs = my_swap_subchannels,
3423 .has_voicemail = my_has_voicemail,
3424 .check_for_conference = my_check_for_conference,
3425 .conf_add = my_conf_add,
3426 .conf_del = my_conf_del,
3427 .complete_conference_update = my_complete_conference_update,
3429 .all_subchannels_hungup = my_all_subchannels_hungup,
3430 .lock_private = my_lock_private,
3431 .unlock_private = my_unlock_private,
3432 .handle_dtmfup = my_handle_dtmfup,
3434 .new_ast_channel = my_new_analog_ast_channel,
3435 .dsp_set_digitmode = my_dsp_set_digitmode,
3436 .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3437 .send_callerid = my_send_callerid,
3438 .callwait = my_callwait,
3439 .stop_callwait = my_stop_callwait,
3440 .get_callerid = my_get_callerid,
3441 .start_cid_detect = my_start_cid_detect,
3442 .stop_cid_detect = my_stop_cid_detect,
3443 .handle_notify_message = my_handle_notify_message,
3444 .increase_ss_count = my_increase_ss_count,
3445 .decrease_ss_count = my_decrease_ss_count,
3446 .distinctive_ring = my_distinctive_ring,
3447 .set_linear_mode = my_set_linear_mode,
3448 .get_and_handle_alarms = my_get_and_handle_alarms,
3449 .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
3450 .get_sub_fd = my_get_sub_fd,
3451 .set_cadence = my_set_cadence,
3452 .set_alarm = my_set_alarm,
3453 .set_dialing = my_set_dialing,
3454 .set_ringtimeout = my_set_ringtimeout,
3455 .set_waitingfordt = my_set_waitingfordt,
3456 .check_waitingfordt = my_check_waitingfordt,
3457 .set_confirmanswer = my_set_confirmanswer,
3458 .check_confirmanswer = my_check_confirmanswer,
3459 .cancel_cidspill = my_cancel_cidspill,
3460 .confmute = my_confmute,
3461 .set_pulsedial = my_set_pulsedial,
3462 .get_orig_dialstring = my_get_orig_dialstring,
3463 .set_needringing = my_set_needringing,
3466 /*! Round robin search locations. */
3467 static struct dahdi_pvt *round_robin[32];
3469 static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok)
3472 if (p->subs[SUB_REAL].owner == ast)
3474 else if (p->subs[SUB_CALLWAIT].owner == ast)
3476 else if (p->subs[SUB_THREEWAY].owner == ast)
3481 ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
3486 static void wakeup_sub(struct dahdi_pvt *p, int a)
3489 if (p->subs[a].owner) {
3490 if (ast_channel_trylock(p->subs[a].owner)) {
3491 DEADLOCK_AVOIDANCE(&p->lock);
3493 ast_queue_frame(p->subs[a].owner, &ast_null_frame);
3494 ast_channel_unlock(p->subs[a].owner);
3502 static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
3506 if (ast_channel_trylock(p->owner)) {
3507 DEADLOCK_AVOIDANCE(&p->lock);
3509 ast_queue_frame(p->owner, f);
3510 ast_channel_unlock(p->owner);
3518 static void handle_clear_alarms(struct dahdi_pvt *p)
3520 if (report_alarms & REPORT_CHANNEL_ALARMS) {
3521 ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
3522 manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
3524 if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
3525 ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
3526 manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
3532 static int dahdi_r2_answer(struct dahdi_pvt *p)
3535 /* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
3536 * and does not has support for openr2_chan_answer_call_with_mode
3538 #if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3539 const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
3540 int wants_double_answer = ast_true(double_answer) ? 1 : 0;
3541 if (!double_answer) {
3542 /* this still can result in double answer if the channel context
3543 * was configured that way */
3544 res = openr2_chan_answer_call(p->r2chan);
3545 } else if (wants_double_answer) {
3546 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3548 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3551 res = openr2_chan_answer_call(p->r2chan);
3558 /* should be called with the ast_channel locked */
3559 static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
3561 openr2_calling_party_category_t cat;
3562 const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
3563 struct dahdi_pvt *p = c->tech_pvt;
3564 if (ast_strlen_zero(catstr)) {
3565 ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
3566 c->name, openr2_proto_get_category_string(p->mfcr2_category));
3567 return p->mfcr2_category;
3569 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3570 ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
3571 catstr, c->name, openr2_proto_get_category_string(p->mfcr2_category));
3572 return p->mfcr2_category;
3574 ast_debug(1, "Using category %s\n", catstr);
3578 static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3580 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3581 ast_mutex_lock(&p->lock);
3583 ast_mutex_unlock(&p->lock);
3584 /* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
3585 interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
3586 can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
3587 the other end will see our seize as a forced release and drop the call, we will see an invalid
3588 pattern that will be seen and treated as protocol error. */
3589 ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3593 /* better safe than sorry ... */
3594 p->cid_name[0] = '\0';
3595 p->cid_num[0] = '\0';
3596 p->cid_subaddr[0] = '\0';
3599 p->mfcr2_ani_index = '\0';
3600 p->mfcr2_dnis_index = '\0';
3601 p->mfcr2_dnis_matched = 0;
3602 p->mfcr2_answer_pending = 0;
3603 p->mfcr2_call_accepted = 0;
3604 ast_mutex_unlock(&p->lock);
3605 ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3608 static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
3611 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3612 ast_mutex_lock(&p->lock);
3613 p->inalarm = alarm ? 1 : 0;
3615 res = get_alarms(p);
3616 handle_alarms(p, res);
3618 handle_clear_alarms(p);
3620 ast_mutex_unlock(&p->lock);
3623 static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
3625 ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3628 static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3630 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3631 ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
3633 p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR;
3634 p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
3636 ast_mutex_lock(&p->lock);
3638 ast_mutex_unlock(&p->lock);
3641 static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
3643 if (openr2_chan_disconnect_call(p->r2chan, cause)) {
3644 ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
3645 p->channel, openr2_proto_get_disconnect_string(cause));
3646 /* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
3647 openr2_chan_set_idle(p->r2chan);
3648 ast_mutex_lock(&p->lock);
3650 ast_mutex_unlock(&p->lock);
3654 static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
3656 struct dahdi_pvt *p;
3657 struct ast_channel *c;
3658 ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
3659 openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
3660 openr2_proto_get_category_string(category));
3661 p = openr2_chan_get_client_data(r2chan);
3662 /* if collect calls are not allowed and this is a collect call, reject it! */
3663 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
3664 ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
3665 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
3668 ast_mutex_lock(&p->lock);
3669 p->mfcr2_recvd_category = category;
3670 /* if we're not supposed to use CID, clear whatever we have */
3671 if (!p->use_callerid) {
3672 ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n");
3676 /* if we're supposed to answer immediately, clear DNIS and set 's' exten */
3677 if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
3678 ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n");
3682 ast_mutex_unlock(&p->lock);
3683 if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
3684 ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
3685 p->channel, p->exten, p->context);
3686 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
3689 if (!p->mfcr2_accept_on_offer) {
3690 /* The user wants us to start the PBX thread right away without accepting the call first */
3691 c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
3693 /* Done here, don't disable reading now since we still need to generate MF tones to accept
3694 the call or reject it and detect the tone off condition of the other end, all of this
3695 will be done in the PBX thread now */
3698 ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
3699 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
3700 } else if (p->mfcr2_charge_calls) {
3701 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
3702 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
3704 ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
3705 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
3709 static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
3711 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3712 ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
3713 ast_mutex_lock(&p->lock);
3715 ast_mutex_unlock(&p->lock);
3718 static void dahdi_enable_ec(struct dahdi_pvt *p);
3719 static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
3721 struct dahdi_pvt *p = NULL;
3722 struct ast_channel *c = NULL;
3723 p = openr2_chan_get_client_data(r2chan);
3725 p->mfcr2_call_accepted = 1;
3726 /* if it's an incoming call ... */
3727 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
3728 ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
3729 /* If accept on offer is not set, it means at this point the PBX thread is already
3730 launched (was launched in the 'on call offered' handler) and therefore this callback
3731 is being executed already in the PBX thread rather than the monitor thread, don't launch
3732 any other thread, just disable the openr2 reading and answer the call if neede