2
* Asterisk -- An open source telephony toolkit.
4
* Copyright (C) 1999 - 2006, 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: 253595 $")
53
#if defined(__NetBSD__) || defined(__FreeBSD__)
57
#include <sys/signal.h>
59
#include <sys/ioctl.h>
63
#include <dahdi/user.h>
64
#include <dahdi/tonezone.h>
78
#include "asterisk/lock.h"
79
#include "asterisk/channel.h"
80
#include "asterisk/config.h"
81
#include "asterisk/module.h"
82
#include "asterisk/pbx.h"
83
#include "asterisk/file.h"
84
#include "asterisk/ulaw.h"
85
#include "asterisk/alaw.h"
86
#include "asterisk/callerid.h"
87
#include "asterisk/adsi.h"
88
#include "asterisk/cli.h"
89
#include "asterisk/cdr.h"
90
#include "asterisk/features.h"
91
#include "asterisk/musiconhold.h"
92
#include "asterisk/say.h"
93
#include "asterisk/tdd.h"
94
#include "asterisk/app.h"
95
#include "asterisk/dsp.h"
96
#include "asterisk/astdb.h"
97
#include "asterisk/manager.h"
98
#include "asterisk/causes.h"
99
#include "asterisk/term.h"
100
#include "asterisk/utils.h"
101
#include "asterisk/transcap.h"
102
#include "asterisk/stringfields.h"
103
#include "asterisk/abstract_jb.h"
104
#include "asterisk/smdi.h"
105
#include "asterisk/astobj.h"
106
#include "asterisk/event.h"
107
#include "asterisk/devicestate.h"
108
#include "asterisk/paths.h"
111
<application name="DAHDISendKeypadFacility" language="en_US">
113
Send digits out of band over a PRI.
116
<parameter name="digits" required="true" />
119
<para>This application will send the given string of digits in a Keypad
120
Facility IE over the current channel.</para>
123
<application name="DAHDISendCallreroutingFacility" language="en_US">
125
Send QSIG call rerouting facility over a PRI.
128
<parameter name="destination" required="true">
129
<para>Destination number.</para>
131
<parameter name="original">
132
<para>Original called number.</para>
134
<parameter name="reason">
135
<para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
139
<para>This application will send a Callrerouting Facility IE over the
140
current channel.</para>
143
<application name="DAHDIAcceptR2Call" language="en_US">
145
Accept an R2 call if its not already accepted (you still need to answer it)
148
<parameter name="charge" required="true">
149
<para>Yes or No.</para>
150
<para>Whether you want to accept the call with charge or without charge.</para>
154
<para>This application will Accept the R2 call either with charge or no charge.</para>
159
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
161
static const char *lbostr[] = {
162
"0 db (CSU)/0-133 feet (DSX-1)",
163
"133-266 feet (DSX-1)",
164
"266-399 feet (DSX-1)",
165
"399-533 feet (DSX-1)",
166
"533-655 feet (DSX-1)",
172
/*! Global jitterbuffer configuration - by default, jb is disabled */
173
static struct ast_jb_conf default_jbconf =
177
.resync_threshold = -1,
181
static struct ast_jb_conf global_jbconf;
183
/* define this to send PRI user-user information elements */
184
#undef SUPPORT_USERUSER
187
* \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
188
* the user hangs up to reset the state machine so ring works properly.
189
* This is used to be able to support kewlstart by putting the zhone in
190
* groundstart mode since their forward disconnect supervision is entirely
191
* broken even though their documentation says it isn't and their support
192
* is entirely unwilling to provide any assistance with their channel banks
193
* even though their web site says they support their products for life.
195
/* #define ZHONE_HACK */
198
* Define if you want to check the hook state for an FXO (FXS signalled) interface
199
* before dialing on it. Certain FXO interfaces always think they're out of
200
* service with this method however.
202
/* #define DAHDI_CHECK_HOOKSTATE */
204
/*! \brief Typically, how many rings before we should send Caller*ID */
205
#define DEFAULT_CIDRINGS 1
207
#define CHANNEL_PSEUDO -12
209
#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
212
/*! \brief Signaling types that need to use MF detection should be placed in this macro */
213
#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))
215
static const char tdesc[] = "DAHDI Telephony Driver"
216
#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
230
#if defined(HAVE_PRI) || defined(HAVE_SS7)
238
static const char config[] = "chan_dahdi.conf";
240
#define SIG_EM DAHDI_SIG_EM
241
#define SIG_EMWINK (0x0100000 | DAHDI_SIG_EM)
242
#define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
243
#define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
244
#define SIG_FEATB (0x0800000 | DAHDI_SIG_EM)
245
#define SIG_E911 (0x1000000 | DAHDI_SIG_EM)
246
#define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
247
#define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM)
248
#define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
249
#define SIG_FXSLS DAHDI_SIG_FXSLS
250
#define SIG_FXSGS DAHDI_SIG_FXSGS
251
#define SIG_FXSKS DAHDI_SIG_FXSKS
252
#define SIG_FXOLS DAHDI_SIG_FXOLS
253
#define SIG_FXOGS DAHDI_SIG_FXOGS
254
#define SIG_FXOKS DAHDI_SIG_FXOKS
255
#define SIG_PRI DAHDI_SIG_CLEAR
256
#define SIG_BRI (0x2000000 | DAHDI_SIG_CLEAR)
257
#define SIG_BRI_PTMP (0X4000000 | DAHDI_SIG_CLEAR)
258
#define SIG_SS7 (0x1000000 | DAHDI_SIG_CLEAR)
259
#define SIG_MFCR2 DAHDI_SIG_CAS
260
#define SIG_SF DAHDI_SIG_SF
261
#define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF)
262
#define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
263
#define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
264
#define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF)
265
#define SIG_EM_E1 DAHDI_SIG_EM_E1
266
#define SIG_GR303FXOKS (0x0100000 | DAHDI_SIG_FXOKS)
267
#define SIG_GR303FXSKS (0x0100000 | DAHDI_SIG_FXSKS)
270
#define NUM_SPANS DAHDI_MAX_SPANS
274
#define NUM_DCHANS 4 /*!< No more than 4 d-channels */
275
#define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
277
#define CHAN_PSEUDO -2
279
#define DCHAN_PROVISIONED (1 << 0)
280
#define DCHAN_NOTINALARM (1 << 1)
281
#define DCHAN_UP (1 << 2)
283
#define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
285
/* Overlap dialing option types */
286
#define DAHDI_OVERLAPDIAL_NONE 0
287
#define DAHDI_OVERLAPDIAL_OUTGOING 1
288
#define DAHDI_OVERLAPDIAL_INCOMING 2
289
#define DAHDI_OVERLAPDIAL_BOTH (DAHDI_OVERLAPDIAL_INCOMING|DAHDI_OVERLAPDIAL_OUTGOING)
291
#define CALLPROGRESS_PROGRESS 1
292
#define CALLPROGRESS_FAX_OUTGOING 2
293
#define CALLPROGRESS_FAX_INCOMING 4
294
#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
296
static char defaultcic[64] = "";
297
static char defaultozz[64] = "";
299
static char parkinglot[AST_MAX_EXTENSION] = ""; /*!< Default parking lot for this channel */
301
/*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
302
static char mwimonitornotify[PATH_MAX] = "";
303
#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
304
static int mwisend_rpas = 0;
307
static char progzone[10] = "";
309
static int usedistinctiveringdetection = 0;
310
static int distinctiveringaftercid = 0;
312
static int numbufs = 4;
314
static int mwilevel = 512;
317
static struct ast_channel inuse;
318
#ifdef PRI_GETSET_TIMERS
319
static int pritimers[PRI_MAX_TIMERS];
321
static int pridebugfd = -1;
322
static char pridebugfilename[1024] = "";
325
/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
326
static int firstdigittimeout = 16000;
328
/*! \brief How long to wait for following digits (FXO logic) */
329
static int gendigittimeout = 8000;
331
/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
332
static int matchdigittimeout = 3000;
334
/*! \brief Protect the interface list (of dahdi_pvt's) */
335
AST_MUTEX_DEFINE_STATIC(iflock);
337
/* QSIG channel mapping option types */
338
#define DAHDI_CHAN_MAPPING_PHYSICAL 0
339
#define DAHDI_CHAN_MAPPING_LOGICAL 1
342
static int ifcount = 0;
345
AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
348
/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
349
when it's doing something critical. */
350
AST_MUTEX_DEFINE_STATIC(monlock);
352
/*! \brief This is the thread for the monitor which checks for input on the channels
353
which are not currently in use. */
354
static pthread_t monitor_thread = AST_PTHREADT_NULL;
355
static ast_cond_t ss_thread_complete;
356
AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
357
AST_MUTEX_DEFINE_STATIC(restart_lock);
358
static int ss_thread_count = 0;
359
static int num_restart_pending = 0;
361
static int restart_monitor(void);
363
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);
365
static int dahdi_sendtext(struct ast_channel *c, const char *text);
367
static void mwi_event_cb(const struct ast_event *event, void *userdata)
369
/* This module does not handle MWI in an event-based manner. However, it
370
* subscribes to MWI for each mailbox that is configured so that the core
371
* knows that we care about it. Then, chan_dahdi will get the MWI from the
372
* event cache instead of checking the mailbox directly. */
375
/*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
376
static inline int dahdi_get_event(int fd)
379
if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
384
/*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
385
static inline int dahdi_wait_event(int fd)
388
i = DAHDI_IOMUX_SIGEVENT;
389
if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
391
if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
396
/*! Chunk size to read -- we use 20ms chunks to make things happy. */
397
#define READ_SIZE 160
399
#define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
400
#define MASK_INUSE (1 << 1) /*!< Channel currently in use */
402
#define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) /*!< 300 ms */
403
#define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
404
#define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) /*!< 500 ms */
405
#define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
406
#define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
411
* \brief Configured ring timeout base.
412
* \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
414
static int ringt_base = DEFAULT_RINGT;
418
#define LINKSTATE_INALARM (1 << 0)
419
#define LINKSTATE_STARTING (1 << 1)
420
#define LINKSTATE_UP (1 << 2)
421
#define LINKSTATE_DOWN (1 << 3)
423
#define SS7_NAI_DYNAMIC -1
425
#define LINKSET_FLAG_EXPLICITACM (1 << 0)
428
pthread_t master; /*!< Thread of master */
432
int linkstate[NUM_DCHANS];
436
LINKSET_STATE_DOWN = 0,
439
char called_nai; /*!< Called Nature of Address Indicator */
440
char calling_nai; /*!< Calling Nature of Address Indicator */
441
char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */
442
char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */
443
char subscriberprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
444
char unknownprefix[20]; /*!< for unknown dialplans */
446
struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
447
int flags; /*!< Linkset flags */
450
static struct dahdi_ss7 linksets[NUM_SPANS];
452
static int cur_ss7type = -1;
453
static int cur_linkset = -1;
454
static int cur_pointcode = -1;
455
static int cur_cicbeginswith = -1;
456
static int cur_adjpointcode = -1;
457
static int cur_networkindicator = -1;
458
static int cur_defaultdpc = -1;
459
#endif /* HAVE_SS7 */
463
pthread_t r2master; /*!< Thread of master */
464
openr2_context_t *protocol_context; /*!< OpenR2 context handle */
465
struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
466
int numchans; /*!< Number of channels in this R2 block */
467
int monitored_count; /*!< Number of channels being monitored */
470
struct dahdi_mfcr2_conf {
471
openr2_variant_t variant;
473
int metering_pulse_timeout;
476
signed int get_ani_first:2;
477
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
478
signed int skip_category_request:2;
480
unsigned int call_files:1;
481
unsigned int allow_collect_calls:1;
482
unsigned int charge_calls:1;
483
unsigned int accept_on_offer:1;
484
unsigned int forced_release:1;
485
unsigned int double_answer:1;
486
signed int immediate_accept:2;
487
char logdir[OR2_MAX_PATH];
488
char r2proto_file[OR2_MAX_PATH];
489
openr2_log_level_t loglevel;
490
openr2_calling_party_category_t category;
493
/* malloc'd array of malloc'd r2links */
494
static struct dahdi_mfcr2 **r2links;
495
/* how many r2links have been malloc'd */
496
static int r2links_count = 0;
498
#endif /* HAVE_OPENR2 */
502
#define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
503
#define PRI_CHANNEL(p) ((p) & 0xff)
504
#define PRI_SPAN(p) (((p) >> 8) & 0xff)
505
#define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
508
pthread_t master; /*!< Thread of master */
509
ast_mutex_t lock; /*!< Mutex */
510
char idleext[AST_MAX_EXTENSION]; /*!< Where to idle extra calls */
511
char idlecontext[AST_MAX_CONTEXT]; /*!< What context to use for idle */
512
char idledial[AST_MAX_EXTENSION]; /*!< What to dial before dumping */
513
int minunused; /*!< Min # of channels to keep empty */
514
int minidle; /*!< Min # of "idling" calls to keep active */
515
int nodetype; /*!< Node type */
516
int switchtype; /*!< Type of switch to emulate */
517
int nsf; /*!< Network-Specific Facilities */
518
int dialplan; /*!< Dialing plan */
519
int localdialplan; /*!< Local dialing plan */
520
char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */
521
char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */
522
char localprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
523
char privateprefix[20]; /*!< for private dialplans */
524
char unknownprefix[20]; /*!< for unknown dialplans */
525
int dchannels[NUM_DCHANS]; /*!< What channel are the dchannels on */
526
int trunkgroup; /*!< What our trunkgroup is */
527
int mastertrunkgroup; /*!< What trunk group is our master */
528
int prilogicalspan; /*!< Logical span number within trunk group */
529
int numchans; /*!< Num of channels we represent */
530
int overlapdial; /*!< In overlap dialing mode */
531
int qsigchannelmapping; /*!< QSIG channel mapping type */
532
int discardremoteholdretrieval; /*!< shall remote hold or remote retrieval notifications be discarded? */
533
int facilityenable; /*!< Enable facility IEs */
534
struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */
535
int dchanavail[NUM_DCHANS]; /*!< Whether each channel is available */
536
struct pri *pri; /*!< Currently active D-channel */
537
/*! \brief TRUE if to dump PRI event info (Tested but never set) */
539
int fds[NUM_DCHANS]; /*!< FD's for d-channels */
540
/*! \brief Value set but not used */
542
/*! \brief Span number put into user output messages */
544
/*! \brief TRUE if span is being reset/restarted */
546
/*! \brief Current position during a reset (-1 if not started) */
548
#ifdef HAVE_PRI_INBANDDISCONNECT
549
unsigned int inbanddisconnect:1; /*!< Should we support inband audio after receiving DISCONNECT? */
551
time_t lastreset; /*!< time when unused channels were last reset */
552
long resetinterval; /*!< Interval (in seconds) for resetting unused channels */
553
/*! \brief ISDN signalling type (SIG_PRI, SIG_BRI, SIG_BRI_PTMP, etc...) */
555
struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
556
struct dahdi_pvt *crvs; /*!< Member CRV structs */
557
struct dahdi_pvt *crvend; /*!< Pointer to end of CRV structs */
561
static struct dahdi_pri pris[NUM_SPANS];
564
#define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
566
#define DEFAULT_PRI_DEBUG 0
569
static inline void pri_rel(struct dahdi_pri *pri)
571
ast_mutex_unlock(&pri->lock);
575
/*! Shut up the compiler */
579
#define SUB_REAL 0 /*!< Active call */
580
#define SUB_CALLWAIT 1 /*!< Call-Waiting call on hold */
581
#define SUB_THREEWAY 2 /*!< Three-way call */
583
/* Polarity states */
584
#define POLARITY_IDLE 0
585
#define POLARITY_REV 1
588
struct distRingData {
592
struct ringContextData {
593
char contextData[AST_MAX_CONTEXT];
595
struct dahdi_distRings {
596
struct distRingData ringnum[3];
597
struct ringContextData ringContext[3];
600
static char *subnames[] = {
606
struct dahdi_subchannel {
608
struct ast_channel *owner;
610
short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
611
struct ast_frame f; /*!< One frame for each channel. How did this ever work before? */
612
unsigned int needringing:1;
613
unsigned int needbusy:1;
614
unsigned int needcongestion:1;
615
unsigned int needcallerid:1;
616
unsigned int needanswer:1;
617
unsigned int needflash:1;
618
unsigned int needhold:1;
619
unsigned int needunhold:1;
620
unsigned int linear:1;
621
unsigned int inthreeway:1;
622
struct dahdi_confinfo curconf;
625
#define CONF_USER_REAL (1 << 0)
626
#define CONF_USER_THIRDCALL (1 << 1)
630
/* States for sending MWI message
631
* First three states are required for send Ring Pulse Alert Signal
643
struct mwisend_info {
644
struct timeval pause;
645
mwisend_states mwisend_current;
648
static struct dahdi_pvt {
649
ast_mutex_t lock; /*!< Channel private lock. */
650
struct ast_channel *owner; /*!< Our current active owner (if applicable) */
651
/*!< Up to three channels can be associated with this call */
653
struct dahdi_subchannel sub_unused; /*!< Just a safety precaution */
654
struct dahdi_subchannel subs[3]; /*!< Sub-channels */
655
struct dahdi_confinfo saveconf; /*!< Saved conference info */
657
struct dahdi_pvt *slaves[MAX_SLAVES]; /*!< Slave to us (follows our conferencing) */
658
struct dahdi_pvt *master; /*!< Master to us (we follow their conferencing) */
659
int inconference; /*!< If our real should be in the conference */
661
int bufsize; /*!< Size of the buffers */
662
int buf_no; /*!< Number of buffers */
663
int buf_policy; /*!< Buffer policy */
664
int faxbuf_no; /*!< Number of Fax buffers */
665
int faxbuf_policy; /*!< Fax buffer policy */
666
int sig; /*!< Signalling style */
668
* \brief Nonzero if the signaling type is sent over a radio.
669
* \note Set to a couple of nonzero values but it is only tested like a boolean.
672
int outsigmod; /*!< Outbound Signalling style (modifier) */
673
int oprmode; /*!< "Operator Services" mode */
674
struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */
675
/*! \brief Amount of gain to increase during caller id */
677
/*! \brief Rx gain set by chan_dahdi.conf */
679
/*! \brief Tx gain set by chan_dahdi.conf */
681
int tonezone; /*!< tone zone for this chan, or -1 for default */
682
struct dahdi_pvt *next; /*!< Next channel in list */
683
struct dahdi_pvt *prev; /*!< Prev channel in list */
688
* \brief TRUE if ADSI (Analog Display Services Interface) available
689
* \note Set from the "adsi" value read in from chan_dahdi.conf
693
* \brief TRUE if we can use a polarity reversal to mark when an outgoing
694
* call is answered by the remote party.
695
* \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
697
unsigned int answeronpolarityswitch:1;
699
* \brief TRUE if busy detection is enabled.
700
* (Listens for the beep-beep busy pattern.)
701
* \note Set from the "busydetect" value read in from chan_dahdi.conf
703
unsigned int busydetect:1;
705
* \brief TRUE if call return is enabled.
706
* (*69, if your dialplan doesn't catch this first)
707
* \note Set from the "callreturn" value read in from chan_dahdi.conf
709
unsigned int callreturn:1;
711
* \brief TRUE if busy extensions will hear the call-waiting tone
712
* and can use hook-flash to switch between callers.
713
* \note Can be disabled by dialing *70.
714
* \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
716
unsigned int callwaiting:1;
718
* \brief TRUE if send caller ID for Call Waiting
719
* \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
721
unsigned int callwaitingcallerid:1;
723
* \brief TRUE if support for call forwarding enabled.
724
* Dial *72 to enable call forwarding.
725
* Dial *73 to disable call forwarding.
726
* \note Set from the "cancallforward" value read in from chan_dahdi.conf
728
unsigned int cancallforward:1;
730
* \brief TRUE if support for call parking is enabled.
731
* \note Set from the "canpark" value read in from chan_dahdi.conf
733
unsigned int canpark:1;
734
/*! \brief TRUE if to wait for a DTMF digit to confirm answer */
735
unsigned int confirmanswer:1;
737
* \brief TRUE if the channel is to be destroyed on hangup.
738
* (Used by pseudo channels.)
740
unsigned int destroy:1;
741
unsigned int didtdd:1; /*!< flag to say its done it once */
742
/*! \brief TRUE if analog type line dialed no digits in Dial() */
743
unsigned int dialednone:1;
744
/*! \brief TRUE if in the process of dialing digits or sending something. */
745
unsigned int dialing:1;
746
/*! \brief TRUE if the transfer capability of the call is digital. */
747
unsigned int digital:1;
748
/*! \brief TRUE if Do-Not-Disturb is enabled. */
750
/*! \brief XXX BOOLEAN Purpose??? */
751
unsigned int echobreak:1;
753
* \brief TRUE if echo cancellation enabled when bridged.
754
* \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
755
* \note Disabled if the echo canceller is not setup.
757
unsigned int echocanbridged:1;
758
/*! \brief TRUE if echo cancellation is turned on. */
759
unsigned int echocanon:1;
760
/*! \brief TRUE if a fax tone has already been handled. */
761
unsigned int faxhandled:1;
762
/*! \brief TRUE if dynamic faxbuffers are configured for use, default is OFF */
763
unsigned int usefaxbuffers:1;
764
/*! \brief TRUE while dynamic faxbuffers are in use */
765
unsigned int faxbuffersinuse:1;
766
/*! \brief TRUE if over a radio and dahdi_read() has been called. */
767
unsigned int firstradio:1;
769
* \brief TRUE if the call will be considered "hung up" on a polarity reversal.
770
* \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
772
unsigned int hanguponpolarityswitch:1;
773
/*! \brief TRUE if DTMF detection needs to be done by hardware. */
774
unsigned int hardwaredtmf:1;
776
* \brief TRUE if the outgoing caller ID is blocked/hidden.
777
* \note Caller ID can be disabled by dialing *67.
778
* \note Caller ID can be enabled by dialing *82.
779
* \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
781
unsigned int hidecallerid:1;
783
* \brief TRUE if hide just the name not the number for legacy PBX use.
784
* \note Only applies to PRI channels.
785
* \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
787
unsigned int hidecalleridname:1;
788
/*! \brief TRUE if DTMF detection is disabled. */
789
unsigned int ignoredtmf:1;
791
* \brief TRUE if the channel should be answered immediately
792
* without attempting to gather any digits.
793
* \note Set from the "immediate" value read in from chan_dahdi.conf
795
unsigned int immediate:1;
796
/*! \brief TRUE if in an alarm condition. */
797
unsigned int inalarm:1;
798
/*! \brief TRUE if TDD in MATE mode */
800
/*! \brief TRUE if we originated the call leg. */
801
unsigned int outgoing:1;
802
/* unsigned int overlapdial:1; unused and potentially confusing */
804
* \brief TRUE if busy extensions will hear the call-waiting tone
805
* and can use hook-flash to switch between callers.
806
* \note Set from the "callwaiting" value read in from chan_dahdi.conf
808
unsigned int permcallwaiting:1;
810
* \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
811
* \note Set from the "hidecallerid" value read in from chan_dahdi.conf
813
unsigned int permhidecallerid:1;
815
* \brief TRUE if PRI congestion/busy indications are sent out-of-band.
816
* \note Set from the "priindication" value read in from chan_dahdi.conf
818
unsigned int priindication_oob:1;
820
* \brief TRUE if PRI B channels are always exclusively selected.
821
* \note Set from the "priexclusive" value read in from chan_dahdi.conf
823
unsigned int priexclusive:1;
825
* \brief TRUE if we will pulse dial.
826
* \note Set from the "pulsedial" value read in from chan_dahdi.conf
828
unsigned int pulse:1;
829
/*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
830
unsigned int pulsedial:1;
831
unsigned int restartpending:1; /*!< flag to ensure counted only once for restart */
833
* \brief TRUE if caller ID is restricted.
834
* \note Set but not used. Should be deleted. Redundant with permhidecallerid.
835
* \note Set from the "restrictcid" value read in from chan_dahdi.conf
837
unsigned int restrictcid:1;
839
* \brief TRUE if three way calling is enabled
840
* \note Set from the "threewaycalling" value read in from chan_dahdi.conf
842
unsigned int threewaycalling:1;
844
* \brief TRUE if call transfer is enabled
845
* \note For FXS ports (either direct analog or over T1/E1):
846
* Support flash-hook call transfer
847
* \note For digital ports using ISDN PRI protocols:
848
* Support switch-side transfer (called 2BCT, RLT or other names)
849
* \note Set from the "transfer" value read in from chan_dahdi.conf
851
unsigned int transfer:1;
853
* \brief TRUE if caller ID is used on this channel.
854
* \note PRI and SS7 spans will save caller ID from the networking peer.
855
* \note FXS ports will generate the caller ID spill.
856
* \note FXO ports will listen for the caller ID spill.
857
* \note Set from the "usecallerid" value read in from chan_dahdi.conf
859
unsigned int use_callerid:1;
861
* \brief TRUE if we will use the calling presentation setting
862
* from the Asterisk channel for outgoing calls.
863
* \note Only applies to PRI and SS7 channels.
864
* \note Set from the "usecallingpres" value read in from chan_dahdi.conf
866
unsigned int use_callingpres:1;
868
* \brief TRUE if distinctive rings are to be detected.
869
* \note For FXO lines
870
* \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
872
unsigned int usedistinctiveringdetection:1;
874
* \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
875
* \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
877
unsigned int dahditrcallerid:1;
879
* \brief TRUE if allowed to flash-transfer to busy channels.
880
* \note Set from the "transfertobusy" value read in from chan_dahdi.conf
882
unsigned int transfertobusy:1;
884
* \brief TRUE if the FXO port monitors for neon type MWI indications from the other end.
885
* \note Set if the "mwimonitor" value read in contains "neon" from chan_dahdi.conf
887
unsigned int mwimonitor_neon:1;
889
* \brief TRUE if the FXO port monitors for fsk type MWI indications from the other end.
890
* \note Set if the "mwimonitor" value read in contains "fsk" from chan_dahdi.conf
892
unsigned int mwimonitor_fsk:1;
894
* \brief TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
895
* \note RPAS - Ring Pulse Alert Signal
896
* \note Set if the "mwimonitor" value read in contains "rpas" from chan_dahdi.conf
898
unsigned int mwimonitor_rpas:1;
899
/*! \brief TRUE if an MWI monitor thread is currently active */
900
unsigned int mwimonitoractive:1;
901
/*! \brief TRUE if a MWI message sending thread is active */
902
unsigned int mwisendactive:1;
904
* \brief TRUE if channel is out of reset and ready
905
* \note Set but not used.
907
unsigned int inservice:1;
909
* \brief TRUE if the channel is locally blocked.
910
* \note Applies to SS7 channels.
912
unsigned int locallyblocked:1;
914
* \brief TRUE if the channel is remotely blocked.
915
* \note Applies to SS7 channels.
917
unsigned int remotelyblocked:1;
918
#if defined(HAVE_PRI) || defined(HAVE_SS7)
920
* \brief XXX BOOLEAN Purpose???
921
* \note Applies to SS7 channels.
924
/*! \brief TRUE if channel is alerting/ringing */
925
unsigned int alerting:1;
926
/*! \brief TRUE if the call has already gone/hungup */
927
unsigned int alreadyhungup:1;
929
* \brief TRUE if this is an idle call
930
* \note Applies to PRI channels.
932
unsigned int isidlecall:1;
934
* \brief TRUE if call is in a proceeding state.
935
* The call has started working its way through the network.
937
unsigned int proceeding:1;
938
/*! \brief TRUE if the call has seen progress through the network. */
939
unsigned int progress:1;
941
* \brief TRUE if this channel is being reset/restarted
942
* \note Applies to PRI channels.
944
unsigned int resetting:1;
946
* \brief TRUE if this channel has received a SETUP_ACKNOWLEDGE
947
* \note Applies to PRI channels.
949
unsigned int setup_ack:1;
952
* \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
953
* \note Set from the "usesmdi" value read in from chan_dahdi.conf
955
unsigned int use_smdi:1;
956
struct mwisend_info mwisend_data;
957
/*! \brief The serial port to listen for SMDI data on */
958
struct ast_smdi_interface *smdi_iface;
960
/*! \brief Distinctive Ring data */
961
struct dahdi_distRings drings;
964
* \brief The configured context for incoming calls.
965
* \note The "context" string read in from chan_dahdi.conf
967
char context[AST_MAX_CONTEXT];
969
* \brief Saved context string.
971
char defcontext[AST_MAX_CONTEXT];
972
/*! \brief Extension to use in the dialplan. */
973
char exten[AST_MAX_EXTENSION];
975
* \brief Language configured for calls.
976
* \note The "language" string read in from chan_dahdi.conf
978
char language[MAX_LANGUAGE];
980
* \brief The configured music-on-hold class to use for calls.
981
* \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
983
char mohinterpret[MAX_MUSICCLASS];
985
* \brief Suggested music-on-hold class for peer channel to use for calls.
986
* \note The "mohsuggest" string read in from chan_dahdi.conf
988
char mohsuggest[MAX_MUSICCLASS];
989
char parkinglot[AST_MAX_EXTENSION]; /*!< Parking lot for this channel */
990
#if defined(PRI_ANI) || defined(HAVE_SS7)
991
/*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
992
char cid_ani[AST_MAX_EXTENSION];
994
/*! \brief Automatic Number Identification code from PRI */
996
/*! \brief Caller ID number from an incoming call. */
997
char cid_num[AST_MAX_EXTENSION];
998
/*! \brief Caller ID Q.931 TON/NPI field values. Set by PRI. Zero otherwise. */
1000
/*! \brief Caller ID name from an incoming call. */
1001
char cid_name[AST_MAX_EXTENSION];
1002
/*! \brief Last Caller ID number from an incoming call. */
1003
char lastcid_num[AST_MAX_EXTENSION];
1004
/*! \brief Last Caller ID name from an incoming call. */
1005
char lastcid_name[AST_MAX_EXTENSION];
1006
char *origcid_num; /*!< malloced original callerid */
1007
char *origcid_name; /*!< malloced original callerid */
1008
/*! \brief Call waiting number. */
1009
char callwait_num[AST_MAX_EXTENSION];
1010
/*! \brief Call waiting name. */
1011
char callwait_name[AST_MAX_EXTENSION];
1012
/*! \brief Redirecting Directory Number Information Service (RDNIS) number */
1013
char rdnis[AST_MAX_EXTENSION];
1014
/*! \brief Dialed Number Identifier */
1015
char dnid[AST_MAX_EXTENSION];
1017
* \brief Bitmapped groups this belongs to.
1018
* \note The "group" bitmapped group string read in from chan_dahdi.conf
1021
/*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
1023
int confno; /*!< Our conference */
1024
int confusers; /*!< Who is using our conference */
1025
int propconfno; /*!< Propagated conference number */
1027
* \brief Bitmapped call groups this belongs to.
1028
* \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
1030
ast_group_t callgroup;
1032
* \brief Bitmapped pickup groups this belongs to.
1033
* \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
1035
ast_group_t pickupgroup;
1037
* \brief Channel variable list with associated values to set when a channel is created.
1038
* \note The "setvar" strings read in from chan_dahdi.conf
1040
struct ast_variable *vars;
1041
int channel; /*!< Channel Number or CRV */
1042
int span; /*!< Span number */
1043
time_t guardtime; /*!< Must wait this much time before using for new call */
1044
int cid_signalling; /*!< CID signalling type bell202 or v23 */
1045
int cid_start; /*!< CID start indicator, polarity or ring */
1046
int callingpres; /*!< The value of calling presentation that we're going to use when placing a PRI call */
1047
int callwaitingrepeat; /*!< How many samples to wait before repeating call waiting */
1048
int cidcwexpire; /*!< When to expire our muting for CID/CW */
1049
/*! \brief Analog caller ID waveform sample buffer */
1050
unsigned char *cidspill;
1051
/*! \brief Position in the cidspill buffer to send out next. */
1053
/*! \brief Length of the cidspill buffer containing samples. */
1055
/*! \brief Ring timeout timer?? */
1058
* \brief Ring timeout base.
1059
* \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
1063
* \brief Number of most significant digits/characters to strip from the dialed number.
1064
* \note Feature is deprecated. Use dialplan logic.
1065
* \note The characters are stripped before the PRI TON/NPI prefix
1066
* characters are processed.
1069
/*! \brief BOOLEAN. XXX Meaning what?? */
1071
/*! \brief Number of call waiting rings. */
1073
/*! \brief Echo cancel parameters. */
1075
struct dahdi_echocanparams head;
1076
struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS];
1079
* \brief Echo training time. 0 = disabled
1080
* \note Set from the "echotraining" value read in from chan_dahdi.conf
1083
/*! \brief Filled with 'w'. XXX Purpose?? */
1086
* \brief Number of times to see "busy" tone before hanging up.
1087
* \note Set from the "busycount" value read in from chan_dahdi.conf
1091
* \brief Length of "busy" tone on time.
1092
* \note Set from the "busypattern" value read in from chan_dahdi.conf
1094
int busy_tonelength;
1096
* \brief Length of "busy" tone off time.
1097
* \note Set from the "busypattern" value read in from chan_dahdi.conf
1099
int busy_quietlength;
1101
* \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
1102
* \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
1106
* \brief Number of milliseconds to wait for dialtone.
1107
* \note Set from the "waitfordialtone" value read in from chan_dahdi.conf
1109
int waitfordialtone;
1110
struct timeval waitingfordt; /*!< Time we started waiting for dialtone */
1111
struct timeval flashtime; /*!< Last flash-hook time */
1112
/*! \brief Opaque DSP configuration structure. */
1113
struct ast_dsp *dsp;
1114
//int cref; /*!< Call reference number (Not used) */
1115
/*! \brief DAHDI dial operation command struct for ioctl() call. */
1116
struct dahdi_dialoperation dop;
1117
int whichwink; /*!< SIG_FEATDMF_TA Which wink are we on? */
1118
/*! \brief Second part of SIG_FEATDMF_TA wink operation. */
1120
char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
1121
int amaflags; /*!< AMA Flags */
1122
struct tdd_state *tdd; /*!< TDD flag */
1123
/*! \brief Accumulated call forwarding number. */
1124
char call_forward[AST_MAX_EXTENSION];
1126
* \brief Voice mailbox location.
1127
* \note Set from the "mailbox" string read in from chan_dahdi.conf
1129
char mailbox[AST_MAX_EXTENSION];
1130
/*! \brief Opaque event subscription parameters for message waiting indication support. */
1131
struct ast_event_sub *mwi_event_sub;
1132
/*! \brief Delayed dialing for E911. Overlap digits for ISDN. */
1134
/*! \brief Time the interface went on-hook. */
1136
/*! \brief TRUE if the FXS port is off-hook */
1137
int fxsoffhookstate;
1138
/*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
1140
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1141
struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */
1142
unsigned int mwisend_fsk: 1; /*! Variable for enabling FSK MWI handling in chan_dahdi */
1143
unsigned int mwisend_rpas:1; /*! Variable for enabling Ring Pulse Alert before MWI FSK Spill */
1145
int distinctivering; /*!< Which distinctivering to use */
1146
int cidrings; /*!< Which ring to deliver CID on */
1147
int dtmfrelax; /*!< whether to run in relaxed DTMF mode */
1148
/*! \brief Holding place for event injected from outside normal operation. */
1151
* \brief Minimal time period (ms) between the answer polarity
1152
* switch and hangup polarity switch.
1154
int polarityonanswerdelay;
1155
/*! \brief Start delay time if polarityonanswerdelay is nonzero. */
1156
struct timeval polaritydelaytv;
1158
* \brief Send caller ID after this many rings.
1159
* \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
1161
int sendcalleridafter;
1163
/*! \brief DAHDI PRI control parameters */
1164
struct dahdi_pri *pri;
1165
/*! \brief XXX Purpose??? */
1166
struct dahdi_pvt *bearer;
1167
/*! \brief XXX Purpose??? */
1168
struct dahdi_pvt *realcall;
1169
/*! \brief Opaque libpri call control structure */
1171
/*! \brief Channel number in span. */
1173
/*! \brief Logical span number within trunk group */
1176
/*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
1178
/*! \brief DSP feature flags: DSP_FEATURE_xxx */
1181
/*! \brief SS7 control parameters */
1182
struct dahdi_ss7 *ss7;
1183
/*! \brief Opaque libss7 call control structure */
1184
struct isup_call *ss7call;
1185
char charge_number[50];
1186
char gen_add_number[50];
1187
char gen_dig_number[50];
1188
char orig_called_num[50];
1189
char redirecting_num[50];
1190
char generic_name[50];
1191
unsigned char gen_add_num_plan;
1192
unsigned char gen_add_nai;
1193
unsigned char gen_add_pres_ind;
1194
unsigned char gen_add_type;
1195
unsigned char gen_dig_type;
1196
unsigned char gen_dig_scheme;
1197
char jip_number[50];
1198
unsigned char lspi_type;
1199
unsigned char lspi_scheme;
1200
unsigned char lspi_context;
1201
char lspi_ident[50];
1202
unsigned int call_ref_ident;
1203
unsigned int call_ref_pc;
1204
unsigned char calling_party_cat;
1206
int cic; /*!< CIC associated with channel */
1207
unsigned int dpc; /*!< CIC's DPC */
1208
unsigned int loopedback:1;
1211
struct dahdi_mfcr2 *mfcr2;
1212
openr2_chan_t *r2chan;
1213
openr2_calling_party_category_t mfcr2_recvd_category;
1214
openr2_calling_party_category_t mfcr2_category;
1215
int mfcr2_dnis_index;
1216
int mfcr2_ani_index;
1218
int mfcr2_answer_pending:1;
1219
int mfcr2_charge_calls:1;
1220
int mfcr2_allow_collect_calls:1;
1221
int mfcr2_forced_release:1;
1222
int mfcr2_dnis_matched:1;
1223
int mfcr2_call_accepted:1;
1224
int mfcr2_accept_on_offer:1;
1226
/*! \brief DTMF digit in progress. 0 when no digit in progress. */
1228
/*! \brief TRUE if confrence is muted. */
1230
} *iflist = NULL, *ifend = NULL;
1232
/*! \brief Channel configuration from chan_dahdi.conf .
1233
* This struct is used for parsing the [channels] section of chan_dahdi.conf.
1234
* Generally there is a field here for every possible configuration item.
1236
* The state of fields is saved along the parsing and whenever a 'channel'
1237
* statement is reached, the current dahdi_chan_conf is used to configure the
1238
* channel (struct dahdi_pvt)
1240
* \see dahdi_chan_init for the default values.
1242
struct dahdi_chan_conf {
1243
struct dahdi_pvt chan;
1245
struct dahdi_pri pri;
1249
struct dahdi_ss7 ss7;
1253
struct dahdi_mfcr2_conf mfcr2;
1255
struct dahdi_params timing;
1256
int is_sig_auto; /*!< Use channel signalling from DAHDI? */
1259
* \brief The serial port to listen for SMDI data on
1260
* \note Set from the "smdiport" string read in from chan_dahdi.conf
1262
char smdi_port[SMDI_MAX_FILENAME_LEN];
1265
/*! returns a new dahdi_chan_conf with default values (by-value) */
1266
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
1268
/* recall that if a field is not included here it is initialized
1269
* to 0 or equivalent
1271
struct dahdi_chan_conf conf = {
1274
.nsf = PRI_NSF_NONE,
1275
.switchtype = PRI_SWITCH_NI2,
1276
.dialplan = PRI_UNKNOWN + 1,
1277
.localdialplan = PRI_NATIONAL_ISDN + 1,
1278
.nodetype = PRI_CPE,
1279
.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
1284
.internationalprefix = "",
1285
.nationalprefix = "",
1287
.privateprefix = "",
1288
.unknownprefix = "",
1289
.resetinterval = -1,
1294
.called_nai = SS7_NAI_NATIONAL,
1295
.calling_nai = SS7_NAI_NATIONAL,
1296
.internationalprefix = "",
1297
.nationalprefix = "",
1298
.subscriberprefix = "",
1304
.variant = OR2_VAR_ITU,
1305
.mfback_timeout = -1,
1306
.metering_pulse_timeout = -1,
1309
.get_ani_first = -1,
1310
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1311
.skip_category_request = -1,
1314
.allow_collect_calls = 0,
1316
.accept_on_offer = 1,
1317
.forced_release = 0,
1319
.immediate_accept = -1,
1322
.loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1323
.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1327
.context = "default",
1330
.mohinterpret = "default",
1333
.transfertobusy = 1,
1335
.cid_signalling = CID_SIG_BELL,
1336
.cid_start = CID_START_RING,
1337
.dahditrcallerid = 0,
1346
.echocancel.head.tap_length = 1,
1354
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1357
.polarityonanswerdelay = 600,
1359
.sendcalleridafter = DEFAULT_CIDRINGS,
1361
.buf_policy = DAHDI_POLICY_IMMEDIATE,
1364
.faxbuf_policy = DAHDI_POLICY_IMMEDIATE,
1365
.faxbuf_no = numbufs,
1378
.smdi_port = "/dev/ttyS0",
1385
static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause);
1386
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
1387
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
1388
static int dahdi_sendtext(struct ast_channel *c, const char *text);
1389
static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
1390
static int dahdi_hangup(struct ast_channel *ast);
1391
static int dahdi_answer(struct ast_channel *ast);
1392
static struct ast_frame *dahdi_read(struct ast_channel *ast);
1393
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
1394
static struct ast_frame *dahdi_exception(struct ast_channel *ast);
1395
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
1396
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1397
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1398
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
1399
static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event);
1401
static const struct ast_channel_tech dahdi_tech = {
1403
.description = tdesc,
1404
.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
1405
.requester = dahdi_request,
1406
.send_digit_begin = dahdi_digit_begin,
1407
.send_digit_end = dahdi_digit_end,
1408
.send_text = dahdi_sendtext,
1410
.hangup = dahdi_hangup,
1411
.answer = dahdi_answer,
1413
.write = dahdi_write,
1414
.bridge = dahdi_bridge,
1415
.exception = dahdi_exception,
1416
.indicate = dahdi_indicate,
1417
.fixup = dahdi_fixup,
1418
.setoption = dahdi_setoption,
1419
.func_channel_read = dahdi_func_read,
1423
#define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
1425
#define GET_CHANNEL(p) ((p)->channel)
1428
struct dahdi_pvt *round_robin[32];
1430
#if defined(HAVE_PRI)
1431
static inline int pri_grab(struct dahdi_pvt *pvt, struct dahdi_pri *pri)
1434
/* Grab the lock first */
1436
res = ast_mutex_trylock(&pri->lock);
1438
DEADLOCK_AVOIDANCE(&pvt->lock);
1441
/* Then break the poll */
1442
if (pri->master != AST_PTHREADT_NULL)
1443
pthread_kill(pri->master, SIGURG);
1446
#endif /* defined(HAVE_PRI) */
1448
#if defined(HAVE_SS7)
1449
static inline void ss7_rel(struct dahdi_ss7 *ss7)
1451
ast_mutex_unlock(&ss7->lock);
1453
#endif /* defined(HAVE_SS7) */
1455
#if defined(HAVE_SS7)
1456
static inline int ss7_grab(struct dahdi_pvt *pvt, struct dahdi_ss7 *pri)
1459
/* Grab the lock first */
1461
res = ast_mutex_trylock(&pri->lock);
1463
DEADLOCK_AVOIDANCE(&pvt->lock);
1466
/* Then break the poll */
1467
if (pri->master != AST_PTHREADT_NULL)
1468
pthread_kill(pri->master, SIGURG);
1471
#endif /* defined(HAVE_SS7) */
1472
#define NUM_CADENCE_MAX 25
1473
static int num_cadence = 4;
1474
static int user_has_defined_cadences = 0;
1476
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
1477
{ { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
1478
{ { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
1479
{ { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
1480
{ { 1000, 500, 2500, 5000 } }, /*!< Long ring */
1483
/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
1484
* is 1, the second pause is 2 and so on.
1487
static int cidrings[NUM_CADENCE_MAX] = {
1488
2, /*!< Right after first long ring */
1489
4, /*!< Right after long part */
1490
3, /*!< After third chirp */
1491
2, /*!< Second spell */
1494
/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
1495
static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
1497
#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
1498
(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
1500
#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
1501
#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
1503
static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok)
1506
if (p->subs[SUB_REAL].owner == ast)
1508
else if (p->subs[SUB_CALLWAIT].owner == ast)
1510
else if (p->subs[SUB_THREEWAY].owner == ast)
1515
ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
1520
static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri)
1524
ast_mutex_unlock(&pri->lock);
1527
if (p->subs[a].owner) {
1528
if (ast_channel_trylock(p->subs[a].owner)) {
1529
DEADLOCK_AVOIDANCE(&p->lock);
1531
ast_queue_frame(p->subs[a].owner, &ast_null_frame);
1532
ast_channel_unlock(p->subs[a].owner);
1540
ast_mutex_lock(&pri->lock);
1544
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f, void *data)
1547
struct dahdi_pri *pri = (struct dahdi_pri*) data;
1550
struct dahdi_ss7 *ss7 = (struct dahdi_ss7*) data;
1552
/* We must unlock the PRI to avoid the possibility of a deadlock */
1553
#if defined(HAVE_PRI) || defined(HAVE_SS7)
1560
ast_mutex_unlock(&pri->lock);
1565
ast_mutex_unlock(&ss7->lock);
1575
if (ast_channel_trylock(p->owner)) {
1576
DEADLOCK_AVOIDANCE(&p->lock);
1578
ast_queue_frame(p->owner, f);
1579
ast_channel_unlock(p->owner);
1585
#if defined(HAVE_PRI) || defined(HAVE_SS7)
1592
ast_mutex_lock(&pri->lock);
1597
ast_mutex_lock(&ss7->lock);
1607
static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
1610
static int dahdi_r2_answer(struct dahdi_pvt *p)
1613
/* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
1614
* and does not has support for openr2_chan_answer_call_with_mode
1616
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1617
const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
1618
int wants_double_answer = ast_true(double_answer) ? 1 : 0;
1619
if (!double_answer) {
1620
/* this still can result in double answer if the channel context
1621
* was configured that way */
1622
res = openr2_chan_answer_call(p->r2chan);
1623
} else if (wants_double_answer) {
1624
res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
1626
res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
1629
res = openr2_chan_answer_call(p->r2chan);
1636
/* should be called with the ast_channel locked */
1637
static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
1639
openr2_calling_party_category_t cat;
1640
const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
1641
struct dahdi_pvt *p = c->tech_pvt;
1642
if (ast_strlen_zero(catstr)) {
1643
ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
1644
c->name, openr2_proto_get_category_string(p->mfcr2_category));
1645
return p->mfcr2_category;
1647
if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
1648
ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
1649
catstr, c->name, openr2_proto_get_category_string(p->mfcr2_category));
1650
return p->mfcr2_category;
1652
ast_debug(1, "Using category %s\n", catstr);
1656
static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
1658
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1659
ast_mutex_lock(&p->lock);
1661
ast_mutex_unlock(&p->lock);
1662
/* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
1663
interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
1664
can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
1665
the other end will see our seize as a forced release and drop the call, we will see an invalid
1666
pattern that will be seen and treated as protocol error. */
1667
ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
1671
/* better safe than sorry ... */
1672
p->cid_name[0] = '\0';
1673
p->cid_num[0] = '\0';
1676
p->mfcr2_ani_index = '\0';
1677
p->mfcr2_dnis_index = '\0';
1678
p->mfcr2_dnis_matched = 0;
1679
p->mfcr2_answer_pending = 0;
1680
p->mfcr2_call_accepted = 0;
1681
ast_mutex_unlock(&p->lock);
1682
ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
1685
static int get_alarms(struct dahdi_pvt *p);
1686
static void handle_alarms(struct dahdi_pvt *p, int alms);
1687
static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
1690
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1691
ast_mutex_lock(&p->lock);
1692
p->inalarm = alarm ? 1 : 0;
1694
res = get_alarms(p);
1695
handle_alarms(p, res);
1697
ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
1698
manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
1700
ast_mutex_unlock(&p->lock);
1703
static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
1705
ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
1708
static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
1710
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1711
ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
1713
p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR;
1714
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
1716
ast_mutex_lock(&p->lock);
1718
ast_mutex_unlock(&p->lock);
1721
static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
1723
if (openr2_chan_disconnect_call(p->r2chan, cause)) {
1724
ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
1725
p->channel, openr2_proto_get_disconnect_string(cause));
1726
/* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
1727
openr2_chan_set_idle(p->r2chan);
1728
ast_mutex_lock(&p->lock);
1730
ast_mutex_unlock(&p->lock);
1734
static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
1736
struct dahdi_pvt *p;
1737
struct ast_channel *c;
1738
ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
1739
openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
1740
openr2_proto_get_category_string(category));
1741
p = openr2_chan_get_client_data(r2chan);
1742
/* if collect calls are not allowed and this is a collect call, reject it! */
1743
if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
1744
ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
1745
dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
1748
ast_mutex_lock(&p->lock);
1749
p->mfcr2_recvd_category = category;
1750
/* if we're not supposed to use CID, clear whatever we have */
1751
if (!p->use_callerid) {
1752
ast_log(LOG_DEBUG, "No CID allowed in configuration, CID is being cleared!\n");
1756
/* if we're supposed to answer immediately, clear DNIS and set 's' exten */
1757
if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
1758
ast_log(LOG_DEBUG, "Setting exten => s because of immediate or 0 DNIS configured\n");
1762
ast_mutex_unlock(&p->lock);
1763
if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
1764
ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
1765
p->channel, p->exten, p->context);
1766
dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
1769
if (!p->mfcr2_accept_on_offer) {
1770
/* The user wants us to start the PBX thread right away without accepting the call first */
1771
c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
1773
/* Done here, don't disable reading now since we still need to generate MF tones to accept
1774
the call or reject it and detect the tone off condition of the other end, all of this
1775
will be done in the PBX thread now */
1778
ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
1779
dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
1780
} else if (p->mfcr2_charge_calls) {
1781
ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
1782
openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
1784
ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
1785
openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
1789
static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
1791
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1792
ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
1793
ast_mutex_lock(&p->lock);
1795
ast_mutex_unlock(&p->lock);
1798
static void dahdi_enable_ec(struct dahdi_pvt *p);
1799
static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
1801
struct dahdi_pvt *p = NULL;
1802
struct ast_channel *c = NULL;
1803
p = openr2_chan_get_client_data(r2chan);
1805
p->mfcr2_call_accepted = 1;
1806
/* if it's an incoming call ... */
1807
if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
1808
ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
1809
/* If accept on offer is not set, it means at this point the PBX thread is already
1810
launched (was launched in the 'on call offered' handler) and therefore this callback
1811
is being executed already in the PBX thread rather than the monitor thread, don't launch
1812
any other thread, just disable the openr2 reading and answer the call if needed */
1813
if (!p->mfcr2_accept_on_offer) {
1814
openr2_chan_disable_read(r2chan);
1815
if (p->mfcr2_answer_pending) {
1816
ast_log(LOG_DEBUG, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
1821
c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
1823
/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
1824
library to forget about it */
1825
openr2_chan_disable_read(r2chan);
1828
ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
1829
/* failed to create the channel, bail out and report it as an out of order line */
1830
dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
1833
/* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
1834
ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
1835
p->subs[SUB_REAL].needringing = 1;
1837
/* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
1838
openr2_chan_disable_read(r2chan);
1841
static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
1843
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1844
ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
1845
p->subs[SUB_REAL].needanswer = 1;
1848
static void dahdi_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
1850
/*ast_log(LOG_DEBUG, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/
1853
static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
1856
case OR2_CAUSE_BUSY_NUMBER:
1857
return AST_CAUSE_BUSY;
1858
case OR2_CAUSE_NETWORK_CONGESTION:
1859
return AST_CAUSE_CONGESTION;
1860
case OR2_CAUSE_OUT_OF_ORDER:
1861
return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
1862
case OR2_CAUSE_UNALLOCATED_NUMBER:
1863
return AST_CAUSE_UNREGISTERED;
1864
case OR2_CAUSE_NO_ANSWER:
1865
return AST_CAUSE_NO_ANSWER;
1866
case OR2_CAUSE_NORMAL_CLEARING:
1867
return AST_CAUSE_NORMAL_CLEARING;
1868
case OR2_CAUSE_UNSPECIFIED:
1870
return AST_CAUSE_NOTDEFINED;
1874
static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
1876
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1877
ast_verbose("MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
1878
ast_mutex_lock(&p->lock);
1880
ast_mutex_unlock(&p->lock);
1881
/* no owner, therefore we can't use dahdi_hangup to disconnect, do it right now */
1882
dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
1885
/* when we have an owner we don't call dahdi_r2_disconnect_call here, that will
1886
be done in dahdi_hangup */
1887
if (p->owner->_state == AST_STATE_UP) {
1888
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
1889
ast_mutex_unlock(&p->lock);
1890
} else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
1891
/* being the forward side we must report what happened to the call to whoever requested it */
1893
case OR2_CAUSE_BUSY_NUMBER:
1894
p->subs[SUB_REAL].needbusy = 1;
1896
case OR2_CAUSE_NETWORK_CONGESTION:
1897
case OR2_CAUSE_OUT_OF_ORDER:
1898
case OR2_CAUSE_UNALLOCATED_NUMBER:
1899
case OR2_CAUSE_NO_ANSWER:
1900
case OR2_CAUSE_UNSPECIFIED:
1901
case OR2_CAUSE_NORMAL_CLEARING:
1902
p->subs[SUB_REAL].needcongestion = 1;
1905
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
1907
ast_mutex_unlock(&p->lock);
1909
ast_mutex_unlock(&p->lock);
1910
/* being the backward side and not UP yet, we only need to request hangup */
1911
/* TODO: what about doing this same thing when were AST_STATE_UP? */
1912
ast_queue_hangup_with_cause(p->owner, dahdi_r2_cause_to_ast_cause(cause));
1916
static void dahdi_r2_write_log(openr2_log_level_t level, char *logmessage)
1919
case OR2_LOG_NOTICE:
1920
ast_verbose("%s", logmessage);
1922
case OR2_LOG_WARNING:
1923
ast_log(LOG_WARNING, "%s", logmessage);
1926
ast_log(LOG_ERROR, "%s", logmessage);
1928
case OR2_LOG_STACK_TRACE:
1929
case OR2_LOG_MF_TRACE:
1930
case OR2_LOG_CAS_TRACE:
1932
case OR2_LOG_EX_DEBUG:
1933
ast_log(LOG_DEBUG, "%s", logmessage);
1936
ast_log(LOG_WARNING, "We should handle logging level %d here.\n", level);
1937
ast_log(LOG_DEBUG, "%s", logmessage);
1942
static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
1944
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1945
ast_mutex_lock(&p->lock);
1946
p->remotelyblocked = 1;
1947
ast_mutex_unlock(&p->lock);
1948
ast_log(LOG_NOTICE, "Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
1951
static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
1953
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1954
ast_mutex_lock(&p->lock);
1955
p->remotelyblocked = 0;
1956
ast_mutex_unlock(&p->lock);
1957
ast_log(LOG_NOTICE, "Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
1960
static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
1961
__attribute__((format (printf, 3, 0)));
1962
static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level, const char *fmt, va_list ap)
1964
#define CONTEXT_TAG "Context - "
1966
char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1];
1967
vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
1968
snprintf(completemsg, sizeof(completemsg), CONTEXT_TAG "%s", logmsg);
1969
dahdi_r2_write_log(level, completemsg);
1973
static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
1974
__attribute__((format (printf, 3, 0)));
1975
static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level, const char *fmt, va_list ap)
1977
#define CHAN_TAG "Chan "
1979
char completemsg[sizeof(logmsg) + sizeof(CHAN_TAG) - 1];
1980
vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
1981
snprintf(completemsg, sizeof(completemsg), CHAN_TAG "%d - %s", openr2_chan_get_number(r2chan), logmsg);
1982
dahdi_r2_write_log(level, completemsg);
1985
static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
1987
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
1988
/* if 'immediate' is set, let's stop requesting DNIS */
1992
p->exten[p->mfcr2_dnis_index] = digit;
1993
p->rdnis[p->mfcr2_dnis_index] = digit;
1994
p->mfcr2_dnis_index++;
1995
p->exten[p->mfcr2_dnis_index] = 0;
1996
p->rdnis[p->mfcr2_dnis_index] = 0;
1997
/* if the DNIS is a match and cannot match more, stop requesting DNIS */
1998
if ((p->mfcr2_dnis_matched ||
1999
(ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num) && (p->mfcr2_dnis_matched = 1))) &&
2000
!ast_matchmore_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
2003
/* otherwise keep going */
2007
static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan, char digit)
2009
struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
2010
p->cid_num[p->mfcr2_ani_index] = digit;
2011
p->cid_name[p->mfcr2_ani_index] = digit;
2012
p->mfcr2_ani_index++;
2013
p->cid_num[p->mfcr2_ani_index] = 0;
2014
p->cid_name[p->mfcr2_ani_index] = 0;
2017
static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
2019
ast_verbose("MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
2022
static openr2_event_interface_t dahdi_r2_event_iface = {
2023
.on_call_init = dahdi_r2_on_call_init,
2024
.on_call_offered = dahdi_r2_on_call_offered,
2025
.on_call_accepted = dahdi_r2_on_call_accepted,
2026
.on_call_answered = dahdi_r2_on_call_answered,
2027
.on_call_disconnect = dahdi_r2_on_call_disconnect,
2028
.on_call_end = dahdi_r2_on_call_end,
2029
.on_call_read = dahdi_r2_on_call_read,
2030
.on_hardware_alarm = dahdi_r2_on_hardware_alarm,
2031
.on_os_error = dahdi_r2_on_os_error,
2032
.on_protocol_error = dahdi_r2_on_protocol_error,
2033
.on_line_blocked = dahdi_r2_on_line_blocked,
2034
.on_line_idle = dahdi_r2_on_line_idle,
2035
/* cast seems to be needed to get rid of the annoying warning regarding format attribute */
2036
.on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
2037
.on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
2038
.on_ani_digit_received = dahdi_r2_on_ani_digit_received,
2039
/* so far we do nothing with billing pulses */
2040
.on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
2043
static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
2045
return AST_ALAW(sample);
2048
static inline uint8_t dahdi_r2_linear_to_alaw(int sample)
2050
return AST_LIN2A(sample);
2053
static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
2054
dahdi_r2_alaw_to_linear,
2055
dahdi_r2_linear_to_alaw
2058
#endif /* HAVE_OPENR2 */
2060
static int restore_gains(struct dahdi_pvt *p);
2062
static void swap_subs(struct dahdi_pvt *p, int a, int b)
2066
struct ast_channel *towner;
2068
ast_debug(1, "Swapping %d and %d\n", a, b);
2070
tchan = p->subs[a].chan;
2071
towner = p->subs[a].owner;
2072
tinthreeway = p->subs[a].inthreeway;
2074
p->subs[a].chan = p->subs[b].chan;
2075
p->subs[a].owner = p->subs[b].owner;
2076
p->subs[a].inthreeway = p->subs[b].inthreeway;
2078
p->subs[b].chan = tchan;
2079
p->subs[b].owner = towner;
2080
p->subs[b].inthreeway = tinthreeway;
2082
if (p->subs[a].owner)
2083
ast_channel_set_fd(p->subs[a].owner, 0, p->subs[a].dfd);
2084
if (p->subs[b].owner)
2085
ast_channel_set_fd(p->subs[b].owner, 0, p->subs[b].dfd);
2086
wakeup_sub(p, a, NULL);
2087
wakeup_sub(p, b, NULL);
2090
static int dahdi_open(char *fn)
2098
for (x = 0; x < strlen(fn); x++) {
2099
if (!isdigit(fn[x])) {
2107
ast_log(LOG_WARNING, "Invalid channel number '%s'\n", fn);
2110
fn = "/dev/dahdi/channel";
2112
fd = open(fn, O_RDWR | O_NONBLOCK);
2114
ast_log(LOG_WARNING, "Unable to open '%s': %s\n", fn, strerror(errno));
2118
if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
2122
ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
2127
if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs) == -1) {
2128
ast_log(LOG_WARNING, "Unable to set blocksize '%d': %s\n", bs, strerror(errno));
2137
static void dahdi_close(int fd)
2143
static void dahdi_close_sub(struct dahdi_pvt *chan_pvt, int sub_num)
2145
dahdi_close(chan_pvt->subs[sub_num].dfd);
2146
chan_pvt->subs[sub_num].dfd = -1;
2149
#if defined(HAVE_PRI)
2150
static void dahdi_close_pri_fd(struct dahdi_pri *pri, int fd_num)
2152
dahdi_close(pri->fds[fd_num]);
2153
pri->fds[fd_num] = -1;
2155
#endif /* defined(HAVE_PRI) */
2157
#if defined(HAVE_SS7)
2158
static void dahdi_close_ss7_fd(struct dahdi_ss7 *ss7, int fd_num)
2160
dahdi_close(ss7->fds[fd_num]);
2161
ss7->fds[fd_num] = -1;
2163
#endif /* defined(HAVE_SS7) */
2165
static int dahdi_setlinear(int dfd, int linear)
2168
res = ioctl(dfd, DAHDI_SETLINEAR, &linear);
2175
static int alloc_sub(struct dahdi_pvt *p, int x)
2177
struct dahdi_bufferinfo bi;
2179
if (p->subs[x].dfd >= 0) {
2180
ast_log(LOG_WARNING, "%s subchannel of %d already in use\n", subnames[x], p->channel);
2184
p->subs[x].dfd = dahdi_open("/dev/dahdi/pseudo");
2185
if (p->subs[x].dfd <= -1) {
2186
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
2190
res = ioctl(p->subs[x].dfd, DAHDI_GET_BUFINFO, &bi);
2192
bi.txbufpolicy = p->buf_policy;
2193
bi.rxbufpolicy = p->buf_policy;
2194
bi.numbufs = p->buf_no;
2195
res = ioctl(p->subs[x].dfd, DAHDI_SET_BUFINFO, &bi);
2197
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", x, strerror(errno));
2200
ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", x, strerror(errno));
2202
if (ioctl(p->subs[x].dfd, DAHDI_CHANNO, &p->subs[x].chan) == 1) {
2203
ast_log(LOG_WARNING, "Unable to get channel number for pseudo channel on FD %d: %s\n", p->subs[x].dfd, strerror(errno));
2204
dahdi_close_sub(p, x);
2205
p->subs[x].dfd = -1;
2208
ast_debug(1, "Allocated %s subchannel on FD %d channel %d\n", subnames[x], p->subs[x].dfd, p->subs[x].chan);
2212
static int unalloc_sub(struct dahdi_pvt *p, int x)
2215
ast_log(LOG_WARNING, "Trying to unalloc the real channel %d?!?\n", p->channel);
2218
ast_debug(1, "Released sub %d of channel %d\n", x, p->channel);
2219
dahdi_close_sub(p, x);
2220
p->subs[x].linear = 0;
2221
p->subs[x].chan = 0;
2222
p->subs[x].owner = NULL;
2223
p->subs[x].inthreeway = 0;
2224
p->polarity = POLARITY_IDLE;
2225
memset(&p->subs[x].curconf, 0, sizeof(p->subs[x].curconf));
2229
static int digit_to_dtmfindex(char digit)
2232
return DAHDI_TONE_DTMF_BASE + (digit - '0');
2233
else if (digit >= 'A' && digit <= 'D')
2234
return DAHDI_TONE_DTMF_A + (digit - 'A');
2235
else if (digit >= 'a' && digit <= 'd')
2236
return DAHDI_TONE_DTMF_A + (digit - 'a');
2237
else if (digit == '*')
2238
return DAHDI_TONE_DTMF_s;
2239
else if (digit == '#')
2240
return DAHDI_TONE_DTMF_p;
2245
static int dahdi_digit_begin(struct ast_channel *chan, char digit)
2247
struct dahdi_pvt *pvt;
2251
pvt = chan->tech_pvt;
2253
ast_mutex_lock(&pvt->lock);
2255
idx = dahdi_get_index(chan, pvt, 0);
2257
if ((idx != SUB_REAL) || !pvt->owner)
2261
if (((pvt->sig == SIG_PRI) || (pvt->sig == SIG_BRI) || (pvt->sig == SIG_BRI_PTMP))
2262
&& (chan->_state == AST_STATE_DIALING) && !pvt->proceeding) {
2263
if (pvt->setup_ack) {
2264
if (!pri_grab(pvt, pvt->pri)) {
2265
pri_information(pvt->pri->pri, pvt->call, digit);
2268
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", pvt->span);
2269
} else if (strlen(pvt->dialdest) < sizeof(pvt->dialdest) - 1) {
2271
ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n", digit);
2272
res = strlen(pvt->dialdest);
2273
pvt->dialdest[res++] = digit;
2274
pvt->dialdest[res] = '\0';
2279
if ((dtmf = digit_to_dtmfindex(digit)) == -1)
2282
if (pvt->pulse || ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &dtmf)) {
2284
struct dahdi_dialoperation zo = {
2285
.op = DAHDI_DIAL_OP_APPEND,
2288
zo.dialstr[0] = 'T';
2289
zo.dialstr[1] = digit;
2290
zo.dialstr[2] = '\0';
2291
if ((res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_DIAL, &zo)))
2292
ast_log(LOG_WARNING, "Couldn't dial digit %c: %s\n", digit, strerror(errno));
2296
ast_debug(1, "Started VLDTMF digit '%c'\n", digit);
2298
pvt->begindigit = digit;
2302
ast_mutex_unlock(&pvt->lock);
2307
static int dahdi_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
2309
struct dahdi_pvt *pvt;
2314
pvt = chan->tech_pvt;
2316
ast_mutex_lock(&pvt->lock);
2318
idx = dahdi_get_index(chan, pvt, 0);
2320
if ((idx != SUB_REAL) || !pvt->owner || pvt->pulse)
2324
/* This means that the digit was already sent via PRI signalling */
2325
if (((pvt->sig == SIG_PRI) || (pvt->sig == SIG_BRI) || (pvt->sig == SIG_BRI_PTMP))
2326
&& !pvt->begindigit)
2330
if (pvt->begindigit) {
2332
ast_debug(1, "Ending VLDTMF digit '%c'\n", digit);
2333
res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SENDTONE, &x);
2335
pvt->begindigit = 0;
2339
ast_mutex_unlock(&pvt->lock);
2344
static char *events[] = {
2357
"Hook Transition Complete",
2362
"Polarity Reversal",
2370
{ DAHDI_ALARM_RED, "Red Alarm" },
2371
{ DAHDI_ALARM_YELLOW, "Yellow Alarm" },
2372
{ DAHDI_ALARM_BLUE, "Blue Alarm" },
2373
{ DAHDI_ALARM_RECOVER, "Recovering" },
2374
{ DAHDI_ALARM_LOOPBACK, "Loopback" },
2375
{ DAHDI_ALARM_NOTOPEN, "Not Open" },
2376
{ DAHDI_ALARM_NONE, "None" },
2379
static char *alarm2str(int alm)
2382
for (x = 0; x < ARRAY_LEN(alarms); x++) {
2383
if (alarms[x].alarm & alm)
2384
return alarms[x].name;
2386
return alm ? "Unknown Alarm" : "No Alarm";
2389
static char *event2str(int event)
2391
static char buf[256];
2392
if ((event < (ARRAY_LEN(events))) && (event > -1))
2393
return events[event];
2394
sprintf(buf, "Event %d", event); /* safe */
2399
static char *dialplan2str(int dialplan)
2401
if (dialplan == -1 || dialplan == -2) {
2402
return("Dynamically set dialplan in ISDN");
2404
return (pri_plan2str(dialplan));
2408
static char *dahdi_sig2str(int sig)
2410
static char buf[256];
2413
return "E & M Immediate";
2415
return "E & M Wink";
2419
return "Feature Group D (DTMF)";
2421
return "Feature Group D (MF)";
2422
case SIG_FEATDMF_TA:
2423
return "Feature Groud D (MF) Tandem Access";
2425
return "Feature Group B (MF)";
2429
return "FGC/CAMA (Dialpulse)";
2430
case SIG_FGC_CAMAMF:
2431
return "FGC/CAMA (MF)";
2433
return "FXS Loopstart";
2435
return "FXS Groundstart";
2437
return "FXS Kewlstart";
2439
return "FXO Loopstart";
2441
return "FXO Groundstart";
2443
return "FXO Kewlstart";
2447
return "ISDN BRI Point to Point";
2449
return "ISDN BRI Point to MultiPoint";
2455
return "SF (Tone) Immediate";
2457
return "SF (Tone) Wink";
2459
return "SF (Tone) with Feature Group D (DTMF)";
2460
case SIG_SF_FEATDMF:
2461
return "SF (Tone) with Feature Group D (MF)";
2463
return "SF (Tone) with Feature Group B (MF)";
2464
case SIG_GR303FXOKS:
2465
return "GR-303 with FXOKS";
2466
case SIG_GR303FXSKS:
2467
return "GR-303 with FXSKS";
2471
snprintf(buf, sizeof(buf), "Unknown signalling %d", sig);
2476
#define sig2str dahdi_sig2str
2478
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx, int slavechannel)
2480
/* If the conference already exists, and we're already in it
2481
don't bother doing anything */
2482
struct dahdi_confinfo zi;
2484
memset(&zi, 0, sizeof(zi));
2487
if (slavechannel > 0) {
2488
/* If we have only one slave, do a digital mon */
2489
zi.confmode = DAHDI_CONF_DIGITALMON;
2490
zi.confno = slavechannel;
2493
/* Real-side and pseudo-side both participate in conference */
2494
zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
2495
DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
2497
zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
2498
zi.confno = p->confno;
2500
if ((zi.confno == c->curconf.confno) && (zi.confmode == c->curconf.confmode))
2504
if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
2505
ast_log(LOG_WARNING, "Failed to add %d to conference %d/%d: %s\n", c->dfd, zi.confmode, zi.confno, strerror(errno));
2508
if (slavechannel < 1) {
2509
p->confno = zi.confno;
2511
memcpy(&c->curconf, &zi, sizeof(c->curconf));
2512
ast_debug(1, "Added %d to conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
2516
static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
2518
/* If they're listening to our channel, they're ours */
2519
if ((p->channel == c->curconf.confno) && (c->curconf.confmode == DAHDI_CONF_DIGITALMON))
2521
/* If they're a talker on our (allocated) conference, they're ours */
2522
if ((p->confno > 0) && (p->confno == c->curconf.confno) && (c->curconf.confmode & DAHDI_CONF_TALKER))
2527
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx)
2529
struct dahdi_confinfo zi;
2530
if (/* Can't delete if there's no dfd */
2532
/* Don't delete from the conference if it's not our conference */
2534
/* Don't delete if we don't think it's conferenced at all (implied) */
2536
memset(&zi, 0, sizeof(zi));
2537
if (ioctl(c->dfd, DAHDI_SETCONF, &zi)) {
2538
ast_log(LOG_WARNING, "Failed to drop %d from conference %d/%d: %s\n", c->dfd, c->curconf.confmode, c->curconf.confno, strerror(errno));
2541
ast_debug(1, "Removed %d from conference %d/%d\n", c->dfd, c->curconf.confmode, c->curconf.confno);
2542
memcpy(&c->curconf, &zi, sizeof(c->curconf));
2546
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
2550
struct dahdi_pvt *slave = NULL;
2551
/* Start out optimistic */
2553
/* Update conference state in a stateless fashion */
2554
for (x = 0; x < 3; x++) {
2555
/* Any three-way calling makes slave native mode *definitely* out
2557
if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway)
2560
/* If we don't have any 3-way calls, check to see if we have
2561
precisely one slave */
2562
if (useslavenative) {
2563
for (x = 0; x < MAX_SLAVES; x++) {
2566
/* Whoops already have a slave! No
2567
slave native and stop right away */
2572
/* We have one slave so far */
2573
slave = p->slaves[x];
2578
/* If no slave, slave native definitely out */
2581
else if (slave->law != p->law) {
2587
return useslavenative;
2590
static int reset_conf(struct dahdi_pvt *p)
2593
memset(&p->subs[SUB_REAL].curconf, 0, sizeof(p->subs[SUB_REAL].curconf));
2594
if (p->subs[SUB_REAL].dfd > -1) {
2595
struct dahdi_confinfo zi;
2597
memset(&zi, 0, sizeof(zi));
2598
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &zi))
2599
ast_log(LOG_WARNING, "Failed to reset conferencing on channel %d: %s\n", p->channel, strerror(errno));
2604
static int update_conf(struct dahdi_pvt *p)
2609
struct dahdi_pvt *slave = NULL;
2611
useslavenative = isslavenative(p, &slave);
2612
/* Start with the obvious, general stuff */
2613
for (x = 0; x < 3; x++) {
2614
/* Look for three way calls */
2615
if ((p->subs[x].dfd > -1) && p->subs[x].inthreeway) {
2616
conf_add(p, &p->subs[x], x, 0);
2619
conf_del(p, &p->subs[x], x);
2622
/* If we have a slave, add him to our conference now. or DAX
2623
if this is slave native */
2624
for (x = 0; x < MAX_SLAVES; x++) {
2627
conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2629
conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2634
/* If we're supposed to be in there, do so now */
2635
if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2637
conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2639
conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2643
/* If we have a master, add ourselves to his conference */
2645
if (isslavenative(p->master, NULL)) {
2646
conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
2648
conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2652
/* Nobody is left (or should be left) in our conference.
2656
ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
2660
static void dahdi_enable_ec(struct dahdi_pvt *p)
2667
ast_debug(1, "Echo cancellation already on\n");
2671
ast_debug(1, "Echo cancellation isn't required on digital connection\n");
2674
if (p->echocancel.head.tap_length) {
2675
if ((p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP) || (p->sig == SIG_PRI) || (p->sig == SIG_SS7)) {
2677
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x);
2679
ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
2681
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &p->echocancel);
2683
ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
2686
ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);
2689
ast_debug(1, "No echo cancellation requested\n");
2692
static void dahdi_train_ec(struct dahdi_pvt *p)
2697
if (p && p->echocanon && p->echotraining) {
2698
x = p->echotraining;
2699
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOTRAIN, &x);
2701
ast_log(LOG_WARNING, "Unable to request echo training on channel %d: %s\n", p->channel, strerror(errno));
2703
ast_debug(1, "Engaged echo training on channel %d\n", p->channel);
2705
ast_debug(1, "No echo training requested\n");
2709
static void dahdi_disable_ec(struct dahdi_pvt *p)
2714
struct dahdi_echocanparams ecp = { .tap_length = 0 };
2716
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_ECHOCANCEL_PARAMS, &ecp);
2719
ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d: %s\n", p->channel, strerror(errno));
2721
ast_debug(1, "Disabled echo cancellation on channel %d\n", p->channel);
2727
static void fill_txgain(struct dahdi_gains *g, float gain, int law)
2731
float linear_gain = pow(10.0, gain / 20.0);
2734
case DAHDI_LAW_ALAW:
2735
for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
2737
k = (int) (((float) AST_ALAW(j)) * linear_gain);
2738
if (k > 32767) k = 32767;
2739
if (k < -32767) k = -32767;
2740
g->txgain[j] = AST_LIN2A(k);
2746
case DAHDI_LAW_MULAW:
2747
for (j = 0; j < ARRAY_LEN(g->txgain); j++) {
2749
k = (int) (((float) AST_MULAW(j)) * linear_gain);
2750
if (k > 32767) k = 32767;
2751
if (k < -32767) k = -32767;
2752
g->txgain[j] = AST_LIN2MU(k);
2761
static void fill_rxgain(struct dahdi_gains *g, float gain, int law)
2765
float linear_gain = pow(10.0, gain / 20.0);
2768
case DAHDI_LAW_ALAW:
2769
for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
2771
k = (int) (((float) AST_ALAW(j)) * linear_gain);
2772
if (k > 32767) k = 32767;
2773
if (k < -32767) k = -32767;
2774
g->rxgain[j] = AST_LIN2A(k);
2780
case DAHDI_LAW_MULAW:
2781
for (j = 0; j < ARRAY_LEN(g->rxgain); j++) {
2783
k = (int) (((float) AST_MULAW(j)) * linear_gain);
2784
if (k > 32767) k = 32767;
2785
if (k < -32767) k = -32767;
2786
g->rxgain[j] = AST_LIN2MU(k);
2795
static int set_actual_txgain(int fd, int chan, float gain, int law)
2797
struct dahdi_gains g;
2800
memset(&g, 0, sizeof(g));
2802
res = ioctl(fd, DAHDI_GETGAINS, &g);
2804
ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
2808
fill_txgain(&g, gain, law);
2810
return ioctl(fd, DAHDI_SETGAINS, &g);
2813
static int set_actual_rxgain(int fd, int chan, float gain, int law)
2815
struct dahdi_gains g;
2818
memset(&g, 0, sizeof(g));
2820
res = ioctl(fd, DAHDI_GETGAINS, &g);
2822
ast_debug(1, "Failed to read gains: %s\n", strerror(errno));
2826
fill_rxgain(&g, gain, law);
2828
return ioctl(fd, DAHDI_SETGAINS, &g);
2831
static int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
2833
return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
2836
static int bump_gains(struct dahdi_pvt *p)
2840
/* Bump receive gain by value stored in cid_rxgain */
2841
res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain + p->cid_rxgain, p->txgain, p->law);
2843
ast_log(LOG_WARNING, "Unable to bump gain: %s\n", strerror(errno));
2850
static int restore_gains(struct dahdi_pvt *p)
2854
res = set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
2856
ast_log(LOG_WARNING, "Unable to restore gains: %s\n", strerror(errno));
2863
static inline int dahdi_set_hook(int fd, int hs)
2868
res = ioctl(fd, DAHDI_HOOK, &x);
2871
if (errno == EINPROGRESS)
2873
ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s\n", res, hs, strerror(errno));
2874
/* will expectedly fail if phone is off hook during operation, such as during a restart */
2880
static inline int dahdi_confmute(struct dahdi_pvt *p, int muted)
2884
if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
2886
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &y);
2888
ast_log(LOG_WARNING, "Unable to set audio mode on %d: %s\n", p->channel, strerror(errno));
2890
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_CONFMUTE, &x);
2892
ast_log(LOG_WARNING, "DAHDI confmute(%d) failed on channel %d: %s\n", muted, p->channel, strerror(errno));
2896
static int save_conference(struct dahdi_pvt *p)
2898
struct dahdi_confinfo c;
2900
if (p->saveconf.confmode) {
2901
ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
2904
p->saveconf.chan = 0;
2905
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &p->saveconf);
2907
ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
2908
p->saveconf.confmode = 0;
2911
memset(&c, 0, sizeof(c));
2912
c.confmode = DAHDI_CONF_NORMAL;
2913
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &c);
2915
ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
2918
ast_debug(1, "Disabled conferencing\n");
2923
* \brief Send MWI state change
2925
* \arg mailbox_full This is the mailbox associated with the FXO line that the
2926
* MWI state has changed on.
2927
* \arg thereornot This argument should simply be set to 1 or 0, to indicate
2928
* whether there are messages waiting or not.
2932
* This function does two things:
2934
* 1) It generates an internal Asterisk event notifying any other module that
2935
* cares about MWI that the state of a mailbox has changed.
2937
* 2) It runs the script specified by the mwimonitornotify option to allow
2938
* some custom handling of the state change.
2940
static void notify_message(char *mailbox_full, int thereornot)
2942
char s[sizeof(mwimonitornotify) + 80];
2943
struct ast_event *event;
2944
char *mailbox, *context;
2946
/* Strip off @default */
2947
context = mailbox = ast_strdupa(mailbox_full);
2948
strsep(&context, "@");
2949
if (ast_strlen_zero(context))
2950
context = "default";
2952
if (!(event = ast_event_new(AST_EVENT_MWI,
2953
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
2954
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
2955
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
2956
AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
2957
AST_EVENT_IE_END))) {
2961
ast_event_queue_and_cache(event);
2963
if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
2964
snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
2969
static int restore_conference(struct dahdi_pvt *p)
2972
if (p->saveconf.confmode) {
2973
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCONF, &p->saveconf);
2974
p->saveconf.confmode = 0;
2976
ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
2980
ast_debug(1, "Restored conferencing\n");
2984
static int send_callerid(struct dahdi_pvt *p);
2986
static int send_cwcidspill(struct dahdi_pvt *p)
2990
if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
2992
p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
2993
/* Make sure we account for the end */
2994
p->cidlen += READ_SIZE * 4;
2997
ast_verb(3, "CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p->callwait_name, p->callwait_num);
3001
static int has_voicemail(struct dahdi_pvt *p)
3004
struct ast_event *event;
3005
char *mailbox, *context;
3007
mailbox = context = ast_strdupa(p->mailbox);
3008
strsep(&context, "@");
3009
if (ast_strlen_zero(context))
3010
context = "default";
3012
event = ast_event_get_cached(AST_EVENT_MWI,
3013
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
3014
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
3018
new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
3019
ast_event_destroy(event);
3021
new_msgs = ast_app_has_voicemail(p->mailbox, NULL);
3026
static int send_callerid(struct dahdi_pvt *p)
3028
/* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
3030
/* Take out of linear mode if necessary */
3031
if (p->subs[SUB_REAL].linear) {
3032
p->subs[SUB_REAL].linear = 0;
3033
dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
3035
while (p->cidpos < p->cidlen) {
3036
res = write(p->subs[SUB_REAL].dfd, p->cidspill + p->cidpos, p->cidlen - p->cidpos);
3038
if (errno == EAGAIN)
3041
ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
3049
ast_free(p->cidspill);
3051
if (p->callwaitcas) {
3052
/* Wait for CID/CW to expire */
3053
p->cidcwexpire = CIDCW_EXPIRE_SAMPLES;
3055
restore_conference(p);
3059
static int dahdi_callwait(struct ast_channel *ast)
3061
struct dahdi_pvt *p = ast->tech_pvt;
3062
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
3064
ast_log(LOG_WARNING, "Spill already exists?!?\n");
3065
ast_free(p->cidspill);
3067
if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
3071
memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
3072
if (!p->callwaitrings && p->callwaitingcallerid) {
3073
ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
3075
p->cidlen = 2400 + 680 + READ_SIZE * 4;
3077
ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
3079
p->cidlen = 2400 + READ_SIZE * 4;
3087
#if defined(HAVE_SS7)
3088
static unsigned char cid_pres2ss7pres(int cid_pres)
3090
return (cid_pres >> 5) & 0x03;
3092
#endif /* defined(HAVE_SS7) */
3094
#if defined(HAVE_SS7)
3095
static unsigned char cid_pres2ss7screen(int cid_pres)
3097
return cid_pres & 0x03;
3099
#endif /* defined(HAVE_SS7) */
3101
static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout)
3103
struct dahdi_pvt *p = ast->tech_pvt;
3104
int x, res, idx,mysig;
3109
char dest[256]; /* must be same length as p->dialdest */
3110
ast_mutex_lock(&p->lock);
3111
ast_copy_string(dest, rdest, sizeof(dest));
3112
ast_copy_string(p->dialdest, rdest, sizeof(p->dialdest));
3113
if ((ast->_state == AST_STATE_BUSY)) {
3114
p->subs[SUB_REAL].needbusy = 1;
3115
ast_mutex_unlock(&p->lock);
3118
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
3119
ast_log(LOG_WARNING, "dahdi_call called on %s, neither down nor reserved\n", ast->name);
3120
ast_mutex_unlock(&p->lock);
3123
p->waitingfordt.tv_sec = 0;
3125
if ((p->radio || (p->oprmode < 0))) /* if a radio channel, up immediately */
3127
/* Special pseudo -- automatically up */
3128
ast_setstate(ast, AST_STATE_UP);
3129
ast_mutex_unlock(&p->lock);
3132
x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
3133
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
3135
ast_log(LOG_WARNING, "Unable to flush input on channel %d: %s\n", p->channel, strerror(errno));
3138
if (IS_DIGITAL(ast->transfercapability)){
3139
set_actual_gain(p->subs[SUB_REAL].dfd, 0, 0, 0, p->law);
3141
set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
3145
if (p->outsigmod > -1)
3146
mysig = p->outsigmod;
3152
if (p->owner == ast) {
3153
/* Normal ring, on hook */
3155
/* Don't send audio while on hook, until the call is answered */
3157
if (p->use_callerid) {
3158
/* Generate the Caller-ID spill if desired */
3160
ast_log(LOG_WARNING, "cidspill already exists??\n");
3161
ast_free(p->cidspill);
3164
if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
3165
p->cidlen = ast_callerid_generate(p->cidspill, ast->cid.cid_name, ast->cid.cid_num, AST_LAW(p));
3170
/* Choose proper cadence */
3171
if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
3172
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
3173
ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
3174
p->cidrings = cidrings[p->distinctivering - 1];
3176
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
3177
ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
3178
p->cidrings = p->sendcalleridafter;
3181
/* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
3182
c = strchr(dest, '/');
3185
if (c && (strlen(c) < p->stripmsd)) {
3186
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
3190
p->dop.op = DAHDI_DIAL_OP_REPLACE;
3191
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
3192
ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
3194
p->dop.dialstr[0] = '\0';
3197
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x) && (errno != EINPROGRESS)) {
3198
ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
3199
ast_mutex_unlock(&p->lock);
3204
/* Call waiting call */
3205
p->callwaitrings = 0;
3206
if (ast->cid.cid_num)
3207
ast_copy_string(p->callwait_num, ast->cid.cid_num, sizeof(p->callwait_num));
3209
p->callwait_num[0] = '\0';
3210
if (ast->cid.cid_name)
3211
ast_copy_string(p->callwait_name, ast->cid.cid_name, sizeof(p->callwait_name));
3213
p->callwait_name[0] = '\0';
3214
/* Call waiting tone instead */
3215
if (dahdi_callwait(ast)) {
3216
ast_mutex_unlock(&p->lock);
3219
/* Make ring-back */
3220
if (tone_zone_play_tone(p->subs[SUB_CALLWAIT].dfd, DAHDI_TONE_RINGTONE))
3221
ast_log(LOG_WARNING, "Unable to generate call-wait ring-back on channel %s\n", ast->name);
3223
n = ast->cid.cid_name;
3224
l = ast->cid.cid_num;
3226
ast_copy_string(p->lastcid_num, l, sizeof(p->lastcid_num));
3228
p->lastcid_num[0] = '\0';
3230
ast_copy_string(p->lastcid_name, n, sizeof(p->lastcid_name));
3232
p->lastcid_name[0] = '\0';
3233
ast_setstate(ast, AST_STATE_RINGING);
3234
idx = dahdi_get_index(ast, p, 0);
3236
p->subs[idx].needringing = 1;
3242
if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
3243
ast_debug(1, "Ignore possible polarity reversal on line seizure\n");
3244
p->polaritydelaytv = ast_tvnow();
3254
case SIG_FGC_CAMAMF:
3259
case SIG_SF_FEATDMF:
3260
case SIG_FEATDMF_TA:
3262
c = strchr(dest, '/');
3267
if (strlen(c) < p->stripmsd) {
3268
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
3269
ast_mutex_unlock(&p->lock);
3273
/* Start the trunk, if not GR-303 */
3277
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
3279
if (errno != EINPROGRESS) {
3280
ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
3281
ast_mutex_unlock(&p->lock);
3288
ast_debug(1, "Dialing '%s'\n", c);
3289
p->dop.op = DAHDI_DIAL_OP_REPLACE;
3295
l = ast->cid.cid_num;
3297
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c);
3299
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c);
3302
l = ast->cid.cid_num;
3304
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*00%s#*%s#", l, c);
3306
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*02#*%s#", c);
3308
case SIG_FEATDMF_TA:
3310
const char *cic, *ozz;
3312
/* If you have to go through a Tandem Access point you need to use this */
3313
ozz = pbx_builtin_getvar_helper(p->owner, "FEATDMF_OZZ");
3316
cic = pbx_builtin_getvar_helper(p->owner, "FEATDMF_CIC");
3320
ast_log(LOG_WARNING, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
3321
ast_mutex_unlock(&p->lock);
3324
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s%s#", ozz, cic);
3325
snprintf(p->finaldial, sizeof(p->finaldial), "M*%s#", c);
3330
ast_copy_string(p->dop.dialstr, "M*911#", sizeof(p->dop.dialstr));
3333
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%s", c);
3335
case SIG_FGC_CAMAMF:
3337
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%s#", c);
3341
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "P%sw", c);
3343
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%sw", c);
3347
if (p->echotraining && (strlen(p->dop.dialstr) > 4)) {
3348
memset(p->echorest, 'w', sizeof(p->echorest) - 1);
3349
strcpy(p->echorest + (p->echotraining / 400) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
3350
p->echorest[sizeof(p->echorest) - 1] = '\0';
3352
p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
3356
/* waitfordialtone ? */
3360
if( p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp ) {
3361
ast_log(LOG_DEBUG, "Defer dialling for %dms or dialtone\n", p->waitfordialtone);
3362
gettimeofday(&p->waitingfordt,NULL);
3363
ast_setstate(ast, AST_STATE_OFFHOOK);
3370
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
3371
int saveerr = errno;
3374
ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
3375
ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
3376
ast_mutex_unlock(&p->lock);
3380
ast_debug(1, "Deferring dialing...\n");
3383
if (ast_strlen_zero(c))
3385
ast_setstate(ast, AST_STATE_DIALING);
3388
/* Special pseudo -- automatically up*/
3389
ast_setstate(ast, AST_STATE_UP);
3396
/* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
3397
p->dialdest[0] = '\0';
3401
ast_debug(1, "not yet implemented\n");
3402
ast_mutex_unlock(&p->lock);
3407
char ss7_called_nai;
3408
int called_nai_strip;
3409
char ss7_calling_nai;
3410
int calling_nai_strip;
3411
const char *charge_str = NULL;
3412
const char *gen_address = NULL;
3413
const char *gen_digits = NULL;
3414
const char *gen_dig_type = NULL;
3415
const char *gen_dig_scheme = NULL;
3416
const char *gen_name = NULL;
3417
const char *jip_digits = NULL;
3418
const char *lspi_ident = NULL;
3419
const char *rlt_flag = NULL;
3420
const char *call_ref_id = NULL;
3421
const char *call_ref_pc = NULL;
3422
const char *send_far = NULL;
3424
c = strchr(dest, '/');
3430
if (strlen(c) < p->stripmsd) {
3431
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
3432
ast_mutex_unlock(&p->lock);
3436
if (!p->hidecallerid) {
3437
l = ast->cid.cid_num;
3442
if (ss7_grab(p, p->ss7)) {
3443
ast_log(LOG_WARNING, "Failed to grab SS7!\n");
3444
ast_mutex_unlock(&p->lock);
3447
p->digital = IS_DIGITAL(ast->transfercapability);
3448
p->ss7call = isup_new_call(p->ss7->ss7);
3452
ast_mutex_unlock(&p->lock);
3453
ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n");
3457
called_nai_strip = 0;
3458
ss7_called_nai = p->ss7->called_nai;
3459
if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */
3460
if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
3461
called_nai_strip = strlen(p->ss7->internationalprefix);
3462
ss7_called_nai = SS7_NAI_INTERNATIONAL;
3463
} else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
3464
called_nai_strip = strlen(p->ss7->nationalprefix);
3465
ss7_called_nai = SS7_NAI_NATIONAL;
3467
ss7_called_nai = SS7_NAI_SUBSCRIBER;
3470
isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7);
3472
calling_nai_strip = 0;
3473
ss7_calling_nai = p->ss7->calling_nai;
3474
if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */
3475
if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) {
3476
calling_nai_strip = strlen(p->ss7->internationalprefix);
3477
ss7_calling_nai = SS7_NAI_INTERNATIONAL;
3478
} else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) {
3479
calling_nai_strip = strlen(p->ss7->nationalprefix);
3480
ss7_calling_nai = SS7_NAI_NATIONAL;
3482
ss7_calling_nai = SS7_NAI_SUBSCRIBER;
3485
isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai,
3486
p->use_callingpres ? cid_pres2ss7pres(ast->cid.cid_pres) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED),
3487
p->use_callingpres ? cid_pres2ss7screen(ast->cid.cid_pres) : SS7_SCREENING_USER_PROVIDED );
3489
isup_set_oli(p->ss7call, ast->cid.cid_ani2);
3490
isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc);
3492
ast_channel_lock(ast);
3493
/* Set the charge number if it is set */
3494
charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER");
3496
isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10);
3498
gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS");
3500
isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */
3502
gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS");
3503
gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE");
3504
gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME");
3506
isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme));
3508
gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME");
3510
isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED);
3512
jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP");
3514
isup_set_jip_digits(p->ss7call, jip_digits);
3516
lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT");
3518
isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00);
3520
rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON");
3521
if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) {
3522
isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */
3525
call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT");
3526
call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC");
3527
if (call_ref_id && call_ref_pc) {
3528
isup_set_callref(p->ss7call, atoi(call_ref_id),
3529
call_ref_pc ? atoi(call_ref_pc) : 0);
3532
send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR");
3533
if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 ))
3534
(isup_far(p->ss7->ss7, p->ss7call));
3536
ast_channel_unlock(ast);
3538
isup_iam(p->ss7->ss7, p->ss7call);
3539
ast_setstate(ast, AST_STATE_DIALING);
3542
#endif /* HAVE_SS7 */
3545
openr2_calling_party_category_t chancat;
3549
c = strchr(dest, '/');
3555
if (!p->hidecallerid) {
3556
l = ast->cid.cid_num;
3560
if (strlen(c) < p->stripmsd) {
3561
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
3562
ast_mutex_unlock(&p->lock);
3566
ast_channel_lock(ast);
3567
chancat = dahdi_r2_get_channel_category(ast);
3568
ast_channel_unlock(ast);
3569
callres = openr2_chan_make_call(p->r2chan, l, (c + p->stripmsd), chancat);
3570
if (-1 == callres) {
3571
ast_mutex_unlock(&p->lock);
3572
ast_log(LOG_ERROR, "unable to make new MFC/R2 call!\n");
3575
ast_setstate(ast, AST_STATE_DIALING);
3577
#endif /* HAVE_OPENR2 */
3581
#ifdef SUPPORT_USERUSER
3582
const char *useruser;
3586
int prilocaldialplan;
3590
int redirect_reason;
3592
c = strchr(dest, '/');
3601
if (!p->hidecallerid) {
3602
l = ast->cid.cid_num;
3603
if (!p->hidecalleridname) {
3604
n = ast->cid.cid_name;
3608
if (strlen(c) < p->stripmsd) {
3609
ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
3610
ast_mutex_unlock(&p->lock);
3613
if (mysig != SIG_FXSKS) {
3614
p->dop.op = DAHDI_DIAL_OP_REPLACE;
3615
s = strchr(c + p->stripmsd, 'w');
3618
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", s);
3620
p->dop.dialstr[0] = '\0';
3623
p->dop.dialstr[0] = '\0';
3626
if (pri_grab(p, p->pri)) {
3627
ast_log(LOG_WARNING, "Failed to grab PRI!\n");
3628
ast_mutex_unlock(&p->lock);
3631
if (!(p->call = pri_new_call(p->pri->pri))) {
3632
ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
3634
ast_mutex_unlock(&p->lock);
3637
if (!(sr = pri_sr_new())) {
3638
ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
3640
ast_mutex_unlock(&p->lock);
3642
if (p->bearer || (mysig == SIG_FXSKS)) {
3644
ast_debug(1, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
3645
p->bearer->call = p->call;
3647
ast_debug(1, "I'm being setup with no bearer right now...\n");
3649
pri_set_crv(p->pri->pri, p->call, p->channel, 0);
3651
p->digital = IS_DIGITAL(ast->transfercapability);
3653
/* Should the picked channel be used exclusively? */
3654
if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
3660
pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
3661
pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
3663
((p->law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
3664
if (p->pri->facilityenable)
3665
pri_facility_enable(p->pri->pri);
3667
ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
3670
pridialplan = p->pri->dialplan - 1;
3671
if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */
3672
if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
3673
if (pridialplan == -2) {
3674
dp_strip = strlen(p->pri->internationalprefix);
3676
pridialplan = PRI_INTERNATIONAL_ISDN;
3677
} else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
3678
if (pridialplan == -2) {
3679
dp_strip = strlen(p->pri->nationalprefix);
3681
pridialplan = PRI_NATIONAL_ISDN;
3683
pridialplan = PRI_LOCAL_ISDN;
3686
while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
3687
switch (c[p->stripmsd]) {
3689
pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
3692
pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
3695
pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
3698
pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
3701
pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
3704
pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
3707
pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
3710
pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
3713
pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
3716
pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
3719
pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
3722
pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
3725
pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
3728
pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
3731
if (isalpha(c[p->stripmsd])) {
3732
ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
3733
c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
3739
pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
3742
prilocaldialplan = p->pri->localdialplan - 1;
3743
if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */
3744
if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
3745
if (prilocaldialplan == -2) {
3746
ldp_strip = strlen(p->pri->internationalprefix);
3748
prilocaldialplan = PRI_INTERNATIONAL_ISDN;
3749
} else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
3750
if (prilocaldialplan == -2) {
3751
ldp_strip = strlen(p->pri->nationalprefix);
3753
prilocaldialplan = PRI_NATIONAL_ISDN;
3755
prilocaldialplan = PRI_LOCAL_ISDN;
3759
while (*l > '9' && *l != '*' && *l != '#') {
3762
prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
3765
prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
3768
prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
3771
prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
3774
prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
3777
prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
3780
prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
3783
prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
3786
prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
3789
prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
3792
prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
3795
prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
3798
prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
3801
prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
3805
ast_log(LOG_WARNING,
3806
"Unrecognized prilocaldialplan %s modifier: %c\n",
3807
*l > 'Z' ? "NPI" : "TON", *l);
3814
pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
3815
p->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
3816
if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) {
3817
if (!strcasecmp(rr_str, "UNKNOWN"))
3818
redirect_reason = 0;
3819
else if (!strcasecmp(rr_str, "BUSY"))
3820
redirect_reason = 1;
3821
else if (!strcasecmp(rr_str, "NO_REPLY") || !strcasecmp(rr_str, "NOANSWER"))
3822
/* the NOANSWER is to match diversion-reason from chan_sip, (which never reads PRIREDIRECTREASON) */
3823
redirect_reason = 2;
3824
else if (!strcasecmp(rr_str, "UNCONDITIONAL"))
3825
redirect_reason = 15;
3827
redirect_reason = PRI_REDIR_UNCONDITIONAL;
3829
redirect_reason = PRI_REDIR_UNCONDITIONAL;
3830
pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason);
3832
#ifdef SUPPORT_USERUSER
3833
/* User-user info */
3834
useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
3836
pri_sr_set_useruser(sr, useruser);
3839
if (pri_setup(p->pri->pri, p->call, sr)) {
3840
ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
3841
c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
3843
ast_mutex_unlock(&p->lock);
3848
ast_setstate(ast, AST_STATE_DIALING);
3852
ast_mutex_unlock(&p->lock);
3856
static void destroy_dahdi_pvt(struct dahdi_pvt **pvt)
3858
struct dahdi_pvt *p = *pvt;
3859
/* Remove channel from the list */
3861
p->prev->next = p->next;
3863
p->next->prev = p->prev;
3865
ast_smdi_interface_unref(p->smdi_iface);
3866
if (p->mwi_event_sub)
3867
ast_event_unsubscribe(p->mwi_event_sub);
3869
ast_variables_destroy(p->vars);
3871
ast_mutex_destroy(&p->lock);
3872
dahdi_close_sub(p, SUB_REAL);
3874
p->owner->tech_pvt = NULL;
3879
static int destroy_channel(struct dahdi_pvt *prev, struct dahdi_pvt *cur, int now)
3889
for (i = 0; i < 3; i++) {
3890
if (cur->subs[i].owner) {
3896
prev->next = cur->next;
3898
prev->next->prev = prev;
3904
iflist->prev = NULL;
3908
destroy_dahdi_pvt(&cur);
3912
prev->next = cur->next;
3914
prev->next->prev = prev;
3920
iflist->prev = NULL;
3924
destroy_dahdi_pvt(&cur);
3929
static void destroy_all_channels(void)
3932
struct dahdi_pvt *p, *pl;
3934
while (num_restart_pending) {
3938
ast_mutex_lock(&iflock);
3939
/* Destroy all the interfaces and free their memory */
3942
/* Free any callerid */
3944
ast_free(p->cidspill);
3948
/* Free associated memory */
3950
destroy_dahdi_pvt(&pl);
3951
if (option_verbose > 2)
3952
ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x);
3956
ast_mutex_unlock(&iflock);
3959
#if defined(HAVE_PRI)
3960
static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility";
3962
static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, void *data)
3964
/* Data will be our digit string */
3965
struct dahdi_pvt *p;
3966
char *digits = (char *) data;
3968
if (ast_strlen_zero(digits)) {
3969
ast_debug(1, "No digit string sent to application!\n");
3973
p = (struct dahdi_pvt *)chan->tech_pvt;
3976
ast_debug(1, "Unable to find technology private\n");
3980
ast_mutex_lock(&p->lock);
3982
if (!p->pri || !p->call) {
3983
ast_debug(1, "Unable to find pri or call on channel!\n");
3984
ast_mutex_unlock(&p->lock);
3988
if (!pri_grab(p, p->pri)) {
3989
pri_keypad_facility(p->pri->pri, p->call, digits);
3992
ast_debug(1, "Unable to grab pri to send keypad facility!\n");
3993
ast_mutex_unlock(&p->lock);
3997
ast_mutex_unlock(&p->lock);
4001
#endif /* defined(HAVE_PRI) */
4003
#if defined(HAVE_PRI)
4004
#if defined(HAVE_PRI_PROG_W_CAUSE)
4005
static char *dahdi_send_callrerouting_facility_app = "DAHDISendCallreroutingFacility";
4007
static int dahdi_send_callrerouting_facility_exec(struct ast_channel *chan, void *data)
4009
/* Data will be our digit string */
4010
struct dahdi_pvt *p;
4013
AST_DECLARE_APP_ARGS(args,
4014
AST_APP_ARG(destination);
4015
AST_APP_ARG(original);
4016
AST_APP_ARG(reason);
4019
if (ast_strlen_zero(data)) {
4020
ast_log(LOG_DEBUG, "No data sent to application!\n");
4024
p = (struct dahdi_pvt *)chan->tech_pvt;
4027
ast_log(LOG_DEBUG, "Unable to find technology private\n");
4031
parse = ast_strdupa(data);
4032
AST_STANDARD_APP_ARGS(args, parse);
4034
if (ast_strlen_zero(args.destination)) {
4035
ast_log(LOG_WARNING, "callrerouting facility requires at least destination number argument\n");
4039
if (ast_strlen_zero(args.original)) {
4040
ast_log(LOG_WARNING, "Callrerouting Facility without original called number argument\n");
4041
args.original = NULL;
4044
if (ast_strlen_zero(args.reason)) {
4045
ast_log(LOG_NOTICE, "Callrerouting Facility without diversion reason argument, defaulting to unknown\n");
4049
ast_mutex_lock(&p->lock);
4051
if (!p->pri || !p->call) {
4052
ast_log(LOG_DEBUG, "Unable to find pri or call on channel!\n");
4053
ast_mutex_unlock(&p->lock);
4059
if (!pri_grab(p, p->pri)) {
4060
if (chan->_state == AST_STATE_RING) {
4061
res = pri_callrerouting_facility(p->pri->pri, p->call, args.destination, args.original, args.reason);
4065
ast_log(LOG_DEBUG, "Unable to grab pri to send callrerouting facility on span %d!\n", p->span);
4066
ast_mutex_unlock(&p->lock);
4072
ast_mutex_unlock(&p->lock);
4076
#endif /* defined(HAVE_PRI_PROG_W_CAUSE) */
4077
#endif /* defined(HAVE_PRI) */
4079
#if defined(HAVE_PRI)
4080
static int pri_is_up(struct dahdi_pri *pri)
4083
for (x = 0; x < NUM_DCHANS; x++) {
4084
if (pri->dchanavail[x] == DCHAN_AVAILABLE)
4089
#endif /* defined(HAVE_PRI) */
4091
#if defined(HAVE_PRI)
4092
static int pri_assign_bearer(struct dahdi_pvt *crv, struct dahdi_pri *pri, struct dahdi_pvt *bearer)
4094
bearer->owner = &inuse;
4095
bearer->realcall = crv;
4096
crv->subs[SUB_REAL].dfd = bearer->subs[SUB_REAL].dfd;
4097
if (crv->subs[SUB_REAL].owner)
4098
ast_channel_set_fd(crv->subs[SUB_REAL].owner, 0, crv->subs[SUB_REAL].dfd);
4099
crv->bearer = bearer;
4100
crv->call = bearer->call;
4104
#endif /* defined(HAVE_PRI) */
4106
#if defined(HAVE_PRI)
4107
static char *pri_order(int level)
4117
return "Quaternary";
4122
#endif /* defined(HAVE_PRI) */
4124
#if defined(HAVE_PRI)
4125
/* Returns fd of the active dchan */
4126
static int pri_active_dchan_fd(struct dahdi_pri *pri)
4130
for (x = 0; x < NUM_DCHANS; x++) {
4131
if ((pri->dchans[x] == pri->pri))
4137
#endif /* defined(HAVE_PRI) */
4139
#if defined(HAVE_PRI)
4140
static int pri_find_dchan(struct dahdi_pri *pri)
4147
for (x = 0; x < NUM_DCHANS; x++) {
4148
if ((pri->dchanavail[x] == DCHAN_AVAILABLE) && (newslot < 0))
4150
if (pri->dchans[x] == old) {
4156
/* This is annoying to see on non persistent layer 2 connections. Let's not complain in that case */
4157
if (pri->sig != SIG_BRI_PTMP) {
4158
ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n",
4159
pri->dchannels[newslot]);
4162
if (old && (oldslot != newslot))
4163
ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
4164
pri->dchannels[oldslot], pri->dchannels[newslot]);
4165
pri->pri = pri->dchans[newslot];
4168
#endif /* defined(HAVE_PRI) */
4170
#if defined(HAVE_OPENR2)
4171
static const char *dahdi_accept_r2_call_app = "DAHDIAcceptR2Call";
4173
static int dahdi_accept_r2_call_exec(struct ast_channel *chan, void *data)
4175
/* data is whether to accept with charge or no charge */
4176
openr2_call_mode_t accept_mode;
4177
int res, timeout, maxloops;
4178
struct ast_frame *f;
4179
struct dahdi_pvt *p;
4181
AST_DECLARE_APP_ARGS(args,
4182
AST_APP_ARG(charge);
4185
if (ast_strlen_zero(data)) {
4186
ast_log(LOG_DEBUG, "No data sent to application!\n");
4190
if (chan->tech != &dahdi_tech) {
4191
ast_log(LOG_DEBUG, "Only DAHDI technology accepted!\n");
4195
p = (struct dahdi_pvt *)chan->tech_pvt;
4197
ast_log(LOG_DEBUG, "Unable to find technology private!\n");
4201
parse = ast_strdupa(data);
4202
AST_STANDARD_APP_ARGS(args, parse);
4204
if (ast_strlen_zero(args.charge)) {
4205
ast_log(LOG_WARNING, "DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
4209
ast_mutex_lock(&p->lock);
4210
if (!p->mfcr2 || !p->mfcr2call) {
4211
ast_mutex_unlock(&p->lock);
4212
ast_log(LOG_DEBUG, "Channel %s does not seems to be an R2 active channel!\n", chan->name);
4216
if (p->mfcr2_call_accepted) {
4217
ast_mutex_unlock(&p->lock);
4218
ast_log(LOG_DEBUG, "MFC/R2 call already accepted on channel %s!\n", chan->name);
4221
accept_mode = ast_true(args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
4222
if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
4223
ast_mutex_unlock(&p->lock);
4224
ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
4227
ast_mutex_unlock(&p->lock);
4231
maxloops = 50; /* wait up to 5 seconds */
4232
/* we need to read() until the call is accepted */
4233
while (maxloops > 0) {
4235
if (ast_check_hangup(chan)) {
4238
res = ast_waitfor(chan, timeout);
4240
ast_log(LOG_DEBUG, "ast_waitfor failed on channel %s, going out ...\n", chan->name);
4249
ast_log(LOG_DEBUG, "No frame read on channel %s, going out ...\n", chan->name);
4253
if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
4254
ast_log(LOG_DEBUG, "Got HANGUP frame on channel %s, going out ...\n", chan->name);
4260
ast_mutex_lock(&p->lock);
4261
if (p->mfcr2_call_accepted) {
4262
ast_mutex_unlock(&p->lock);
4263
ast_log(LOG_DEBUG, "Accepted MFC/R2 call!\n");
4266
ast_mutex_unlock(&p->lock);
4269
ast_log(LOG_WARNING, "Failed to accept MFC/R2 call!\n");
4274
static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(int cause)
4276
openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
4278
case AST_CAUSE_USER_BUSY:
4279
case AST_CAUSE_CALL_REJECTED:
4280
case AST_CAUSE_INTERWORKING: /* I don't know wtf is this but is used sometimes when ekiga rejects a call */
4281
r2cause = OR2_CAUSE_BUSY_NUMBER;
4284
case AST_CAUSE_NORMAL_CIRCUIT_CONGESTION:
4285
case AST_CAUSE_SWITCH_CONGESTION:
4286
r2cause = OR2_CAUSE_NETWORK_CONGESTION;
4289
case AST_CAUSE_UNALLOCATED:
4290
r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
4293
case AST_CAUSE_NETWORK_OUT_OF_ORDER:
4294
case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
4295
r2cause = OR2_CAUSE_OUT_OF_ORDER;
4298
case AST_CAUSE_NO_ANSWER:
4299
case AST_CAUSE_NO_USER_RESPONSE:
4300
r2cause = OR2_CAUSE_NO_ANSWER;
4304
r2cause = OR2_CAUSE_NORMAL_CLEARING;
4307
ast_log(LOG_DEBUG, "ast cause %d resulted in openr2 cause %d/%s\n",
4308
cause, r2cause, openr2_proto_get_disconnect_string(r2cause));
4313
static int dahdi_hangup(struct ast_channel *ast)
4317
/*static int restore_gains(struct dahdi_pvt *p);*/
4318
struct dahdi_pvt *p = ast->tech_pvt;
4319
struct dahdi_pvt *tmp = NULL;
4320
struct dahdi_pvt *prev = NULL;
4321
struct dahdi_params par;
4323
ast_debug(1, "dahdi_hangup(%s)\n", ast->name);
4324
if (!ast->tech_pvt) {
4325
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
4329
ast_mutex_lock(&p->lock);
4331
idx = dahdi_get_index(ast, p, 1);
4333
if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
4335
ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
4336
p->cid_num[0] = '\0';
4337
p->cid_name[0] = '\0';
4341
dahdi_confmute(p, 0);
4344
if (p->origcid_num) {
4345
ast_copy_string(p->cid_num, p->origcid_num, sizeof(p->cid_num));
4346
ast_free(p->origcid_num);
4347
p->origcid_num = NULL;
4349
if (p->origcid_name) {
4350
ast_copy_string(p->cid_name, p->origcid_name, sizeof(p->cid_name));
4351
ast_free(p->origcid_name);
4352
p->origcid_name = NULL;
4355
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
4358
ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
4359
p->channel, idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
4363
/* Real channel, do some fixup */
4364
p->subs[idx].owner = NULL;
4365
p->subs[idx].needanswer = 0;
4366
p->subs[idx].needflash = 0;
4367
p->subs[idx].needringing = 0;
4368
p->subs[idx].needbusy = 0;
4369
p->subs[idx].needcongestion = 0;
4370
p->subs[idx].linear = 0;
4371
p->subs[idx].needcallerid = 0;
4372
p->polarity = POLARITY_IDLE;
4373
dahdi_setlinear(p->subs[idx].dfd, 0);
4374
if (idx == SUB_REAL) {
4375
if ((p->subs[SUB_CALLWAIT].dfd > -1) && (p->subs[SUB_THREEWAY].dfd > -1)) {
4376
ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
4377
if (p->subs[SUB_CALLWAIT].inthreeway) {
4378
/* We had flipped over to answer a callwait and now it's gone */
4379
ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
4380
/* Move to the call-wait, but un-own us until they flip back. */
4381
swap_subs(p, SUB_CALLWAIT, SUB_REAL);
4382
unalloc_sub(p, SUB_CALLWAIT);
4385
/* The three way hung up, but we still have a call wait */
4386
ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
4387
swap_subs(p, SUB_THREEWAY, SUB_REAL);
4388
unalloc_sub(p, SUB_THREEWAY);
4389
if (p->subs[SUB_REAL].inthreeway) {
4390
/* This was part of a three way call. Immediately make way for
4392
ast_debug(1, "Call was complete, setting owner to former third call\n");
4393
p->owner = p->subs[SUB_REAL].owner;
4395
/* This call hasn't been completed yet... Set owner to NULL */
4396
ast_debug(1, "Call was incomplete, setting owner to NULL\n");
4399
p->subs[SUB_REAL].inthreeway = 0;
4401
} else if (p->subs[SUB_CALLWAIT].dfd > -1) {
4402
/* Move to the call-wait and switch back to them. */
4403
swap_subs(p, SUB_CALLWAIT, SUB_REAL);
4404
unalloc_sub(p, SUB_CALLWAIT);
4405
p->owner = p->subs[SUB_REAL].owner;
4406
if (p->owner->_state != AST_STATE_UP)
4407
p->subs[SUB_REAL].needanswer = 1;
4408
if (ast_bridged_channel(p->subs[SUB_REAL].owner))
4409
ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
4410
} else if (p->subs[SUB_THREEWAY].dfd > -1) {
4411
swap_subs(p, SUB_THREEWAY, SUB_REAL);
4412
unalloc_sub(p, SUB_THREEWAY);
4413
if (p->subs[SUB_REAL].inthreeway) {
4414
/* This was part of a three way call. Immediately make way for
4416
ast_debug(1, "Call was complete, setting owner to former third call\n");
4417
p->owner = p->subs[SUB_REAL].owner;
4419
/* This call hasn't been completed yet... Set owner to NULL */
4420
ast_debug(1, "Call was incomplete, setting owner to NULL\n");
4423
p->subs[SUB_REAL].inthreeway = 0;
4425
} else if (idx == SUB_CALLWAIT) {
4426
/* Ditch the holding callwait call, and immediately make it availabe */
4427
if (p->subs[SUB_CALLWAIT].inthreeway) {
4428
/* This is actually part of a three way, placed on hold. Place the third part
4429
on music on hold now */
4430
if (p->subs[SUB_THREEWAY].owner && ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
4431
ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
4432
S_OR(p->mohsuggest, NULL),
4433
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
4435
p->subs[SUB_THREEWAY].inthreeway = 0;
4436
/* Make it the call wait now */
4437
swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
4438
unalloc_sub(p, SUB_THREEWAY);
4440
unalloc_sub(p, SUB_CALLWAIT);
4441
} else if (idx == SUB_THREEWAY) {
4442
if (p->subs[SUB_CALLWAIT].inthreeway) {
4443
/* The other party of the three way call is currently in a call-wait state.
4444
Start music on hold for them, and take the main guy out of the third call */
4445
if (p->subs[SUB_CALLWAIT].owner && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
4446
ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
4447
S_OR(p->mohsuggest, NULL),
4448
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
4450
p->subs[SUB_CALLWAIT].inthreeway = 0;
4452
p->subs[SUB_REAL].inthreeway = 0;
4453
/* If this was part of a three way call index, let us make
4454
another three way call */
4455
unalloc_sub(p, SUB_THREEWAY);
4457
/* This wasn't any sort of call, but how are we an index? */
4458
ast_log(LOG_WARNING, "Index found but not any type of call?\n");
4462
if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
4465
p->distinctivering = 0;
4466
p->confirmanswer = 0;
4472
p->onhooktime = time(NULL);
4473
#if defined(HAVE_PRI) || defined(HAVE_SS7)
4482
ast_dsp_free(p->dsp);
4486
if (p->faxbuffersinuse) {
4487
/* faxbuffers are in use, revert them */
4488
struct dahdi_bufferinfo bi = {
4489
.txbufpolicy = p->buf_policy,
4490
.rxbufpolicy = p->buf_policy,
4491
.bufsize = p->bufsize,
4492
.numbufs = p->buf_no
4496
if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
4497
ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
4499
p->faxbuffersinuse = 0;
4502
law = DAHDI_LAW_DEFAULT;
4503
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
4505
ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
4506
/* Perform low level hangup if no owner left */
4510
if (!ss7_grab(p, p->ss7)) {
4511
if (!p->alreadyhungup) {
4512
const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE");
4513
int icause = ast->hangupcause ? ast->hangupcause : -1;
4517
icause = atoi(cause);
4519
isup_rel(p->ss7->ss7, p->ss7call, icause);
4521
p->alreadyhungup = 1;
4523
ast_log(LOG_WARNING, "Trying to hangup twice!\n");
4525
ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic);
4532
p->cid_num[0] = '\0';
4533
p->cid_name[0] = '\0';
4534
if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
4535
ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
4536
/* If it's an incoming call, check the mfcr2_forced_release setting */
4537
if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
4538
dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
4540
const char *r2causestr = pbx_builtin_getvar_helper(ast, "MFCR2_CAUSE");
4541
int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
4542
openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
4543
: dahdi_ast_cause_to_r2_cause(ast->hangupcause);
4544
dahdi_r2_disconnect_call(p, r2cause);
4546
} else if (p->mfcr2call) {
4547
ast_log(LOG_DEBUG, "Clearing call request on channel %d\n", p->channel);
4548
/* since ast_request() was called but not ast_call() we have not yet dialed
4549
and the openr2 stack will not call on_call_end callback, we need to unset
4550
the mfcr2call flag and bump the monitor count so the monitor thread can take
4551
care of this channel events from now on */
4557
#ifdef SUPPORT_USERUSER
4558
const char *useruser = pbx_builtin_getvar_helper(ast,"USERUSERINFO");
4561
/* Make sure we have a call (or REALLY have a call in the case of a PRI) */
4562
if (p->call && (!p->bearer || (p->bearer->call == p->call))) {
4563
if (!pri_grab(p, p->pri)) {
4564
if (p->alreadyhungup) {
4565
ast_debug(1, "Already hungup... Calling hangup once, and clearing call\n");
4567
#ifdef SUPPORT_USERUSER
4568
pri_call_set_useruser(p->call, useruser);
4571
pri_hangup(p->pri->pri, p->call, -1);
4574
p->bearer->call = NULL;
4576
const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
4577
int icause = ast->hangupcause ? ast->hangupcause : -1;
4578
ast_debug(1, "Not yet hungup... Calling hangup once with icause, and clearing call\n");
4580
#ifdef SUPPORT_USERUSER
4581
pri_call_set_useruser(p->call, useruser);
4584
p->alreadyhungup = 1;
4586
p->bearer->alreadyhungup = 1;
4589
icause = atoi(cause);
4591
pri_hangup(p->pri->pri, p->call, icause);
4594
ast_log(LOG_WARNING, "pri_disconnect failed\n");
4597
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
4602
ast_debug(1, "Bearer call is %p, while ours is still %p\n", p->bearer->call, p->call);
4608
if (p->sig && ((p->sig != SIG_PRI) && (p->sig != SIG_SS7)
4609
&& (p->sig != SIG_BRI)
4610
&& (p->sig != SIG_BRI_PTMP))
4611
&& (p->sig != SIG_MFCR2))
4612
res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
4614
ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
4620
memset(&par, 0, sizeof(par));
4621
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
4624
ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
4626
/* If they're off hook, try playing congestion */
4627
if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
4628
tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
4630
tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
4631
p->fxsoffhookstate = par.rxisoffhook;
4637
/* Make sure we're not made available for at least two seconds assuming
4638
we were actually used for an inbound or outbound call. */
4639
if (ast->_state != AST_STATE_RESERVED) {
4640
time(&p->guardtime);
4645
tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
4648
ast_free(p->cidspill);
4650
dahdi_disable_ec(p);
4652
ast_channel_setoption(ast,AST_OPTION_TONE_VERIFY,&x,sizeof(char),0);
4653
ast_channel_setoption(ast,AST_OPTION_TDD,&x,sizeof(char),0);
4657
p->callwaiting = p->permcallwaiting;
4658
p->hidecallerid = p->permhidecallerid;
4659
p->waitingfordt.tv_sec = 0;
4664
/* Restore data mode */
4665
if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
4667
ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
4671
ast_debug(1, "Freeing up bearer channel %d\n", p->bearer->channel);
4672
/* Free up the bearer channel as well, and
4673
don't use its file descriptor anymore */
4674
update_conf(p->bearer);
4675
reset_conf(p->bearer);
4676
p->bearer->owner = NULL;
4677
p->bearer->realcall = NULL;
4679
p->subs[SUB_REAL].dfd = -1;
4683
if (num_restart_pending == 0)
4687
p->callwaitingrepeat = 0;
4690
ast->tech_pvt = NULL;
4691
ast_mutex_unlock(&p->lock);
4692
ast_module_unref(ast_module_info->self);
4693
ast_verb(3, "Hungup '%s'\n", ast->name);
4695
ast_mutex_lock(&iflock);
4697
if (p->restartpending) {
4698
num_restart_pending--;
4706
destroy_channel(prev, tmp, 0);
4714
ast_mutex_unlock(&iflock);
4718
static int dahdi_answer(struct ast_channel *ast)
4720
struct dahdi_pvt *p = ast->tech_pvt;
4723
int oldstate = ast->_state;
4724
ast_setstate(ast, AST_STATE_UP);
4725
ast_mutex_lock(&p->lock);
4726
idx = dahdi_get_index(ast, p, 0);
4729
/* nothing to do if a radio channel */
4730
if ((p->radio || (p->oprmode < 0))) {
4731
ast_mutex_unlock(&p->lock);
4745
case SIG_FEATDMF_TA:
4748
case SIG_FGC_CAMAMF:
4753
case SIG_SF_FEATDMF:
4758
/* Pick up the line */
4759
ast_debug(1, "Took %s off hook\n", ast->name);
4760
if (p->hanguponpolarityswitch) {
4761
p->polaritydelaytv = ast_tvnow();
4763
res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
4764
tone_zone_play_tone(p->subs[idx].dfd, -1);
4766
if ((idx == SUB_REAL) && p->subs[SUB_THREEWAY].inthreeway) {
4767
if (oldstate == AST_STATE_RINGING) {
4768
ast_debug(1, "Finally swapping real and threeway\n");
4769
tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, -1);
4770
swap_subs(p, SUB_THREEWAY, SUB_REAL);
4771
p->owner = p->subs[SUB_REAL].owner;
4774
if (p->sig & __DAHDI_SIG_FXS) {
4783
/* Send a pri acknowledge */
4784
if (!pri_grab(p, p->pri)) {
4787
res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
4790
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
4797
if (!ss7_grab(p, p->ss7)) {
4799
res = isup_anm(p->ss7->ss7, p->ss7call);
4802
ast_log(LOG_WARNING, "Unable to grab SS7 on span %d\n", p->span);
4809
if (!p->mfcr2_call_accepted) {
4810
/* The call was not accepted on offer nor the user, so it must be accepted now before answering,
4811
openr2_chan_answer_call will be called when the callback on_call_accepted is executed */
4812
p->mfcr2_answer_pending = 1;
4813
if (p->mfcr2_charge_calls) {
4814
ast_log(LOG_DEBUG, "Accepting MFC/R2 call with charge before answering on chan %d\n", p->channel);
4815
openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
4817
ast_log(LOG_DEBUG, "Accepting MFC/R2 call with no charge before answering on chan %d\n", p->channel);
4818
openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
4821
ast_log(LOG_DEBUG, "Answering MFC/R2 call on chan %d\n", p->channel);
4827
ast_mutex_unlock(&p->lock);
4830
ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
4833
ast_mutex_unlock(&p->lock);
4837
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen)
4843
struct dahdi_pvt *p = chan->tech_pvt, *pp;
4844
struct oprmode *oprmode;
4847
/* all supported options require data */
4848
if (!data || (datalen < 1)) {
4854
case AST_OPTION_TXGAIN:
4855
scp = (signed char *) data;
4856
idx = dahdi_get_index(chan, p, 0);
4858
ast_log(LOG_WARNING, "No index in TXGAIN?\n");
4861
ast_debug(1, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
4862
return set_actual_txgain(p->subs[idx].dfd, 0, p->txgain + (float) *scp, p->law);
4863
case AST_OPTION_RXGAIN:
4864
scp = (signed char *) data;
4865
idx = dahdi_get_index(chan, p, 0);
4867
ast_log(LOG_WARNING, "No index in RXGAIN?\n");
4870
ast_debug(1, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
4871
return set_actual_rxgain(p->subs[idx].dfd, 0, p->rxgain + (float) *scp, p->law);
4872
case AST_OPTION_TONE_VERIFY:
4878
ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
4879
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | p->dtmfrelax); /* set mute mode if desired */
4882
ast_debug(1, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
4883
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax); /* set mute mode if desired */
4886
ast_debug(1, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
4887
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax); /* set mute mode if desired */
4891
case AST_OPTION_TDD:
4892
/* turn on or off TDD */
4895
if (!*cp) { /* turn it off */
4896
ast_debug(1, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
4902
ast_debug(1, "Set option TDD MODE, value: %s(%d) on %s\n",
4903
(*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
4904
dahdi_disable_ec(p);
4905
/* otherwise, turn it on */
4906
if (!p->didtdd) { /* if havent done it yet */
4907
unsigned char mybuf[41000];/*! \todo XXX This is an abuse of the stack!! */
4909
int size, res, fd, len;
4910
struct pollfd fds[1];
4913
memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
4914
ast_tdd_gen_ecdisa(buf + 16000, 16000); /* put in tone */
4916
idx = dahdi_get_index(chan, p, 0);
4918
ast_log(LOG_WARNING, "No index in TDD?\n");
4921
fd = p->subs[idx].dfd;
4923
if (ast_check_hangup(chan))
4926
if (size > READ_SIZE)
4929
fds[0].events = POLLPRI | POLLOUT;
4931
res = poll(fds, 1, -1);
4933
ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
4936
/* if got exception */
4937
if (fds[0].revents & POLLPRI)
4939
if (!(fds[0].revents & POLLOUT)) {
4940
ast_debug(1, "write fd not ready on channel %d\n", p->channel);
4943
res = write(fd, buf, size);
4945
if (res == -1) return -1;
4946
ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
4952
p->didtdd = 1; /* set to have done it now */
4954
if (*cp == 2) { /* Mate mode */
4961
if (!p->tdd) { /* if we dont have one yet */
4962
p->tdd = tdd_new(); /* allocate one */
4965
case AST_OPTION_RELAXDTMF: /* Relax DTMF decoding (or not) */
4969
ast_debug(1, "Set option RELAX DTMF, value: %s(%d) on %s\n",
4970
*cp ? "ON" : "OFF", (int) *cp, chan->name);
4971
ast_dsp_set_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
4973
case AST_OPTION_AUDIO_MODE: /* Set AUDIO mode (or not) */
4976
ast_debug(1, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
4978
dahdi_disable_ec(p);
4980
ast_debug(1, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
4983
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &x) == -1)
4984
ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, x, strerror(errno));
4986
case AST_OPTION_OPRMODE: /* Operator services mode */
4987
oprmode = (struct oprmode *) data;
4988
/* We don't support operator mode across technologies */
4989
if (strcasecmp(chan->tech->type, oprmode->peer->tech->type)) {
4990
ast_log(LOG_NOTICE, "Operator mode not supported on %s to %s calls.\n",
4991
chan->tech->type, oprmode->peer->tech->type);
4995
pp = oprmode->peer->tech_pvt;
4996
p->oprmode = pp->oprmode = 0;
5000
/* setup modes, if any */
5003
pp->oprmode = oprmode->mode;
5004
p->oprmode = -oprmode->mode;
5006
ast_debug(1, "Set Operator Services mode, value: %d on %s/%s\n",
5007
oprmode->mode, chan->name,oprmode->peer->name);
5009
case AST_OPTION_ECHOCAN:
5012
ast_debug(1, "Enabling echo cancelation on %s\n", chan->name);
5015
ast_debug(1, "Disabling echo cancelation on %s\n", chan->name);
5016
dahdi_disable_ec(p);
5025
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
5027
struct dahdi_pvt *p = chan->tech_pvt;
5029
if (!strcasecmp(data, "rxgain")) {
5030
ast_mutex_lock(&p->lock);
5031
snprintf(buf, len, "%f", p->rxgain);
5032
ast_mutex_unlock(&p->lock);
5033
} else if (!strcasecmp(data, "txgain")) {
5034
ast_mutex_lock(&p->lock);
5035
snprintf(buf, len, "%f", p->txgain);
5036
ast_mutex_unlock(&p->lock);
5038
ast_copy_string(buf, "", len);
5044
static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
5046
/* Unlink a specific slave or all slaves/masters from a given master */
5052
ast_mutex_lock(&master->lock);
5054
while (ast_mutex_trylock(&slave->lock)) {
5055
DEADLOCK_AVOIDANCE(&master->lock);
5060
for (x = 0; x < MAX_SLAVES; x++) {
5061
if (master->slaves[x]) {
5062
if (!slave || (master->slaves[x] == slave)) {
5063
/* Take slave out of the conference */
5064
ast_debug(1, "Unlinking slave %d from %d\n", master->slaves[x]->channel, master->channel);
5065
conf_del(master, &master->slaves[x]->subs[SUB_REAL], SUB_REAL);
5066
conf_del(master->slaves[x], &master->subs[SUB_REAL], SUB_REAL);
5067
master->slaves[x]->master = NULL;
5068
master->slaves[x] = NULL;
5073
master->inconference = 0;
5076
if (master->master) {
5077
/* Take master out of the conference */
5078
conf_del(master->master, &master->subs[SUB_REAL], SUB_REAL);
5079
conf_del(master, &master->master->subs[SUB_REAL], SUB_REAL);
5081
for (x = 0; x < MAX_SLAVES; x++) {
5082
if (master->master->slaves[x] == master)
5083
master->master->slaves[x] = NULL;
5084
else if (master->master->slaves[x])
5088
master->master->inconference = 0;
5090
master->master = NULL;
5092
update_conf(master);
5095
ast_mutex_unlock(&slave->lock);
5096
ast_mutex_unlock(&master->lock);
5100
static void dahdi_link(struct dahdi_pvt *slave, struct dahdi_pvt *master) {
5102
if (!slave || !master) {
5103
ast_log(LOG_WARNING, "Tried to link to/from NULL??\n");
5106
for (x = 0; x < MAX_SLAVES; x++) {
5107
if (!master->slaves[x]) {
5108
master->slaves[x] = slave;
5112
if (x >= MAX_SLAVES) {
5113
ast_log(LOG_WARNING, "Replacing slave %d with new slave, %d\n", master->slaves[MAX_SLAVES - 1]->channel, slave->channel);
5114
master->slaves[MAX_SLAVES - 1] = slave;
5117
ast_log(LOG_WARNING, "Replacing master %d with new master, %d\n", slave->master->channel, master->channel);
5118
slave->master = master;
5120
ast_debug(1, "Making %d slave to master %d at %d\n", slave->channel, master->channel, x);
5123
static void disable_dtmf_detect(struct dahdi_pvt *p)
5130
ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
5132
if (!p->hardwaredtmf && p->dsp) {
5133
p->dsp_features &= ~DSP_FEATURE_DIGIT_DETECT;
5134
ast_dsp_set_features(p->dsp, p->dsp_features);
5138
static void enable_dtmf_detect(struct dahdi_pvt *p)
5142
if (p->channel == CHAN_PSEUDO)
5147
val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
5148
ioctl(p->subs[SUB_REAL].dfd, DAHDI_TONEDETECT, &val);
5150
if (!p->hardwaredtmf && p->dsp) {
5151
p->dsp_features |= DSP_FEATURE_DIGIT_DETECT;
5152
ast_dsp_set_features(p->dsp, p->dsp_features);
5156
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)
5158
struct ast_channel *who;
5159
struct dahdi_pvt *p0, *p1, *op0, *op1;
5160
struct dahdi_pvt *master = NULL, *slave = NULL;
5161
struct ast_frame *f;
5165
int oi0, oi1, i0 = -1, i1 = -1, t0, t1;
5166
int os0 = -1, os1 = -1;
5168
struct ast_channel *oc0, *oc1;
5169
enum ast_bridge_result res;
5172
int triedtopribridge = 0;
5173
q931_call *q931c0 = NULL, *q931c1 = NULL;
5176
/* For now, don't attempt to native bridge if either channel needs DTMF detection.
5177
There is code below to handle it properly until DTMF is actually seen,
5178
but due to currently unresolved issues it's ignored...
5181
if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
5182
return AST_BRIDGE_FAILED_NOWARN;
5184
ast_channel_lock(c0);
5185
while (ast_channel_trylock(c1)) {
5186
CHANNEL_DEADLOCK_AVOIDANCE(c0);
5191
/* cant do pseudo-channels here */
5192
if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
5193
ast_channel_unlock(c0);
5194
ast_channel_unlock(c1);
5195
return AST_BRIDGE_FAILED_NOWARN;
5198
oi0 = dahdi_get_index(c0, p0, 0);
5199
oi1 = dahdi_get_index(c1, p1, 0);
5200
if ((oi0 < 0) || (oi1 < 0)) {
5201
ast_channel_unlock(c0);
5202
ast_channel_unlock(c1);
5203
return AST_BRIDGE_FAILED;
5206
op0 = p0 = c0->tech_pvt;
5207
op1 = p1 = c1->tech_pvt;
5213
if (ast_mutex_trylock(&p0->lock)) {
5214
/* Don't block, due to potential for deadlock */
5215
ast_channel_unlock(c0);
5216
ast_channel_unlock(c1);
5217
ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
5218
return AST_BRIDGE_RETRY;
5220
if (ast_mutex_trylock(&p1->lock)) {
5221
/* Don't block, due to potential for deadlock */
5222
ast_mutex_unlock(&p0->lock);
5223
ast_channel_unlock(c0);
5224
ast_channel_unlock(c1);
5225
ast_log(LOG_NOTICE, "Avoiding deadlock...\n");
5226
return AST_BRIDGE_RETRY;
5229
if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
5230
if (p0->owner && p1->owner) {
5231
/* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
5232
if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
5236
} else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
5241
ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n");
5242
ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
5244
oi0, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
5245
p0->subs[SUB_REAL].inthreeway, p0->channel,
5246
oi0, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
5247
p1->subs[SUB_REAL].inthreeway);
5251
} else if ((oi0 == SUB_REAL) && (oi1 == SUB_THREEWAY)) {
5252
if (p1->subs[SUB_THREEWAY].inthreeway) {
5257
} else if ((oi0 == SUB_THREEWAY) && (oi1 == SUB_REAL)) {
5258
if (p0->subs[SUB_THREEWAY].inthreeway) {
5263
} else if ((oi0 == SUB_REAL) && (oi1 == SUB_CALLWAIT)) {
5264
/* We have a real and a call wait. If we're in a three way call, put us in it, otherwise,
5265
don't put us in anything */
5266
if (p1->subs[SUB_CALLWAIT].inthreeway) {
5271
} else if ((oi0 == SUB_CALLWAIT) && (oi1 == SUB_REAL)) {
5272
/* Same as previous */
5273
if (p0->subs[SUB_CALLWAIT].inthreeway) {
5279
ast_debug(1, "master: %d, slave: %d, nothingok: %d\n",
5280
master ? master->channel : 0, slave ? slave->channel : 0, nothingok);
5281
if (master && slave) {
5282
/* Stop any tones, or play ringtone as appropriate. If they're bridged
5283
in an active threeway call with a channel that is ringing, we should
5284
indicate ringing. */
5285
if ((oi1 == SUB_THREEWAY) &&
5286
p1->subs[SUB_THREEWAY].inthreeway &&
5287
p1->subs[SUB_REAL].owner &&
5288
p1->subs[SUB_REAL].inthreeway &&
5289
(p1->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
5290
ast_debug(1, "Playing ringback on %s since %s is in a ringing three-way\n", c0->name, c1->name);
5291
tone_zone_play_tone(p0->subs[oi0].dfd, DAHDI_TONE_RINGTONE);
5292
os1 = p1->subs[SUB_REAL].owner->_state;
5294
ast_debug(1, "Stopping tones on %d/%d talking to %d/%d\n", p0->channel, oi0, p1->channel, oi1);
5295
tone_zone_play_tone(p0->subs[oi0].dfd, -1);
5297
if ((oi0 == SUB_THREEWAY) &&
5298
p0->subs[SUB_THREEWAY].inthreeway &&
5299
p0->subs[SUB_REAL].owner &&
5300
p0->subs[SUB_REAL].inthreeway &&
5301
(p0->subs[SUB_REAL].owner->_state == AST_STATE_RINGING)) {
5302
ast_debug(1, "Playing ringback on %s since %s is in a ringing three-way\n", c1->name, c0->name);
5303
tone_zone_play_tone(p1->subs[oi1].dfd, DAHDI_TONE_RINGTONE);
5304
os0 = p0->subs[SUB_REAL].owner->_state;
5306
ast_debug(1, "Stopping tones on %d/%d talking to %d/%d\n", p1->channel, oi1, p0->channel, oi0);
5307
tone_zone_play_tone(p1->subs[oi0].dfd, -1);
5309
if ((oi0 == SUB_REAL) && (oi1 == SUB_REAL)) {
5310
if (!p0->echocanbridged || !p1->echocanbridged) {
5311
/* Disable echo cancellation if appropriate */
5312
dahdi_disable_ec(p0);
5313
dahdi_disable_ec(p1);
5316
dahdi_link(slave, master);
5317
master->inconference = inconf;
5318
} else if (!nothingok)
5319
ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n", p0->channel, subnames[oi0], p1->channel, subnames[oi1]);
5323
t0 = p0->subs[SUB_REAL].inthreeway;
5324
t1 = p1->subs[SUB_REAL].inthreeway;
5326
ast_mutex_unlock(&p0->lock);
5327
ast_mutex_unlock(&p1->lock);
5329
ast_channel_unlock(c0);
5330
ast_channel_unlock(c1);
5332
/* Native bridge failed */
5333
if ((!master || !slave) && !nothingok) {
5334
dahdi_enable_ec(p0);
5335
dahdi_enable_ec(p1);
5336
return AST_BRIDGE_FAILED;
5339
ast_verb(3, "Native bridging %s and %s\n", c0->name, c1->name);
5341
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
5342
disable_dtmf_detect(op0);
5344
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
5345
disable_dtmf_detect(op1);
5348
struct ast_channel *c0_priority[2] = {c0, c1};
5349
struct ast_channel *c1_priority[2] = {c1, c0};
5351
/* Here's our main loop... Start by locking things, looking for private parts,
5352
and then balking if anything is wrong */
5354
ast_channel_lock(c0);
5355
while (ast_channel_trylock(c1)) {
5356
CHANNEL_DEADLOCK_AVOIDANCE(c0);
5363
i0 = dahdi_get_index(c0, p0, 1);
5365
i1 = dahdi_get_index(c1, p1, 1);
5367
ast_channel_unlock(c0);
5368
ast_channel_unlock(c1);
5373
(ofd0 != c0->fds[0]) ||
5374
(ofd1 != c1->fds[0]) ||
5375
(p0->subs[SUB_REAL].owner && (os0 > -1) && (os0 != p0->subs[SUB_REAL].owner->_state)) ||
5376
(p1->subs[SUB_REAL].owner && (os1 > -1) && (os1 != p1->subs[SUB_REAL].owner->_state)) ||
5377
(oc0 != p0->owner) ||
5378
(oc1 != p1->owner) ||
5379
(t0 != p0->subs[SUB_REAL].inthreeway) ||
5380
(t1 != p1->subs[SUB_REAL].inthreeway) ||
5383
ast_debug(1, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
5384
op0->channel, oi0, op1->channel, oi1);
5385
res = AST_BRIDGE_RETRY;
5386
goto return_from_bridge;
5392
if (p0->transfer && p1->transfer
5394
&& !triedtopribridge) {
5395
pri_channel_bridge(q931c0, q931c1);
5396
triedtopribridge = 1;
5400
who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
5402
ast_debug(1, "Ooh, empty read...\n");
5406
if (!f || (f->frametype == AST_FRAME_CONTROL)) {
5409
res = AST_BRIDGE_COMPLETE;
5410
goto return_from_bridge;
5412
if (f->frametype == AST_FRAME_DTMF) {
5413
if ((who == c0) && p0->pulsedial) {
5415
} else if ((who == c1) && p1->pulsedial) {
5420
res = AST_BRIDGE_COMPLETE;
5421
goto return_from_bridge;
5426
/* Swap who gets priority */
5427
priority = !priority;
5432
dahdi_enable_ec(p0);
5435
dahdi_enable_ec(p1);
5437
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0) && (oi0 == SUB_REAL))
5438
enable_dtmf_detect(op0);
5440
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1) && (oi1 == SUB_REAL))
5441
enable_dtmf_detect(op1);
5443
dahdi_unlink(slave, master, 1);
5448
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
5450
struct dahdi_pvt *p = newchan->tech_pvt;
5452
ast_mutex_lock(&p->lock);
5453
ast_debug(1, "New owner for channel %d is %s\n", p->channel, newchan->name);
5454
if (p->owner == oldchan) {
5457
for (x = 0; x < 3; x++)
5458
if (p->subs[x].owner == oldchan) {
5460
dahdi_unlink(NULL, p, 0);
5461
p->subs[x].owner = newchan;
5463
if (newchan->_state == AST_STATE_RINGING)
5464
dahdi_indicate(newchan, AST_CONTROL_RINGING, NULL, 0);
5466
ast_mutex_unlock(&p->lock);
5470
static int dahdi_ring_phone(struct dahdi_pvt *p)
5474
/* Make sure our transmit state is on hook */
5477
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
5480
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
5485
/* Wait just in case */
5492
ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
5500
static void *ss_thread(void *data);
5502
static int attempt_transfer(struct dahdi_pvt *p)
5504
/* In order to transfer, we need at least one of the channels to
5505
actually be in a call bridge. We can't conference two applications
5506
together (but then, why would we want to?) */
5507
if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
5508
/* The three-way person we're about to transfer to could still be in MOH, so
5509
stop if now if appropriate */
5510
if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner))
5511
ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
5512
if (p->subs[SUB_REAL].owner->_state == AST_STATE_RINGING) {
5513
ast_indicate(ast_bridged_channel(p->subs[SUB_REAL].owner), AST_CONTROL_RINGING);
5515
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RING) {
5516
tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
5518
if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
5519
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
5520
ast_bridged_channel(p->subs[SUB_REAL].owner)->name, p->subs[SUB_THREEWAY].owner->name);
5523
/* Orphan the channel after releasing the lock */
5524
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5525
unalloc_sub(p, SUB_THREEWAY);
5526
} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
5527
ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
5528
if (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_RINGING) {
5529
ast_indicate(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), AST_CONTROL_RINGING);
5531
if (p->subs[SUB_REAL].owner->_state == AST_STATE_RING) {
5532
tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
5534
if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
5535
ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
5536
ast_bridged_channel(p->subs[SUB_THREEWAY].owner)->name, p->subs[SUB_REAL].owner->name);
5539
/* Three-way is now the REAL */
5540
swap_subs(p, SUB_THREEWAY, SUB_REAL);
5541
ast_channel_unlock(p->subs[SUB_REAL].owner);
5542
unalloc_sub(p, SUB_THREEWAY);
5543
/* Tell the caller not to hangup */
5546
ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
5547
p->subs[SUB_REAL].owner->name, p->subs[SUB_THREEWAY].owner->name);
5548
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
5554
static int check_for_conference(struct dahdi_pvt *p)
5556
struct dahdi_confinfo ci;
5557
/* Fine if we already have a master, etc */
5558
if (p->master || (p->confno > -1))
5560
memset(&ci, 0, sizeof(ci));
5561
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
5562
ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n", p->channel, strerror(errno));
5565
/* If we have no master and don't have a confno, then
5566
if we're in a conference, it's probably a MeetMe room or
5567
some such, so don't let us 3-way out! */
5568
if ((p->subs[SUB_REAL].curconf.confno != ci.confno) || (p->subs[SUB_REAL].curconf.confmode != ci.confmode)) {
5569
ast_verb(3, "Avoiding 3-way call when in an external conference\n");
5575
/*! Checks channel for alarms
5576
* \param p a channel to check for alarms.
5577
* \returns the alarms on the span to which the channel belongs, or alarms on
5578
* the channel if no span alarms.
5580
static int get_alarms(struct dahdi_pvt *p)
5583
struct dahdi_spaninfo zi;
5584
struct dahdi_params params;
5586
memset(&zi, 0, sizeof(zi));
5587
zi.spanno = p->span;
5589
if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &zi)) >= 0) {
5590
if (zi.alarms != DAHDI_ALARM_NONE)
5593
ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
5597
/* No alarms on the span. Check for channel alarms. */
5598
memset(¶ms, 0, sizeof(params));
5599
if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0)
5600
return params.chan_alarms;
5602
ast_log(LOG_WARNING, "Unable to determine alarm on channel %d\n", p->channel);
5604
return DAHDI_ALARM_NONE;
5607
static void dahdi_handle_dtmfup(struct ast_channel *ast, int idx, struct ast_frame **dest)
5609
struct dahdi_pvt *p = ast->tech_pvt;
5610
struct ast_frame *f = *dest;
5612
ast_debug(1, "DTMF digit: %c on %s\n", f->subclass, ast->name);
5614
if (p->confirmanswer) {
5615
ast_debug(1, "Confirm answer on %s!\n", ast->name);
5616
/* Upon receiving a DTMF digit, consider this an answer confirmation instead
5618
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
5619
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
5620
*dest = &p->subs[idx].f;
5621
/* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
5622
p->confirmanswer = 0;
5623
} else if (p->callwaitcas) {
5624
if ((f->subclass == 'A') || (f->subclass == 'D')) {
5625
ast_debug(1, "Got some DTMF, but it's for the CAS\n");
5627
ast_free(p->cidspill);
5631
p->subs[idx].f.frametype = AST_FRAME_NULL;
5632
p->subs[idx].f.subclass = 0;
5633
*dest = &p->subs[idx].f;
5634
} else if (f->subclass == 'f') {
5635
/* Fax tone -- Handle and return NULL */
5636
if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
5637
/* If faxbuffers are configured, use them for the fax transmission */
5638
if (p->usefaxbuffers && !p->faxbuffersinuse) {
5639
struct dahdi_bufferinfo bi = {
5640
.txbufpolicy = p->faxbuf_policy,
5641
.bufsize = p->bufsize,
5642
.numbufs = p->faxbuf_no
5646
if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
5647
ast_log(LOG_WARNING, "Channel '%s' unable to set faxbuffer policy, reason: %s\n", ast->name, strerror(errno));
5649
p->faxbuffersinuse = 1;
5653
if (strcmp(ast->exten, "fax")) {
5654
const char *target_context = S_OR(ast->macrocontext, ast->context);
5656
/* We need to unlock 'ast' here because ast_exists_extension has the
5657
* potential to start autoservice on the channel. Such action is prone
5660
ast_mutex_unlock(&p->lock);
5661
ast_channel_unlock(ast);
5662
if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
5663
ast_channel_lock(ast);
5664
ast_mutex_lock(&p->lock);
5665
ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
5666
/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
5667
pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
5668
if (ast_async_goto(ast, target_context, "fax", 1))
5669
ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
5671
ast_channel_lock(ast);
5672
ast_mutex_lock(&p->lock);
5673
ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
5676
ast_debug(1, "Already in a fax extension, not redirecting\n");
5679
ast_debug(1, "Fax already handled\n");
5681
dahdi_confmute(p, 0);
5682
p->subs[idx].f.frametype = AST_FRAME_NULL;
5683
p->subs[idx].f.subclass = 0;
5684
*dest = &p->subs[idx].f;
5688
static void handle_alarms(struct dahdi_pvt *p, int alms)
5690
const char *alarm_str = alarm2str(alms);
5692
ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
5693
manager_event(EVENT_FLAG_SYSTEM, "Alarm",
5696
alarm_str, p->channel);
5699
static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
5704
struct dahdi_pvt *p = ast->tech_pvt;
5706
struct ast_channel *chan;
5707
struct ast_frame *f;
5709
idx = dahdi_get_index(ast, p, 0);
5711
if (p->outsigmod > -1)
5712
mysig = p->outsigmod;
5713
p->subs[idx].f.frametype = AST_FRAME_NULL;
5714
p->subs[idx].f.subclass = 0;
5715
p->subs[idx].f.datalen = 0;
5716
p->subs[idx].f.samples = 0;
5717
p->subs[idx].f.mallocd = 0;
5718
p->subs[idx].f.offset = 0;
5719
p->subs[idx].f.src = "dahdi_handle_event";
5720
p->subs[idx].f.data.ptr = NULL;
5721
f = &p->subs[idx].f;
5724
return &p->subs[idx].f;
5725
if (p->fake_event) {
5726
res = p->fake_event;
5729
res = dahdi_get_event(p->subs[idx].dfd);
5731
ast_debug(1, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, idx);
5733
if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
5734
p->pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
5735
ast_debug(1, "Detected %sdigit '%c'\n", p->pulsedial ? "pulse ": "", res & 0xff);
5737
if (!p->proceeding && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) && p->pri && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
5741
dahdi_confmute(p, 0);
5742
p->subs[idx].f.frametype = AST_FRAME_DTMF_END;
5743
p->subs[idx].f.subclass = res & 0xff;
5747
dahdi_handle_dtmfup(ast, idx, &f);
5751
if (res & DAHDI_EVENT_DTMFDOWN) {
5752
ast_debug(1, "DTMF Down '%c'\n", res & 0xff);
5753
/* Mute conference */
5754
dahdi_confmute(p, 1);
5755
p->subs[idx].f.frametype = AST_FRAME_DTMF_BEGIN;
5756
p->subs[idx].f.subclass = res & 0xff;
5757
return &p->subs[idx].f;
5761
case DAHDI_EVENT_EC_DISABLED:
5762
ast_verb(3, "Channel %d echo canceler disabled due to CED detection\n", p->channel);
5765
case DAHDI_EVENT_BITSCHANGED:
5767
if (p->sig != SIG_MFCR2) {
5768
ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
5770
ast_log(LOG_DEBUG, "bits changed in chan %d\n", p->channel);
5771
openr2_chan_handle_cas(p->r2chan);
5774
ast_log(LOG_WARNING, "Received bits changed on %s signalling?\n", sig2str(p->sig));
5776
case DAHDI_EVENT_PULSE_START:
5777
/* Stop tone if there's a pulse start and the PBX isn't started */
5779
tone_zone_play_tone(p->subs[idx].dfd, -1);
5781
case DAHDI_EVENT_DIALCOMPLETE:
5783
if ((p->sig & SIG_MFCR2) && p->r2chan && ast->_state != AST_STATE_UP) {
5784
/* we don't need to do anything for this event for R2 signaling
5785
if the call is being setup */
5789
if (p->inalarm) break;
5790
if ((p->radio || (p->oprmode < 0))) break;
5791
if (ioctl(p->subs[idx].dfd,DAHDI_DIALING,&x) == -1) {
5792
ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed on %s: %s\n",ast->name, strerror(errno));
5795
if (!x) { /* if not still dialing in driver */
5799
ast_copy_string(p->dop.dialstr, p->echorest, sizeof(p->dop.dialstr));
5800
p->dop.op = DAHDI_DIAL_OP_REPLACE;
5801
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
5805
if ((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) {
5806
/* if thru with dialing after offhook */
5807
if (ast->_state == AST_STATE_DIALING_OFFHOOK) {
5808
ast_setstate(ast, AST_STATE_UP);
5809
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
5810
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
5812
} else { /* if to state wait for offhook to dial rest */
5813
/* we now wait for off hook */
5814
ast_setstate(ast,AST_STATE_DIALING_OFFHOOK);
5817
if (ast->_state == AST_STATE_DIALING) {
5818
if ((p->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
5819
ast_debug(1, "Done dialing, but waiting for progress detection before doing more...\n");
5820
} else if (p->confirmanswer || (!p->dialednone
5821
&& ((mysig == SIG_EM) || (mysig == SIG_EM_E1)
5822
|| (mysig == SIG_EMWINK) || (mysig == SIG_FEATD)
5823
|| (mysig == SIG_FEATDMF_TA) || (mysig == SIG_FEATDMF)
5824
|| (mysig == SIG_E911) || (mysig == SIG_FGC_CAMA)
5825
|| (mysig == SIG_FGC_CAMAMF) || (mysig == SIG_FEATB)
5826
|| (mysig == SIG_SF) || (mysig == SIG_SFWINK)
5827
|| (mysig == SIG_SF_FEATD) || (mysig == SIG_SF_FEATDMF)
5828
|| (mysig == SIG_SF_FEATB)))) {
5829
ast_setstate(ast, AST_STATE_RINGING);
5830
} else if (!p->answeronpolarityswitch) {
5831
ast_setstate(ast, AST_STATE_UP);
5832
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
5833
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
5834
/* If aops=0 and hops=1, this is necessary */
5835
p->polarity = POLARITY_REV;
5837
/* Start clean, so we can catch the change to REV polarity when party answers */
5838
p->polarity = POLARITY_IDLE;
5844
case DAHDI_EVENT_ALARM:
5846
if ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
5847
if (!p->pri || !p->pri->pri || (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0)) {
5848
/* T309 is not enabled : hangup calls when alarm occurs */
5850
if (p->pri && p->pri->pri) {
5851
if (!pri_grab(p, p->pri)) {
5852
pri_hangup(p->pri->pri, p->call, -1);
5853
pri_destroycall(p->pri->pri, p->call);
5857
ast_log(LOG_WARNING, "Failed to grab PRI!\n");
5859
ast_log(LOG_WARNING, "The PRI Call has not been destroyed\n");
5862
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
5866
p->bearer->inalarm = 1;
5870
res = get_alarms(p);
5871
handle_alarms(p, res);
5873
if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
5874
/* fall through intentionally */
5880
if (p->sig == SIG_SS7)
5884
if (p->sig == SIG_MFCR2)
5887
case DAHDI_EVENT_ONHOOK:
5889
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
5890
p->subs[idx].f.subclass = AST_CONTROL_RADIO_UNKEY;
5895
if (p->oprmode != -1) break;
5896
if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
5898
/* Make sure it starts ringing */
5899
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
5900
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RING);
5901
save_conference(p->oprpeer);
5902
tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
5910
p->onhooktime = time(NULL);
5911
p->fxsoffhookstate = 0;
5913
/* Check for some special conditions regarding call waiting */
5914
if (idx == SUB_REAL) {
5915
/* The normal line was hung up */
5916
if (p->subs[SUB_CALLWAIT].owner) {
5917
/* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
5918
swap_subs(p, SUB_CALLWAIT, SUB_REAL);
5919
ast_verb(3, "Channel %d still has (callwait) call, ringing phone\n", p->channel);
5920
unalloc_sub(p, SUB_CALLWAIT);
5922
p->subs[idx].needanswer = 0;
5923
p->subs[idx].needringing = 0;
5925
p->callwaitingrepeat = 0;
5928
/* Don't start streaming audio yet if the incoming call isn't up yet */
5929
if (p->subs[SUB_REAL].owner->_state != AST_STATE_UP)
5931
dahdi_ring_phone(p);
5932
} else if (p->subs[SUB_THREEWAY].owner) {
5933
unsigned int mssinceflash;
5934
/* Here we have to retain the lock on both the main channel, the 3-way channel, and
5935
the private structure -- not especially easy or clean */
5936
while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
5937
/* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
5938
DLA_UNLOCK(&p->lock);
5939
CHANNEL_DEADLOCK_AVOIDANCE(ast);
5940
/* We can grab ast and p in that order, without worry. We should make sure
5941
nothing seriously bad has happened though like some sort of bizarre double
5944
if (p->owner != ast) {
5945
ast_log(LOG_WARNING, "This isn't good...\n");
5949
if (!p->subs[SUB_THREEWAY].owner) {
5950
ast_log(LOG_NOTICE, "Whoa, threeway disappeared kinda randomly.\n");
5953
mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
5954
ast_debug(1, "Last flash was %d ms ago\n", mssinceflash);
5955
if (mssinceflash < MIN_MS_SINCE_FLASH) {
5956
/* It hasn't been long enough since the last flashook. This is probably a bounce on
5957
hanging up. Hangup both channels now */
5958
if (p->subs[SUB_THREEWAY].owner)
5959
ast_queue_hangup_with_cause(p->subs[SUB_THREEWAY].owner, AST_CAUSE_NO_ANSWER);
5960
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
5961
ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
5962
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5963
} else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
5965
/* In any case this isn't a threeway call anymore */
5966
p->subs[SUB_REAL].inthreeway = 0;
5967
p->subs[SUB_THREEWAY].inthreeway = 0;
5968
/* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
5969
if (!p->transfertobusy && ast->_state == AST_STATE_BUSY) {
5970
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5971
/* Swap subs and dis-own channel */
5972
swap_subs(p, SUB_THREEWAY, SUB_REAL);
5974
/* Ring the phone */
5975
dahdi_ring_phone(p);
5977
if ((res = attempt_transfer(p)) < 0) {
5978
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
5979
if (p->subs[SUB_THREEWAY].owner)
5980
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5982
/* Don't actually hang up at this point */
5983
if (p->subs[SUB_THREEWAY].owner)
5984
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5989
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
5990
if (p->subs[SUB_THREEWAY].owner)
5991
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5994
ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
5995
/* Swap subs and dis-own channel */
5996
swap_subs(p, SUB_THREEWAY, SUB_REAL);
5998
/* Ring the phone */
5999
dahdi_ring_phone(p);
6003
ast_log(LOG_WARNING, "Got a hangup and my index is %d?\n", idx);
6007
dahdi_disable_ec(p);
6011
case DAHDI_EVENT_RINGOFFHOOK:
6012
if (p->inalarm) break;
6015
if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
6017
/* Make sure it stops ringing */
6018
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
6019
tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].dfd, -1);
6020
restore_conference(p->oprpeer);
6026
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6027
p->subs[idx].f.subclass = AST_CONTROL_RADIO_KEY;
6030
/* for E911, its supposed to wait for offhook then dial
6031
the second half of the dial string */
6032
if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
6033
c = strchr(p->dialdest, '/');
6038
if (*c) snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*0%s#", c);
6039
else ast_copy_string(p->dop.dialstr,"M*2#", sizeof(p->dop.dialstr));
6040
if (strlen(p->dop.dialstr) > 4) {
6041
memset(p->echorest, 'w', sizeof(p->echorest) - 1);
6042
strcpy(p->echorest + (p->echotraining / 401) + 1, p->dop.dialstr + strlen(p->dop.dialstr) - 2);
6043
p->echorest[sizeof(p->echorest) - 1] = '\0';
6045
p->dop.dialstr[strlen(p->dop.dialstr)-2] = '\0';
6048
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop)) {
6049
int saveerr = errno;
6052
ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
6053
ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(saveerr));
6057
return &p->subs[idx].f;
6063
p->fxsoffhookstate = 1;
6064
switch (ast->_state) {
6065
case AST_STATE_RINGING:
6068
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6069
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
6070
/* Make sure it stops ringing */
6071
dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
6072
ast_debug(1, "channel %d answered\n", p->channel);
6074
/* Cancel any running CallerID spill */
6075
ast_free(p->cidspill);
6080
if (p->confirmanswer) {
6081
/* Ignore answer if "confirm answer" is enabled */
6082
p->subs[idx].f.frametype = AST_FRAME_NULL;
6083
p->subs[idx].f.subclass = 0;
6084
} else if (!ast_strlen_zero(p->dop.dialstr)) {
6085
/* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
6086
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
6088
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
6089
p->dop.dialstr[0] = '\0';
6092
ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
6093
p->subs[idx].f.frametype = AST_FRAME_NULL;
6094
p->subs[idx].f.subclass = 0;
6097
p->dop.dialstr[0] = '\0';
6098
ast_setstate(ast, AST_STATE_DIALING);
6100
ast_setstate(ast, AST_STATE_UP);
6101
return &p->subs[idx].f;
6102
case AST_STATE_DOWN:
6103
ast_setstate(ast, AST_STATE_RING);
6105
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6106
p->subs[idx].f.subclass = AST_CONTROL_OFFHOOK;
6107
ast_debug(1, "channel %d picked up\n", p->channel);
6108
return &p->subs[idx].f;
6110
/* Make sure it stops ringing */
6111
dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
6112
/* Okay -- probably call waiting*/
6113
if (ast_bridged_channel(p->owner))
6114
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
6115
p->subs[idx].needunhold = 1;
6117
case AST_STATE_RESERVED:
6118
/* Start up dialtone */
6119
if (has_voicemail(p))
6120
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
6122
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
6125
ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->_state);
6131
if (ast->_state == AST_STATE_RING) {
6132
p->ringt = p->ringt_base;
6135
/* If we get a ring then we cannot be in
6136
* reversed polarity. So we reset to idle */
6137
ast_debug(1, "Setting IDLE polarity due "
6138
"to ring. Old polarity was %d\n",
6140
p->polarity = POLARITY_IDLE;
6148
case SIG_FEATDMF_TA:
6151
case SIG_FGC_CAMAMF:
6156
case SIG_SF_FEATDMF:
6158
if (ast->_state == AST_STATE_PRERING)
6159
ast_setstate(ast, AST_STATE_RING);
6160
if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
6161
ast_debug(1, "Ring detected\n");
6162
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6163
p->subs[idx].f.subclass = AST_CONTROL_RING;
6164
} else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
6165
ast_debug(1, "Line answered\n");
6166
if (p->confirmanswer) {
6167
p->subs[idx].f.frametype = AST_FRAME_NULL;
6168
p->subs[idx].f.subclass = 0;
6170
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6171
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
6172
ast_setstate(ast, AST_STATE_UP);
6174
} else if (ast->_state != AST_STATE_RING)
6175
ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->_state, p->channel);
6178
ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
6181
case DAHDI_EVENT_RINGBEGIN:
6186
if (ast->_state == AST_STATE_RING) {
6187
p->ringt = p->ringt_base;
6192
case DAHDI_EVENT_RINGEROFF:
6193
if (p->inalarm) break;
6194
if ((p->radio || (p->oprmode < 0))) break;
6196
if ((ast->rings > p->cidrings) && (p->cidspill)) {
6197
ast_log(LOG_WARNING, "Didn't finish Caller-ID spill. Cancelling.\n");
6198
ast_free(p->cidspill);
6202
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6203
p->subs[idx].f.subclass = AST_CONTROL_RINGING;
6205
case DAHDI_EVENT_RINGERON:
6207
case DAHDI_EVENT_NOALARM:
6210
/* Extremely unlikely but just in case */
6212
p->bearer->inalarm = 0;
6214
ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
6215
manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
6216
"Channel: %d\r\n", p->channel);
6218
case DAHDI_EVENT_WINKFLASH:
6219
if (p->inalarm) break;
6220
if (p->radio) break;
6221
if (p->oprmode < 0) break;
6224
struct dahdi_params par;
6226
memset(&par, 0, sizeof(par));
6227
if (ioctl(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par) != -1)
6229
if (!par.rxisoffhook)
6231
/* Make sure it stops ringing */
6232
dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RINGOFF);
6233
dahdi_set_hook(p->oprpeer->subs[SUB_REAL].dfd, DAHDI_RING);
6235
tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
6240
/* Remember last time we got a flash-hook */
6241
p->flashtime = ast_tvnow();
6246
ast_debug(1, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
6247
idx, p->subs[SUB_REAL].dfd, p->subs[SUB_CALLWAIT].dfd, p->subs[SUB_THREEWAY].dfd);
6250
if (idx != SUB_REAL) {
6251
ast_log(LOG_WARNING, "Got flash hook with index %d on channel %d?!?\n", idx, p->channel);
6255
if (p->subs[SUB_CALLWAIT].owner) {
6256
/* Swap to call-wait */
6257
swap_subs(p, SUB_REAL, SUB_CALLWAIT);
6258
tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
6259
p->owner = p->subs[SUB_REAL].owner;
6260
ast_debug(1, "Making %s the new owner\n", p->owner->name);
6261
if (p->owner->_state == AST_STATE_RINGING) {
6262
ast_setstate(p->owner, AST_STATE_UP);
6263
p->subs[SUB_REAL].needanswer = 1;
6265
p->callwaitingrepeat = 0;
6267
/* Start music on hold if appropriate */
6268
if (!p->subs[SUB_CALLWAIT].inthreeway && ast_bridged_channel(p->subs[SUB_CALLWAIT].owner)) {
6269
ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
6270
S_OR(p->mohsuggest, NULL),
6271
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
6273
p->subs[SUB_CALLWAIT].needhold = 1;
6274
if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
6275
ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
6276
S_OR(p->mohsuggest, NULL),
6277
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
6279
p->subs[SUB_REAL].needunhold = 1;
6280
} else if (!p->subs[SUB_THREEWAY].owner) {
6281
if (!p->threewaycalling) {
6282
/* Just send a flash if no 3-way calling */
6283
p->subs[SUB_REAL].needflash = 1;
6285
} else if (!check_for_conference(p)) {
6291
if (p->dahditrcallerid && p->owner) {
6292
if (p->owner->cid.cid_num)
6293
ast_copy_string(cid_num, p->owner->cid.cid_num, sizeof(cid_num));
6294
if (p->owner->cid.cid_name)
6295
ast_copy_string(cid_name, p->owner->cid.cid_name, sizeof(cid_name));
6297
/* XXX This section needs much more error checking!!! XXX */
6298
/* Start a 3-way call if feasible */
6300
(ast->_state == AST_STATE_UP) ||
6301
(ast->_state == AST_STATE_RING))) {
6302
ast_debug(1, "Flash when call not up or ringing\n");
6305
if (alloc_sub(p, SUB_THREEWAY)) {
6306
ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
6309
/* Make new channel */
6310
chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0);
6311
if (p->dahditrcallerid) {
6312
if (!p->origcid_num)
6313
p->origcid_num = ast_strdup(p->cid_num);
6314
if (!p->origcid_name)
6315
p->origcid_name = ast_strdup(p->cid_name);
6316
ast_copy_string(p->cid_num, cid_num, sizeof(p->cid_num));
6317
ast_copy_string(p->cid_name, cid_name, sizeof(p->cid_name));
6319
/* Swap things around between the three-way and real call */
6320
swap_subs(p, SUB_THREEWAY, SUB_REAL);
6321
/* Disable echo canceller for better dialing */
6322
dahdi_disable_ec(p);
6323
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_DIALRECALL);
6325
ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
6328
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->channel);
6329
} else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
6330
ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
6331
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
6335
struct ast_channel *other = ast_bridged_channel(p->subs[SUB_THREEWAY].owner);
6336
int way3bridge = 0, cdr3way = 0;
6339
other = ast_bridged_channel(p->subs[SUB_REAL].owner);
6343
if (p->subs[SUB_THREEWAY].owner->cdr)
6346
ast_verb(3, "Started three way call on channel %d\n", p->channel);
6348
/* Start music on hold if appropriate */
6349
if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
6350
ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
6351
S_OR(p->mohsuggest, NULL),
6352
!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
6354
p->subs[SUB_THREEWAY].needhold = 1;
6358
/* Already have a 3 way call */
6359
if (p->subs[SUB_THREEWAY].inthreeway) {
6360
/* Call is already up, drop the last person */
6361
ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
6362
/* If the primary call isn't answered yet, use it */
6363
if ((p->subs[SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
6364
/* Swap back -- we're dropping the real 3-way that isn't finished yet*/
6365
swap_subs(p, SUB_THREEWAY, SUB_REAL);
6366
p->owner = p->subs[SUB_REAL].owner;
6368
/* Drop the last call and stop the conference */
6369
ast_verb(3, "Dropping three-way call on %s\n", p->subs[SUB_THREEWAY].owner->name);
6370
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
6371
p->subs[SUB_REAL].inthreeway = 0;
6372
p->subs[SUB_THREEWAY].inthreeway = 0;
6374
/* Lets see what we're up to */
6375
if (((ast->pbx) || (ast->_state == AST_STATE_UP)) &&
6376
(p->transfertobusy || (ast->_state != AST_STATE_BUSY))) {
6377
int otherindex = SUB_THREEWAY;
6378
struct ast_channel *other = ast_bridged_channel(p->subs[SUB_THREEWAY].owner);
6379
int way3bridge = 0, cdr3way = 0;
6382
other = ast_bridged_channel(p->subs[SUB_REAL].owner);
6386
if (p->subs[SUB_THREEWAY].owner->cdr)
6389
ast_verb(3, "Building conference on call on %s and %s\n", p->subs[SUB_THREEWAY].owner->name, p->subs[SUB_REAL].owner->name);
6390
/* Put them in the threeway, and flip */
6391
p->subs[SUB_THREEWAY].inthreeway = 1;
6392
p->subs[SUB_REAL].inthreeway = 1;
6393
if (ast->_state == AST_STATE_UP) {
6394
swap_subs(p, SUB_THREEWAY, SUB_REAL);
6395
otherindex = SUB_REAL;
6397
if (p->subs[otherindex].owner && ast_bridged_channel(p->subs[otherindex].owner))
6398
ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
6399
p->subs[otherindex].needunhold = 1;
6400
p->owner = p->subs[SUB_REAL].owner;
6401
if (ast->_state == AST_STATE_RINGING) {
6402
ast_debug(1, "Enabling ringtone on real and threeway\n");
6403
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
6404
res = tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
6407
ast_verb(3, "Dumping incomplete call on on %s\n", p->subs[SUB_THREEWAY].owner->name);
6408
swap_subs(p, SUB_THREEWAY, SUB_REAL);
6409
p->subs[SUB_THREEWAY].owner->_softhangup |= AST_SOFTHANGUP_DEV;
6410
p->owner = p->subs[SUB_REAL].owner;
6411
if (p->subs[SUB_REAL].owner && ast_bridged_channel(p->subs[SUB_REAL].owner))
6412
ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
6413
p->subs[SUB_REAL].needunhold = 1;
6431
ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
6433
ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
6436
case SIG_FEATDMF_TA:
6437
switch (p->whichwink) {
6439
ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
6440
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
6443
ast_copy_string(p->dop.dialstr, p->finaldial, sizeof(p->dop.dialstr));
6446
ast_log(LOG_WARNING, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
6453
case SIG_FGC_CAMAMF:
6456
case SIG_SF_FEATDMF:
6459
/* FGD MF and EMWINK *Must* wait for wink */
6460
if (!ast_strlen_zero(p->dop.dialstr)) {
6461
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
6463
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
6464
p->dop.dialstr[0] = '\0';
6467
ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
6469
p->dop.dialstr[0] = '\0';
6472
ast_log(LOG_WARNING, "Don't know how to handle ring/off hook for signalling %d\n", p->sig);
6475
case DAHDI_EVENT_HOOKCOMPLETE:
6476
if (p->inalarm) break;
6477
if ((p->radio || (p->oprmode < 0))) break;
6478
if (p->waitingfordt.tv_sec) break;
6480
case SIG_FXSLS: /* only interesting for FXS */
6490
if (!ast_strlen_zero(p->dop.dialstr)) {
6491
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
6493
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", p->channel, strerror(errno));
6494
p->dop.dialstr[0] = '\0';
6497
ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
6499
p->dop.dialstr[0] = '\0';
6500
p->dop.op = DAHDI_DIAL_OP_REPLACE;
6503
case SIG_FEATDMF_TA:
6506
case SIG_FGC_CAMAMF:
6508
case SIG_SF_FEATDMF:
6510
ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
6516
case DAHDI_EVENT_POLARITY:
6518
* If we get a Polarity Switch event, this could be
6519
* due to line seizure, remote end connect or remote end disconnect.
6521
* Check to see if we should change the polarity state and
6522
* mark the channel as UP or if this is an indication
6523
* of remote end disconnect.
6526
if (p->polarityonanswerdelay > 0) {
6527
/* check if event is not too soon after OffHook or Answer */
6528
if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
6529
switch (ast->_state) {
6530
case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */
6531
case AST_STATE_RINGING: /*!< Remote end is ringing */
6532
if (p->answeronpolarityswitch) {
6533
ast_debug(1, "Answering on polarity switch! channel %d\n", p->channel);
6534
ast_setstate(p->owner, AST_STATE_UP);
6535
p->polarity = POLARITY_REV;
6536
if (p->hanguponpolarityswitch) {
6537
p->polaritydelaytv = ast_tvnow();
6540
ast_debug(1, "Ignore Answer on polarity switch, channel %d\n", p->channel);
6544
case AST_STATE_UP: /*!< Line is up */
6545
case AST_STATE_RING: /*!< Line is ringing */
6546
if (p->hanguponpolarityswitch) {
6547
ast_debug(1, "HangingUp on polarity switch! channel %d\n", p->channel);
6548
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
6549
p->polarity = POLARITY_IDLE;
6551
ast_debug(1, "Ignore Hangup on polarity switch, channel %d\n", p->channel);
6555
case AST_STATE_DOWN: /*!< Channel is down and available */
6556
case AST_STATE_RESERVED: /*!< Channel is down, but reserved */
6557
case AST_STATE_OFFHOOK: /*!< Channel is off hook */
6558
case AST_STATE_BUSY: /*!< Line is busy */
6559
case AST_STATE_DIALING_OFFHOOK: /*!< Digits (or equivalent) have been dialed while offhook */
6560
case AST_STATE_PRERING: /*!< Channel has detected an incoming call and is waiting for ring */
6562
if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
6563
ast_debug(1, "Ignoring Polarity switch on channel %d, state %d\n", p->channel, ast->_state);
6568
/* event is too soon after OffHook or Answer */
6569
switch (ast->_state) {
6570
case AST_STATE_DIALING: /*!< Digits (or equivalent) have been dialed */
6571
case AST_STATE_RINGING: /*!< Remote end is ringing */
6572
if (p->answeronpolarityswitch) {
6573
ast_debug(1, "Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %d\n", p->channel, ast->_state);
6577
case AST_STATE_UP: /*!< Line is up */
6578
case AST_STATE_RING: /*!< Line is ringing */
6579
if (p->hanguponpolarityswitch) {
6580
ast_debug(1, "Polarity switch detected but NOT hanging up (too close to Answer event) on channel %d, state %d\n", p->channel, ast->_state);
6585
if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
6586
ast_debug(1, "Polarity switch detected (too close to previous event) on channel %d, state %d\n", p->channel, ast->_state);
6592
/* Added more log_debug information below to provide a better indication of what is going on */
6593
ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
6596
ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
6598
return &p->subs[idx].f;
6601
static struct ast_frame *__dahdi_exception(struct ast_channel *ast)
6603
struct dahdi_pvt *p = ast->tech_pvt;
6607
struct ast_frame *f;
6610
idx = dahdi_get_index(ast, p, 1);
6612
p->subs[idx].f.frametype = AST_FRAME_NULL;
6613
p->subs[idx].f.datalen = 0;
6614
p->subs[idx].f.samples = 0;
6615
p->subs[idx].f.mallocd = 0;
6616
p->subs[idx].f.offset = 0;
6617
p->subs[idx].f.subclass = 0;
6618
p->subs[idx].f.delivery = ast_tv(0,0);
6619
p->subs[idx].f.src = "dahdi_exception";
6620
p->subs[idx].f.data.ptr = NULL;
6623
if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
6624
/* If nobody owns us, absorb the event appropriately, otherwise
6625
we loop indefinitely. This occurs when, during call waiting, the
6626
other end hangs up our channel so that it no longer exists, but we
6627
have neither FLASH'd nor ONHOOK'd to signify our desire to
6628
change to the other channel. */
6629
if (p->fake_event) {
6630
res = p->fake_event;
6633
res = dahdi_get_event(p->subs[SUB_REAL].dfd);
6634
/* Switch to real if there is one and this isn't something really silly... */
6635
if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
6636
(res != DAHDI_EVENT_HOOKCOMPLETE)) {
6637
ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
6638
p->owner = p->subs[SUB_REAL].owner;
6639
if (p->owner && ast_bridged_channel(p->owner))
6640
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
6641
p->subs[SUB_REAL].needunhold = 1;
6644
case DAHDI_EVENT_ONHOOK:
6645
dahdi_disable_ec(p);
6647
ast_verb(3, "Channel %s still has call, ringing phone\n", p->owner->name);
6648
dahdi_ring_phone(p);
6649
p->callwaitingrepeat = 0;
6652
ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
6655
case DAHDI_EVENT_RINGOFFHOOK:
6657
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
6658
if (p->owner && (p->owner->_state == AST_STATE_RINGING)) {
6659
p->subs[SUB_REAL].needanswer = 1;
6663
case DAHDI_EVENT_HOOKCOMPLETE:
6664
case DAHDI_EVENT_RINGERON:
6665
case DAHDI_EVENT_RINGEROFF:
6668
case DAHDI_EVENT_WINKFLASH:
6669
p->flashtime = ast_tvnow();
6671
ast_verb(3, "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
6672
if (p->owner->_state != AST_STATE_UP) {
6673
/* Answer if necessary */
6674
usedindex = dahdi_get_index(p->owner, p, 0);
6675
if (usedindex > -1) {
6676
p->subs[usedindex].needanswer = 1;
6678
ast_setstate(p->owner, AST_STATE_UP);
6680
p->callwaitingrepeat = 0;
6682
if (ast_bridged_channel(p->owner))
6683
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
6684
p->subs[SUB_REAL].needunhold = 1;
6686
ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
6690
ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
6692
f = &p->subs[idx].f;
6695
if (!(p->radio || (p->oprmode < 0)))
6696
ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
6697
/* If it's not us, return NULL immediately */
6698
if (ast != p->owner) {
6699
ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
6700
f = &p->subs[idx].f;
6703
f = dahdi_handle_event(ast);
6707
static struct ast_frame *dahdi_exception(struct ast_channel *ast)
6709
struct dahdi_pvt *p = ast->tech_pvt;
6710
struct ast_frame *f;
6711
ast_mutex_lock(&p->lock);
6712
f = __dahdi_exception(ast);
6713
ast_mutex_unlock(&p->lock);
6717
static struct ast_frame *dahdi_read(struct ast_channel *ast)
6719
struct dahdi_pvt *p = ast->tech_pvt;
6723
struct ast_frame *f;
6725
while (ast_mutex_trylock(&p->lock)) {
6726
CHANNEL_DEADLOCK_AVOIDANCE(ast);
6729
idx = dahdi_get_index(ast, p, 0);
6731
/* Hang up if we don't really exist */
6733
ast_log(LOG_WARNING, "We dont exist?\n");
6734
ast_mutex_unlock(&p->lock);
6738
if ((p->radio || (p->oprmode < 0)) && p->inalarm) {
6739
ast_mutex_unlock(&p->lock);
6743
p->subs[idx].f.frametype = AST_FRAME_NULL;
6744
p->subs[idx].f.datalen = 0;
6745
p->subs[idx].f.samples = 0;
6746
p->subs[idx].f.mallocd = 0;
6747
p->subs[idx].f.offset = 0;
6748
p->subs[idx].f.subclass = 0;
6749
p->subs[idx].f.delivery = ast_tv(0,0);
6750
p->subs[idx].f.src = "dahdi_read";
6751
p->subs[idx].f.data.ptr = NULL;
6753
/* make sure it sends initial key state as first frame */
6754
if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
6756
struct dahdi_params ps;
6758
memset(&ps, 0, sizeof(ps));
6759
ps.channo = p->channel;
6760
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
6761
ast_mutex_unlock(&p->lock);
6765
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6768
p->subs[idx].f.subclass = AST_CONTROL_RADIO_KEY;
6772
p->subs[idx].f.subclass = AST_CONTROL_RADIO_UNKEY;
6774
ast_mutex_unlock(&p->lock);
6775
return &p->subs[idx].f;
6777
if (p->ringt == 1) {
6778
ast_mutex_unlock(&p->lock);
6781
else if (p->ringt > 0)
6786
openr2_chan_process_event(p->r2chan);
6790
if (p->subs[idx].needringing) {
6791
/* Send ringing frame if requested */
6792
p->subs[idx].needringing = 0;
6793
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6794
p->subs[idx].f.subclass = AST_CONTROL_RINGING;
6795
ast_setstate(ast, AST_STATE_RINGING);
6796
ast_mutex_unlock(&p->lock);
6797
return &p->subs[idx].f;
6800
if (p->subs[idx].needbusy) {
6801
/* Send busy frame if requested */
6802
p->subs[idx].needbusy = 0;
6803
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6804
p->subs[idx].f.subclass = AST_CONTROL_BUSY;
6805
ast_mutex_unlock(&p->lock);
6806
return &p->subs[idx].f;
6809
if (p->subs[idx].needcongestion) {
6810
/* Send congestion frame if requested */
6811
p->subs[idx].needcongestion = 0;
6812
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6813
p->subs[idx].f.subclass = AST_CONTROL_CONGESTION;
6814
ast_mutex_unlock(&p->lock);
6815
return &p->subs[idx].f;
6818
if (p->subs[idx].needcallerid) {
6819
ast_set_callerid(ast, S_OR(p->lastcid_num, NULL),
6820
S_OR(p->lastcid_name, NULL),
6821
S_OR(p->lastcid_num, NULL)
6823
p->subs[idx].needcallerid = 0;
6826
if (p->subs[idx].needanswer) {
6827
/* Send answer frame if requested */
6828
p->subs[idx].needanswer = 0;
6829
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6830
p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
6831
ast_mutex_unlock(&p->lock);
6832
return &p->subs[idx].f;
6835
if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
6836
/* openr2 took care of reading and handling any event
6837
(needanswer, needbusy etc), if we continue we will read()
6838
twice, lets just return a null frame. This should only
6839
happen when openr2 is dialing out */
6840
ast_mutex_unlock(&p->lock);
6841
return &ast_null_frame;
6845
if (p->subs[idx].needflash) {
6846
/* Send answer frame if requested */
6847
p->subs[idx].needflash = 0;
6848
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6849
p->subs[idx].f.subclass = AST_CONTROL_FLASH;
6850
ast_mutex_unlock(&p->lock);
6851
return &p->subs[idx].f;
6854
if (p->subs[idx].needhold) {
6855
/* Send answer frame if requested */
6856
p->subs[idx].needhold = 0;
6857
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6858
p->subs[idx].f.subclass = AST_CONTROL_HOLD;
6859
ast_mutex_unlock(&p->lock);
6860
ast_debug(1, "Sending hold on '%s'\n", ast->name);
6861
return &p->subs[idx].f;
6864
if (p->subs[idx].needunhold) {
6865
/* Send answer frame if requested */
6866
p->subs[idx].needunhold = 0;
6867
p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6868
p->subs[idx].f.subclass = AST_CONTROL_UNHOLD;
6869
ast_mutex_unlock(&p->lock);
6870
ast_debug(1, "Sending unhold on '%s'\n", ast->name);
6871
return &p->subs[idx].f;
6874
if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
6875
if (!p->subs[idx].linear) {
6876
p->subs[idx].linear = 1;
6877
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
6879
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
6881
} else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
6882
(ast->rawreadformat == AST_FORMAT_ALAW)) {
6883
if (p->subs[idx].linear) {
6884
p->subs[idx].linear = 0;
6885
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
6887
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
6890
ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
6891
ast_mutex_unlock(&p->lock);
6894
readbuf = ((unsigned char *)p->subs[idx].buffer) + AST_FRIENDLY_OFFSET;
6895
CHECK_BLOCKING(ast);
6896
res = read(p->subs[idx].dfd, readbuf, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
6897
ast_clear_flag(ast, AST_FLAG_BLOCKING);
6898
/* Check for hangup */
6902
if (errno == EAGAIN) {
6903
/* Return "NULL" frame if there is nobody there */
6904
ast_mutex_unlock(&p->lock);
6905
return &p->subs[idx].f;
6906
} else if (errno == ELAST) {
6907
f = __dahdi_exception(ast);
6909
ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
6911
ast_mutex_unlock(&p->lock);
6914
if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
6915
ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
6916
f = __dahdi_exception(ast);
6917
ast_mutex_unlock(&p->lock);
6920
if (p->tdd) { /* if in TDD mode, see if we receive that */
6923
c = tdd_feed(p->tdd,readbuf,READ_SIZE);
6925
ast_debug(1,"tdd_feed failed\n");
6926
ast_mutex_unlock(&p->lock);
6929
if (c) { /* if a char to return */
6930
p->subs[idx].f.subclass = 0;
6931
p->subs[idx].f.frametype = AST_FRAME_TEXT;
6932
p->subs[idx].f.mallocd = 0;
6933
p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
6934
p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET;
6935
p->subs[idx].f.datalen = 1;
6936
*((char *) p->subs[idx].f.data.ptr) = c;
6937
ast_mutex_unlock(&p->lock);
6938
return &p->subs[idx].f;
6941
/* Ensure the CW timer decrements only on a single subchannel */
6942
if (p->callwaitingrepeat && dahdi_get_index(ast, p, 1) == SUB_REAL) {
6943
p->callwaitingrepeat--;
6947
/* Repeat callwaiting */
6948
if (p->callwaitingrepeat == 1) {
6950
dahdi_callwait(ast);
6953
if (p->cidcwexpire == 1) {
6954
ast_verb(3, "CPE does not support Call Waiting Caller*ID.\n");
6955
restore_conference(p);
6957
if (p->subs[idx].linear) {
6958
p->subs[idx].f.datalen = READ_SIZE * 2;
6960
p->subs[idx].f.datalen = READ_SIZE;
6962
/* Handle CallerID Transmission */
6963
if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
6967
p->subs[idx].f.frametype = AST_FRAME_VOICE;
6968
p->subs[idx].f.subclass = ast->rawreadformat;
6969
p->subs[idx].f.samples = READ_SIZE;
6970
p->subs[idx].f.mallocd = 0;
6971
p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
6972
p->subs[idx].f.data.ptr = p->subs[idx].buffer + AST_FRIENDLY_OFFSET / sizeof(p->subs[idx].buffer[0]);
6974
ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name);
6976
if (p->dialing || /* Transmitting something */
6977
(idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
6978
((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
6980
/* Whoops, we're still dialing, or in a state where we shouldn't transmit....
6981
don't send anything */
6982
p->subs[idx].f.frametype = AST_FRAME_NULL;
6983
p->subs[idx].f.subclass = 0;
6984
p->subs[idx].f.samples = 0;
6985
p->subs[idx].f.mallocd = 0;
6986
p->subs[idx].f.offset = 0;
6987
p->subs[idx].f.data.ptr = NULL;
6988
p->subs[idx].f.datalen= 0;
6990
if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) {
6991
/* Perform busy detection etc on the dahdi line */
6994
f = ast_dsp_process(ast, p->dsp, &p->subs[idx].f);
6996
/* Check if DSP code thinks we should be muting this frame and mute the conference if so */
6997
mute = ast_dsp_was_muted(p->dsp);
6998
if (p->muting != mute) {
7000
dahdi_confmute(p, mute);
7004
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_BUSY)) {
7005
if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
7006
/* Treat this as a "hangup" instead of a "busy" on the assumption that
7010
} else if (f->frametype == AST_FRAME_DTMF) {
7012
if (!p->proceeding && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) && p->pri &&
7013
((!p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) ||
7014
(p->outgoing && (p->pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)))) {
7015
/* Don't accept in-band DTMF when in overlap dial mode */
7016
f->frametype = AST_FRAME_NULL;
7020
/* DSP clears us of being pulse */
7022
} else if (p->waitingfordt.tv_sec) {
7023
if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) {
7024
p->waitingfordt.tv_sec = 0;
7025
ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel);
7027
} else if (f->frametype == AST_FRAME_VOICE) {
7028
f->frametype = AST_FRAME_NULL;
7030
if ((ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_DIALTONE || ast_dsp_get_tstate(p->dsp) == DSP_TONE_STATE_RINGING) && ast_dsp_get_tcount(p->dsp) > 9) {
7031
p->waitingfordt.tv_sec = 0;
7032
p->dsp_features &= ~DSP_FEATURE_WAITDIALTONE;
7033
ast_dsp_set_features(p->dsp, p->dsp_features);
7034
ast_log(LOG_DEBUG, "Got 10 samples of dialtone!\n");
7035
if (!ast_strlen_zero(p->dop.dialstr)) { /* Dial deferred digits */
7036
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_DIAL, &p->dop);
7038
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
7039
p->dop.dialstr[0] = '\0';
7040
ast_mutex_unlock(&p->lock);
7043
ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
7045
p->dop.dialstr[0] = '\0';
7046
p->dop.op = DAHDI_DIAL_OP_REPLACE;
7047
ast_setstate(ast, AST_STATE_DIALING);
7055
f = &p->subs[idx].f;
7057
if (f && (f->frametype == AST_FRAME_DTMF))
7058
dahdi_handle_dtmfup(ast, idx, &f);
7060
/* If we have a fake_event, trigger exception to handle it */
7062
ast_set_flag(ast, AST_FLAG_EXCEPTION);
7064
ast_mutex_unlock(&p->lock);
7068
static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
7074
fd = p->subs[idx].dfd;
7077
if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
7078
size = (linear ? READ_SIZE * 2 : READ_SIZE);
7079
res = write(fd, buf, size);
7081
ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
7090
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
7092
struct dahdi_pvt *p = ast->tech_pvt;
7095
idx = dahdi_get_index(ast, p, 0);
7097
ast_log(LOG_WARNING, "%s doesn't really exist?\n", ast->name);
7103
ast_mutex_lock(&p->lock);
7104
if (!p->proceeding && p->sig==SIG_PRI && p->pri && !p->outgoing) {
7106
if (!pri_grab(p, p->pri)) {
7107
pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
7110
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7114
ast_mutex_unlock(&p->lock);
7117
/* Write a frame of (presumably voice) data */
7118
if (frame->frametype != AST_FRAME_VOICE) {
7119
if (frame->frametype != AST_FRAME_IMAGE)
7120
ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
7123
if ((frame->subclass != AST_FORMAT_SLINEAR) &&
7124
(frame->subclass != AST_FORMAT_ULAW) &&
7125
(frame->subclass != AST_FORMAT_ALAW)) {
7126
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
7130
ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name);
7134
ast_debug(1, "Dropping frame since there is no active owner on %s...\n",ast->name);
7138
ast_debug(1, "Dropping frame since I've still got a callerid spill\n");
7141
/* Return if it's not valid data */
7142
if (!frame->data.ptr || !frame->datalen)
7145
if (frame->subclass == AST_FORMAT_SLINEAR) {
7146
if (!p->subs[idx].linear) {
7147
p->subs[idx].linear = 1;
7148
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
7150
ast_log(LOG_WARNING, "Unable to set linear mode on channel %d\n", p->channel);
7152
res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 1);
7155
if (p->subs[idx].linear) {
7156
p->subs[idx].linear = 0;
7157
res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
7159
ast_log(LOG_WARNING, "Unable to set companded mode on channel %d\n", p->channel);
7161
res = my_dahdi_write(p, (unsigned char *)frame->data.ptr, frame->datalen, idx, 0);
7164
ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
7170
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
7172
struct dahdi_pvt *p = chan->tech_pvt;
7175
int func = DAHDI_FLASH;
7176
ast_mutex_lock(&p->lock);
7177
idx = dahdi_get_index(chan, p, 0);
7178
ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name);
7180
if (p->mfcr2 && !p->mfcr2_call_accepted) {
7181
ast_mutex_unlock(&p->lock);
7182
/* if this is an R2 call and the call is not yet accepted, we don't want the
7183
tone indications to mess up with the MF tones */
7187
if (idx == SUB_REAL) {
7188
switch (condition) {
7189
case AST_CONTROL_BUSY:
7191
if (p->priindication_oob && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))) {
7192
chan->hangupcause = AST_CAUSE_USER_BUSY;
7193
chan->_softhangup |= AST_SOFTHANGUP_DEV;
7195
} else if (!p->progress &&
7196
((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
7197
&& p->pri && !p->outgoing) {
7199
if (!pri_grab(p, p->pri)) {
7200
#ifdef HAVE_PRI_PROG_W_CAUSE
7201
pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_USER_BUSY); /* cause = 17 */
7203
pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7208
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7211
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY);
7214
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_BUSY);
7216
case AST_CONTROL_RINGING:
7218
if ((!p->alerting) && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
7219
&& p->pri && !p->outgoing && (chan->_state != AST_STATE_UP)) {
7221
if (!pri_grab(p, p->pri)) {
7222
pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
7226
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7233
if ((!p->alerting) && (p->sig == SIG_SS7) && p->ss7 && !p->outgoing && (chan->_state != AST_STATE_UP)) {
7235
ss7_grab(p, p->ss7);
7237
if ((isup_far(p->ss7->ss7, p->ss7call)) != -1)
7239
if (p->rlt != 1) /* No need to send CPG if call will be RELEASE */
7240
isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_ALERTING);
7247
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_RINGTONE);
7249
if (chan->_state != AST_STATE_UP) {
7250
if ((chan->_state != AST_STATE_RING) ||
7251
((p->sig != SIG_FXSKS) &&
7252
(p->sig != SIG_FXSLS) &&
7253
(p->sig != SIG_FXSGS)))
7254
ast_setstate(chan, AST_STATE_RINGING);
7257
case AST_CONTROL_PROCEEDING:
7258
ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name);
7260
if (!p->proceeding && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
7261
&& p->pri && !p->outgoing) {
7263
if (!pri_grab(p, p->pri)) {
7264
pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p), !p->digital);
7268
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7275
/* This IF sends the FAR for an answered ALEG call */
7276
if (chan->_state == AST_STATE_UP && (p->rlt != 1) && (p->sig == SIG_SS7)){
7277
if ((isup_far(p->ss7->ss7, p->ss7call)) != -1)
7281
if (!p->proceeding && p->sig == SIG_SS7 && p->ss7 && !p->outgoing) {
7283
ss7_grab(p, p->ss7);
7284
isup_acm(p->ss7->ss7, p->ss7call);
7291
/* don't continue in ast_indicate */
7294
case AST_CONTROL_PROGRESS:
7295
ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name);
7297
p->digital = 0; /* Digital-only calls isn't allows any inband progress messages */
7298
if (!p->progress && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
7299
&& p->pri && !p->outgoing) {
7301
if (!pri_grab(p, p->pri)) {
7302
#ifdef HAVE_PRI_PROG_W_CAUSE
7303
pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1); /* no cause at all */
7305
pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7310
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7316
if (!p->progress && p->sig==SIG_SS7 && p->ss7 && !p->outgoing) {
7318
ss7_grab(p, p->ss7);
7319
isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_INBANDINFO);
7322
/* enable echo canceler here on SS7 calls */
7328
/* don't continue in ast_indicate */
7331
case AST_CONTROL_CONGESTION:
7332
chan->hangupcause = AST_CAUSE_CONGESTION;
7334
if (p->priindication_oob && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))) {
7335
chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
7336
chan->_softhangup |= AST_SOFTHANGUP_DEV;
7338
} else if (!p->progress && ((p->sig == SIG_PRI) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP))
7339
&& p->pri && !p->outgoing) {
7341
if (!pri_grab(p, p->pri)) {
7342
#ifdef HAVE_PRI_PROG_W_CAUSE
7343
pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, PRI_CAUSE_SWITCH_CONGESTION); /* cause = 42 */
7345
pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
7349
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7352
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
7355
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
7357
case AST_CONTROL_HOLD:
7359
if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
7360
if (!pri_grab(p, p->pri)) {
7361
res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_HOLD);
7364
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7367
ast_moh_start(chan, data, p->mohinterpret);
7369
case AST_CONTROL_UNHOLD:
7371
if (p->pri && !strcasecmp(p->mohinterpret, "passthrough")) {
7372
if (!pri_grab(p, p->pri)) {
7373
res = pri_notify(p->pri->pri, p->call, p->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
7376
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7381
case AST_CONTROL_RADIO_KEY:
7383
res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
7386
case AST_CONTROL_RADIO_UNKEY:
7388
res = dahdi_set_hook(p->subs[idx].dfd, DAHDI_RINGOFF);
7391
case AST_CONTROL_FLASH:
7392
/* flash hookswitch */
7393
if (ISTRUNK(p) && (p->sig != SIG_PRI)) {
7394
/* Clear out the dial buffer */
7395
p->dop.dialstr[0] = '\0';
7396
if ((ioctl(p->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
7397
ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
7398
chan->name, strerror(errno));
7404
case AST_CONTROL_SRCUPDATE:
7408
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
7413
ast_mutex_unlock(&p->lock);
7417
static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, int transfercapability)
7419
struct ast_channel *tmp;
7424
struct ast_str *chan_name;
7425
struct ast_variable *v;
7426
struct dahdi_params ps;
7427
if (i->subs[idx].owner) {
7428
ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[idx]);
7432
chan_name = ast_str_alloca(32);
7435
if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
7436
ast_str_set(&chan_name, 0, "%d:%d-%d", i->pri->trunkgroup, i->channel, y);
7439
if (i->channel == CHAN_PSEUDO)
7440
ast_str_set(&chan_name, 0, "pseudo-%ld", ast_random());
7442
ast_str_set(&chan_name, 0, "%d-%d", i->channel, y);
7443
for (x = 0; x < 3; x++) {
7444
if ((idx != x) && i->subs[x].owner && !strcasecmp(ast_str_buffer(chan_name), i->subs[x].owner->name + 6))
7449
tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
7452
tmp->tech = &dahdi_tech;
7453
memset(&ps, 0, sizeof(ps));
7454
ps.channo = i->channel;
7455
res = ioctl(i->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps);
7457
ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW: %s\n", strerror(errno));
7458
ps.curlaw = DAHDI_LAW_MULAW;
7460
if (ps.curlaw == DAHDI_LAW_ALAW)
7461
deflaw = AST_FORMAT_ALAW;
7463
deflaw = AST_FORMAT_ULAW;
7465
if (law == DAHDI_LAW_ALAW)
7466
deflaw = AST_FORMAT_ALAW;
7468
deflaw = AST_FORMAT_ULAW;
7470
ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
7471
tmp->nativeformats = deflaw;
7472
/* Start out assuming ulaw since it's smaller :) */
7473
tmp->rawreadformat = deflaw;
7474
tmp->readformat = deflaw;
7475
tmp->rawwriteformat = deflaw;
7476
tmp->writeformat = deflaw;
7477
i->subs[idx].linear = 0;
7478
dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
7480
if (idx == SUB_REAL) {
7481
if (i->busydetect && CANBUSYDETECT(i))
7482
features |= DSP_FEATURE_BUSY_DETECT;
7483
if ((i->callprogress & CALLPROGRESS_PROGRESS) && CANPROGRESSDETECT(i))
7484
features |= DSP_FEATURE_CALL_PROGRESS;
7485
if ((i->waitfordialtone) && CANPROGRESSDETECT(i))
7486
features |= DSP_FEATURE_WAITDIALTONE;
7487
if ((!i->outgoing && (i->callprogress & CALLPROGRESS_FAX_INCOMING)) ||
7488
(i->outgoing && (i->callprogress & CALLPROGRESS_FAX_OUTGOING))) {
7489
features |= DSP_FEATURE_FAX_DETECT;
7491
x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
7492
if (ioctl(i->subs[idx].dfd, DAHDI_TONEDETECT, &x)) {
7493
i->hardwaredtmf = 0;
7494
features |= DSP_FEATURE_DIGIT_DETECT;
7495
} else if (NEED_MFDETECT(i)) {
7496
i->hardwaredtmf = 1;
7497
features |= DSP_FEATURE_DIGIT_DETECT;
7502
ast_debug(1, "Already have a dsp on %s?\n", tmp->name);
7504
if (i->channel != CHAN_PSEUDO)
7505
i->dsp = ast_dsp_new();
7509
i->dsp_features = features;
7510
#if defined(HAVE_PRI) || defined(HAVE_SS7)
7511
/* We cannot do progress detection until receives PROGRESS message */
7512
if (i->outgoing && ((i->sig == SIG_PRI) || (i->sig == SIG_BRI) || (i->sig == SIG_BRI_PTMP) || (i->sig == SIG_SS7))) {
7513
/* Remember requested DSP features, don't treat
7514
talking as ANSWER */
7515
i->dsp_features = features & ~DSP_PROGRESS_TALK;
7519
ast_dsp_set_features(i->dsp, features);
7520
ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | i->dtmfrelax);
7521
if (!ast_strlen_zero(progzone))
7522
ast_dsp_set_call_progress_zone(i->dsp, progzone);
7523
if (i->busydetect && CANBUSYDETECT(i)) {
7524
ast_dsp_set_busy_count(i->dsp, i->busycount);
7525
ast_dsp_set_busy_pattern(i->dsp, i->busy_tonelength, i->busy_quietlength);
7531
if (state == AST_STATE_RING)
7534
if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
7535
/* Only FXO signalled stuff can be picked up */
7536
tmp->callgroup = i->callgroup;
7537
tmp->pickupgroup = i->pickupgroup;
7539
if (!ast_strlen_zero(i->parkinglot))
7540
ast_string_field_set(tmp, parkinglot, i->parkinglot);
7541
if (!ast_strlen_zero(i->language))
7542
ast_string_field_set(tmp, language, i->language);
7545
if (!ast_strlen_zero(i->accountcode))
7546
ast_string_field_set(tmp, accountcode, i->accountcode);
7548
tmp->amaflags = i->amaflags;
7549
i->subs[idx].owner = tmp;
7550
ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
7551
ast_string_field_set(tmp, call_forward, i->call_forward);
7552
/* If we've been told "no ADSI" then enforce it */
7554
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
7555
if (!ast_strlen_zero(i->exten))
7556
ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
7557
if (!ast_strlen_zero(i->rdnis))
7558
tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
7559
if (!ast_strlen_zero(i->dnid))
7560
tmp->cid.cid_dnid = ast_strdup(i->dnid);
7562
/* Don't use ast_set_callerid() here because it will
7563
* generate a needless NewCallerID event */
7565
if (!ast_strlen_zero(i->cid_ani))
7566
tmp->cid.cid_ani = ast_strdup(i->cid_ani);
7568
tmp->cid.cid_ani = ast_strdup(i->cid_num);
7570
tmp->cid.cid_ani = ast_strdup(i->cid_num);
7572
tmp->cid.cid_pres = i->callingpres;
7573
tmp->cid.cid_ton = i->cid_ton;
7574
tmp->cid.cid_ani2 = i->cid_ani2;
7575
#if defined(HAVE_PRI) || defined(HAVE_SS7)
7576
tmp->transfercapability = transfercapability;
7577
pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
7578
if (transfercapability & AST_TRANS_CAP_DIGITAL)
7580
/* Assume calls are not idle calls unless we're told differently */
7582
i->alreadyhungup = 0;
7584
/* clear the fake event in case we posted one before we had ast_channel */
7586
/* Assure there is no confmute on this channel */
7587
dahdi_confmute(i, 0);
7589
/* Configure the new channel jb */
7590
ast_jb_configure(tmp, &global_jbconf);
7592
ast_devstate_changed_literal(ast_state_chan2dev(state), tmp->name);
7594
for (v = i->vars ; v ; v = v->next)
7595
pbx_builtin_setvar_helper(tmp, v->name, v->value);
7600
pbx_builtin_setvar_helper(tmp, "MFCR2_CATEGORY", openr2_proto_get_category_string(i->mfcr2_recvd_category));
7603
if (ast_pbx_start(tmp)) {
7604
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
7611
ast_module_ref(ast_module_info->self);
7616
static int my_getsigstr(struct ast_channel *chan, char *str, const char *term, int ms)
7620
*str = 0; /* start with empty output buffer */
7623
/* Wait for the first digit (up to specified ms). */
7624
c = ast_waitfordigit(chan, ms);
7625
/* if timeout, hangup or error, return as such */
7630
if (strchr(term, c))
7635
static int dahdi_wink(struct dahdi_pvt *p, int idx)
7638
dahdi_set_hook(p->subs[idx].dfd, DAHDI_WINK);
7641
/* set bits of interest */
7642
j = DAHDI_IOMUX_SIGEVENT;
7643
/* wait for some happening */
7644
if (ioctl(p->subs[idx].dfd,DAHDI_IOMUX,&j) == -1) return(-1);
7645
/* exit loop if we have it */
7646
if (j & DAHDI_IOMUX_SIGEVENT) break;
7648
/* get the event info */
7649
if (ioctl(p->subs[idx].dfd,DAHDI_GETEVENT,&j) == -1) return(-1);
7653
/*! \brief enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
7654
* \param dahdichan "Physical" DAHDI channel (e.g: DAHDI/5)
7655
* \param on 1 to enable, 0 to disable
7657
* chan_dahdi has a DND (Do Not Disturb) mode for each dahdichan (physical
7658
* DAHDI channel). Use this to enable or disable it.
7660
* \bug the use of the word "channel" for those dahdichans is really confusing.
7662
static void dahdi_dnd(struct dahdi_pvt *dahdichan, int on)
7664
/* Do not disturb */
7665
dahdichan->dnd = on;
7666
ast_verb(3, "%s DND on channel %d\n",
7667
on? "Enabled" : "Disabled",
7668
dahdichan->channel);
7669
manager_event(EVENT_FLAG_SYSTEM, "DNDState",
7670
"Channel: DAHDI/%d\r\n"
7671
"Status: %s\r\n", dahdichan->channel,
7672
on? "enabled" : "disabled");
7675
static void *ss_thread(void *data)
7677
struct ast_channel *chan = data;
7678
struct dahdi_pvt *p = chan->tech_pvt;
7679
char exten[AST_MAX_EXTENSION] = "";
7680
char exten2[AST_MAX_EXTENSION] = "";
7681
unsigned char buf[256];
7684
struct callerid_state *cs = NULL;
7685
char *name = NULL, *number = NULL;
7692
struct ast_smdi_md_message *smdi_msg = NULL;
7702
ast_mutex_lock(&ss_thread_lock);
7704
ast_mutex_unlock(&ss_thread_lock);
7705
/* in the bizarre case where the channel has become a zombie before we
7706
even get started here, abort safely
7709
ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
7713
ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
7714
idx = dahdi_get_index(chan, p, 1);
7716
ast_log(LOG_WARNING, "Huh?\n");
7721
ast_dsp_digitreset(p->dsp);
7727
/* Now loop looking for an extension */
7728
ast_copy_string(exten, p->exten, sizeof(exten));
7729
len = strlen(exten);
7731
while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
7732
if (len && !ast_ignore_pattern(chan->context, exten))
7733
tone_zone_play_tone(p->subs[idx].dfd, -1);
7735
tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
7736
if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num))
7737
timeout = matchdigittimeout;
7739
timeout = gendigittimeout;
7740
res = ast_waitfordigit(chan, timeout);
7742
ast_debug(1, "waitfordigit returned < 0...\n");
7751
/* if no extension was received ('unspecified') on overlap call, use the 's' extension */
7752
if (ast_strlen_zero(exten)) {
7753
ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n");
7757
tone_zone_play_tone(p->subs[idx].dfd, -1);
7758
if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) {
7759
/* Start the real PBX */
7760
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
7762
ast_dsp_digitreset(p->dsp);
7764
if (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) {
7766
if (!pri_grab(p, p->pri)) {
7767
pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0);
7771
ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
7776
ast_setstate(chan, AST_STATE_RING);
7777
res = ast_pbx_run(chan);
7779
ast_log(LOG_WARNING, "PBX exited non-zero!\n");
7782
ast_debug(1, "No such possible extension '%s' in context '%s'\n", exten, chan->context);
7783
chan->hangupcause = AST_CAUSE_UNALLOCATED;
7786
/* Since we send release complete here, we won't get one */
7794
case SIG_FEATDMF_TA:
7796
case SIG_FGC_CAMAMF:
7800
case SIG_SF_FEATDMF:
7803
if (dahdi_wink(p, idx))
7810
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
7812
ast_dsp_digitreset(p->dsp);
7813
/* set digit mode appropriately */
7815
if (NEED_MFDETECT(p))
7816
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
7818
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
7820
memset(dtmfbuf, 0, sizeof(dtmfbuf));
7821
/* Wait for the first digit only if immediate=no */
7823
/* Wait for the first digit (up to 5 seconds). */
7824
res = ast_waitfordigit(chan, 5000);
7828
/* save first char */
7833
res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
7835
res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
7836
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
7838
case SIG_FEATDMF_TA:
7839
res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
7840
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
7841
if (dahdi_wink(p, idx)) goto quit;
7843
/* Wait for the first digit (up to 5 seconds). */
7844
res = ast_waitfordigit(chan, 5000);
7845
if (res <= 0) break;
7847
/* fall through intentionally */
7850
case SIG_FGC_CAMAMF:
7851
case SIG_SF_FEATDMF:
7852
res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
7853
/* if international caca, do it again to get real ANO */
7854
if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
7856
if (dahdi_wink(p, idx)) goto quit;
7858
/* Wait for the first digit (up to 5 seconds). */
7859
res = ast_waitfordigit(chan, 5000);
7860
if (res <= 0) break;
7862
res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
7865
/* if E911, take off hook */
7866
if (p->sig == SIG_E911)
7867
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
7868
res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "#", 3000);
7870
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
7874
res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
7875
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
7878
/* if we received a '*', we are actually receiving Feature Group D
7879
dial syntax, so use that mode; otherwise, fall through to normal
7883
res = my_getsigstr(chan, dtmfbuf + 1, "*", 3000);
7885
res = my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf), "*", 3000);
7886
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
7890
/* If we got the first digit, get the rest */
7892
dtmfbuf[len] = '\0';
7893
while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
7894
if (ast_exists_extension(chan, chan->context, dtmfbuf, 1, p->cid_num)) {
7895
timeout = matchdigittimeout;
7897
timeout = gendigittimeout;
7899
res = ast_waitfordigit(chan, timeout);
7901
ast_debug(1, "waitfordigit returned < 0...\n");
7905
dtmfbuf[len++] = res;
7906
dtmfbuf[len] = '\0';
7915
ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
7918
} else if (res < 0) {
7919
ast_debug(1, "Got hung up before digits finished\n");
7924
if (p->sig == SIG_FGC_CAMA) {
7927
if (ast_safe_sleep(chan,1000) == -1) {
7931
dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
7932
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
7933
res = my_getsigstr(chan, anibuf, "#", 10000);
7934
if ((res > 0) && (strlen(anibuf) > 2)) {
7935
if (anibuf[strlen(anibuf) - 1] == '#')
7936
anibuf[strlen(anibuf) - 1] = 0;
7937
ast_set_callerid(chan, anibuf + 2, NULL, anibuf + 2);
7939
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
7942
ast_copy_string(exten, dtmfbuf, sizeof(exten));
7943
if (ast_strlen_zero(exten))
7944
ast_copy_string(exten, "s", sizeof(exten));
7945
if (p->sig == SIG_FEATD || p->sig == SIG_EMWINK) {
7946
/* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
7947
if (exten[0] == '*') {
7949
ast_copy_string(exten2, exten, sizeof(exten2));
7950
/* Parse out extension and callerid */
7952
s1 = strsep(&stringp, "*");
7953
s2 = strsep(&stringp, "*");
7955
if (!ast_strlen_zero(p->cid_num))
7956
ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
7958
ast_set_callerid(chan, s1, NULL, s1);
7959
ast_copy_string(exten, s2, sizeof(exten));
7961
ast_copy_string(exten, s1, sizeof(exten));
7962
} else if (p->sig == SIG_FEATD)
7963
ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
7965
if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
7966
if (exten[0] == '*') {
7968
ast_copy_string(exten2, exten, sizeof(exten2));
7969
/* Parse out extension and callerid */
7971
s1 = strsep(&stringp, "#");
7972
s2 = strsep(&stringp, "#");
7974
if (!ast_strlen_zero(p->cid_num))
7975
ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
7978
ast_set_callerid(chan, s1 + 2, NULL, s1 + 2);
7979
ast_copy_string(exten, s2 + 1, sizeof(exten));
7981
ast_copy_string(exten, s1 + 2, sizeof(exten));
7983
ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p->channel);
7985
if ((p->sig == SIG_E911) || (p->sig == SIG_FGC_CAMAMF)) {
7986
if (exten[0] == '*') {
7988
ast_copy_string(exten2, exten, sizeof(exten2));
7989
/* Parse out extension and callerid */
7991
s1 = strsep(&stringp, "#");
7992
s2 = strsep(&stringp, "#");
7993
if (s2 && (*(s2 + 1) == '0')) {
7995
ast_set_callerid(chan, s2 + 2, NULL, s2 + 2);
7997
if (s1) ast_copy_string(exten, s1, sizeof(exten));
7998
else ast_copy_string(exten, "911", sizeof(exten));
8000
ast_log(LOG_WARNING, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p->channel);
8002
if (p->sig == SIG_FEATB) {
8003
if (exten[0] == '*') {
8005
ast_copy_string(exten2, exten, sizeof(exten2));
8006
/* Parse out extension and callerid */
8008
s1 = strsep(&stringp, "#");
8009
ast_copy_string(exten, exten2 + 1, sizeof(exten));
8011
ast_log(LOG_WARNING, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p->channel);
8013
if ((p->sig == SIG_FEATDMF) || (p->sig == SIG_FEATDMF_TA)) {
8015
/* some switches require a minimum guard time between
8016
the last FGD wink and something that answers
8017
immediately. This ensures it */
8018
if (ast_safe_sleep(chan,100)) goto quit;
8021
if (NEED_MFDETECT(p)) {
8023
if (!p->hardwaredtmf)
8024
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
8026
ast_dsp_free(p->dsp);
8032
if (ast_exists_extension(chan, chan->context, exten, 1, chan->cid.cid_num)) {
8033
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
8034
if (p->dsp) ast_dsp_digitreset(p->dsp);
8035
res = ast_pbx_run(chan);
8037
ast_log(LOG_WARNING, "PBX exited non-zero\n");
8038
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8042
ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
8044
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_INFO);
8046
ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
8049
res = ast_streamfile(chan, "ss-noservice", chan->language);
8051
ast_waitstream(chan, "");
8052
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8060
/* Read the first digit */
8061
timeout = firstdigittimeout;
8062
/* If starting a threeway call, never timeout on the first digit so someone
8063
can use flash-hook as a "hold" feature */
8064
if (p->subs[SUB_THREEWAY].owner)
8066
while (len < AST_MAX_EXTENSION-1) {
8067
/* Read digit unless it's supposed to be immediate, in which case the
8068
only answer is 's' */
8072
res = ast_waitfordigit(chan, timeout);
8075
ast_debug(1, "waitfordigit returned < 0...\n");
8076
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
8080
ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
8084
if (!ast_ignore_pattern(chan->context, exten))
8085
tone_zone_play_tone(p->subs[idx].dfd, -1);
8087
tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
8088
if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num) && strcmp(exten, ast_parking_ext())) {
8089
if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) {
8091
/* Record this as the forwarding extension */
8092
ast_copy_string(p->call_forward, exten, sizeof(p->call_forward));
8093
ast_verb(3, "Setting call forward to '%s' on channel %d\n", p->call_forward, p->channel);
8094
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8098
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
8100
memset(exten, 0, sizeof(exten));
8101
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALTONE);
8105
res = tone_zone_play_tone(p->subs[idx].dfd, -1);
8106
ast_copy_string(chan->exten, exten, sizeof(chan->exten));
8107
if (!ast_strlen_zero(p->cid_num)) {
8108
if (!p->hidecallerid)
8109
ast_set_callerid(chan, p->cid_num, NULL, p->cid_num);
8111
ast_set_callerid(chan, NULL, NULL, p->cid_num);
8113
if (!ast_strlen_zero(p->cid_name)) {
8114
if (!p->hidecallerid)
8115
ast_set_callerid(chan, NULL, p->cid_name, NULL);
8117
ast_setstate(chan, AST_STATE_RING);
8119
res = ast_pbx_run(chan);
8121
ast_log(LOG_WARNING, "PBX exited non-zero\n");
8122
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8127
/* It's a match, but they just typed a digit, and there is an ambiguous match,
8128
so just set the timeout to matchdigittimeout and wait some more */
8129
timeout = matchdigittimeout;
8131
} else if (res == 0) {
8132
ast_debug(1, "not enough digits (and no ambiguous match)...\n");
8133
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8134
dahdi_wait_event(p->subs[idx].dfd);
8137
} else if (p->callwaiting && !strcmp(exten, "*70")) {
8138
ast_verb(3, "Disabling call waiting on %s\n", chan->name);
8139
/* Disable call waiting if enabled */
8141
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8143
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
8144
chan->name, strerror(errno));
8147
ioctl(p->subs[idx].dfd,DAHDI_CONFDIAG,&len);
8148
memset(exten, 0, sizeof(exten));
8149
timeout = firstdigittimeout;
8151
} else if (!strcmp(exten,ast_pickup_ext())) {
8152
/* Scan all channels and see if there are any
8153
* ringing channels that have call groups
8154
* that equal this channels pickup group
8156
if (idx == SUB_REAL) {
8157
/* Switch us from Third call to Call Wait */
8158
if (p->subs[SUB_THREEWAY].owner) {
8159
/* If you make a threeway call and the *8# a call, it should actually
8160
look like a callwait */
8161
alloc_sub(p, SUB_CALLWAIT);
8162
swap_subs(p, SUB_CALLWAIT, SUB_THREEWAY);
8163
unalloc_sub(p, SUB_THREEWAY);
8166
if (ast_pickup_call(chan)) {
8167
ast_debug(1, "No call pickup possible...\n");
8168
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8169
dahdi_wait_event(p->subs[idx].dfd);
8174
ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
8179
} else if (!p->hidecallerid && !strcmp(exten, "*67")) {
8180
ast_verb(3, "Disabling Caller*ID on %s\n", chan->name);
8181
/* Disable Caller*ID if enabled */
8182
p->hidecallerid = 1;
8183
if (chan->cid.cid_num)
8184
ast_free(chan->cid.cid_num);
8185
chan->cid.cid_num = NULL;
8186
if (chan->cid.cid_name)
8187
ast_free(chan->cid.cid_name);
8188
chan->cid.cid_name = NULL;
8189
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8191
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
8192
chan->name, strerror(errno));
8195
memset(exten, 0, sizeof(exten));
8196
timeout = firstdigittimeout;
8197
} else if (p->callreturn && !strcmp(exten, "*69")) {
8199
if (!ast_strlen_zero(p->lastcid_num)) {
8200
res = ast_say_digit_str(chan, p->lastcid_num, "", chan->language);
8203
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8205
} else if (!strcmp(exten, "*78")) {
8207
/* Do not disturb */
8208
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8210
memset(exten, 0, sizeof(exten));
8212
} else if (!strcmp(exten, "*79")) {
8214
/* Do not disturb */
8215
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8217
memset(exten, 0, sizeof(exten));
8219
} else if (p->cancallforward && !strcmp(exten, "*72")) {
8220
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8222
memset(exten, 0, sizeof(exten));
8224
} else if (p->cancallforward && !strcmp(exten, "*73")) {
8225
ast_verb(3, "Cancelling call forwarding on channel %d\n", p->channel);
8226
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8227
memset(p->call_forward, 0, sizeof(p->call_forward));
8229
memset(exten, 0, sizeof(exten));
8231
} else if ((p->transfer || p->canpark) && !strcmp(exten, ast_parking_ext()) &&
8232
p->subs[SUB_THREEWAY].owner &&
8233
ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
8234
/* This is a three way call, the main call being a real channel,
8235
and we're parking the first call. */
8236
ast_masq_park_call(ast_bridged_channel(p->subs[SUB_THREEWAY].owner), chan, 0, NULL);
8237
ast_verb(3, "Parking call to '%s'\n", chan->name);
8239
} else if (!ast_strlen_zero(p->lastcid_num) && !strcmp(exten, "*60")) {
8240
ast_verb(3, "Blacklisting number %s\n", p->lastcid_num);
8241
res = ast_db_put("blacklist", p->lastcid_num, "1");
8243
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8244
memset(exten, 0, sizeof(exten));
8247
} else if (p->hidecallerid && !strcmp(exten, "*82")) {
8248
ast_verb(3, "Enabling Caller*ID on %s\n", chan->name);
8249
/* Enable Caller*ID if enabled */
8250
p->hidecallerid = 0;
8251
if (chan->cid.cid_num)
8252
ast_free(chan->cid.cid_num);
8253
chan->cid.cid_num = NULL;
8254
if (chan->cid.cid_name)
8255
ast_free(chan->cid.cid_name);
8256
chan->cid.cid_name = NULL;
8257
ast_set_callerid(chan, p->cid_num, p->cid_name, NULL);
8258
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_DIALRECALL);
8260
ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n",
8261
chan->name, strerror(errno));
8264
memset(exten, 0, sizeof(exten));
8265
timeout = firstdigittimeout;
8266
} else if (!strcmp(exten, "*0")) {
8267
struct ast_channel *nbridge =
8268
p->subs[SUB_THREEWAY].owner;
8269
struct dahdi_pvt *pbridge = NULL;
8270
/* set up the private struct of the bridged one, if any */
8271
if (nbridge && ast_bridged_channel(nbridge))
8272
pbridge = ast_bridged_channel(nbridge)->tech_pvt;
8273
if (nbridge && pbridge &&
8274
(nbridge->tech == &dahdi_tech) &&
8275
(ast_bridged_channel(nbridge)->tech == &dahdi_tech) &&
8277
int func = DAHDI_FLASH;
8278
/* Clear out the dial buffer */
8279
p->dop.dialstr[0] = '\0';
8280
/* flash hookswitch */
8281
if ((ioctl(pbridge->subs[SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
8282
ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
8283
nbridge->name, strerror(errno));
8285
swap_subs(p, SUB_REAL, SUB_THREEWAY);
8286
unalloc_sub(p, SUB_THREEWAY);
8287
p->owner = p->subs[SUB_REAL].owner;
8288
if (ast_bridged_channel(p->subs[SUB_REAL].owner))
8289
ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
8293
tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8294
dahdi_wait_event(p->subs[idx].dfd);
8295
tone_zone_play_tone(p->subs[idx].dfd, -1);
8296
swap_subs(p, SUB_REAL, SUB_THREEWAY);
8297
unalloc_sub(p, SUB_THREEWAY);
8298
p->owner = p->subs[SUB_REAL].owner;
8302
} else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
8303
((exten[0] != '*') || (strlen(exten) > 2))) {
8304
ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
8308
timeout = gendigittimeout;
8309
if (len && !ast_ignore_pattern(chan->context, exten))
8310
tone_zone_play_tone(p->subs[idx].dfd, -1);
8318
/* This is a GR-303 trunk actually. Wait for the first ring... */
8319
struct ast_frame *f;
8324
ast_setstate(chan, AST_STATE_RING);
8325
while (time(NULL) < start + 3) {
8326
res = ast_waitfor(chan, 1000);
8330
ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
8333
} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
8339
ast_debug(1, "Got ring!\n");
8347
/* check for SMDI messages */
8348
if (p->use_smdi && p->smdi_iface) {
8349
smdi_msg = ast_smdi_md_message_wait(p->smdi_iface, SMDI_MD_WAIT_TIMEOUT);
8351
if (smdi_msg != NULL) {
8352
ast_copy_string(chan->exten, smdi_msg->fwd_st, sizeof(chan->exten));
8354
if (smdi_msg->type == 'B')
8355
pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "b");
8356
else if (smdi_msg->type == 'N')
8357
pbx_builtin_setvar_helper(chan, "_SMDI_VM_TYPE", "u");
8359
ast_debug(1, "Received SMDI message on %s\n", chan->name);
8361
ast_log(LOG_WARNING, "SMDI enabled but no SMDI message present\n");
8365
if (p->use_callerid && (p->cid_signalling == CID_SIG_SMDI && smdi_msg)) {
8366
number = smdi_msg->calling_st;
8368
/* If we want caller id, we're in a prering state due to a polarity reversal
8369
* and we're set to use a polarity reversal to trigger the start of caller id,
8370
* grab the caller id and wait for ringing to start... */
8371
} else if (p->use_callerid && (chan->_state == AST_STATE_PRERING && (p->cid_start == CID_START_POLARITY || p->cid_start == CID_START_POLARITY_IN))) {
8372
/* If set to use DTMF CID signalling, listen for DTMF */
8373
if (p->cid_signalling == CID_SIG_DTMF) {
8376
ast_debug(1, "Receiving DTMF cid on "
8377
"channel %s\n", chan->name);
8378
dahdi_setlinear(p->subs[idx].dfd, 0);
8381
struct ast_frame *f;
8382
res = ast_waitfor(chan, res);
8384
ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
8385
"Exiting simple switch\n");
8392
if (f->frametype == AST_FRAME_DTMF) {
8393
dtmfbuf[k++] = f->subclass;
8394
ast_debug(1, "CID got digit '%c'\n", f->subclass);
8398
if (chan->_state == AST_STATE_RING ||
8399
chan->_state == AST_STATE_RINGING)
8400
break; /* Got ring */
8403
dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8404
/* Got cid and ring. */
8405
ast_debug(1, "CID got string '%s'\n", dtmfbuf);
8406
callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
8407
ast_debug(1, "CID is '%s', flags %d\n",
8409
/* If first byte is NULL, we have no cid */
8410
if (!ast_strlen_zero(dtmfcid))
8414
/* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
8415
} else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
8416
cs = callerid_new(p->cid_signalling);
8422
/* Take out of linear mode for Caller*ID processing */
8423
dahdi_setlinear(p->subs[idx].dfd, 0);
8425
/* First we wait and listen for the Caller*ID */
8427
i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
8428
if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
8429
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
8434
if (i & DAHDI_IOMUX_SIGEVENT) {
8435
res = dahdi_get_event(p->subs[idx].dfd);
8436
ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
8437
if (res == DAHDI_EVENT_NOALARM) {
8441
if (p->cid_signalling == CID_SIG_V23_JP) {
8442
if (res == DAHDI_EVENT_RINGBEGIN) {
8443
res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
8450
} else if (i & DAHDI_IOMUX_READ) {
8451
res = read(p->subs[idx].dfd, buf, sizeof(buf));
8453
if (errno != ELAST) {
8454
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
8463
if (p->cid_signalling == CID_SIG_V23_JP) {
8464
res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
8466
res = callerid_feed(cs, buf, res, AST_LAW(p));
8470
ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
8474
else if (samples > (8000 * 10))
8479
callerid_get(cs, &name, &number, &flags);
8480
ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
8483
if (p->cid_signalling == CID_SIG_V23_JP) {
8484
res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
8489
/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
8494
struct ast_frame *f;
8495
res = ast_waitfor(chan, res);
8497
ast_log(LOG_WARNING, "CID timed out waiting for ring. "
8498
"Exiting simple switch\n");
8502
if (!(f = ast_read(chan))) {
8503
ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
8508
if (chan->_state == AST_STATE_RING ||
8509
chan->_state == AST_STATE_RINGING)
8510
break; /* Got ring */
8513
/* We must have a ring by now, so, if configured, lets try to listen for
8514
* distinctive ringing */
8515
if (p->usedistinctiveringdetection) {
8518
/* Clear the current ring data array so we dont have old data in it. */
8519
for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
8520
curRingData[receivedRingT] = 0;
8524
/* Check to see if context is what it should be, if not set to be. */
8525
if (strcmp(p->context,p->defcontext) != 0) {
8526
ast_copy_string(p->context, p->defcontext, sizeof(p->context));
8527
ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
8531
i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
8532
if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
8533
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
8538
if (i & DAHDI_IOMUX_SIGEVENT) {
8539
res = dahdi_get_event(p->subs[idx].dfd);
8540
ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
8541
if (res == DAHDI_EVENT_NOALARM) {
8545
/* Let us detect distinctive ring */
8547
curRingData[receivedRingT] = p->ringt;
8549
if (p->ringt < p->ringt_base/2)
8551
/* Increment the ringT counter so we can match it against
8552
values in chan_dahdi.conf for distinctive ring */
8553
if (++receivedRingT == ARRAY_LEN(curRingData))
8555
} else if (i & DAHDI_IOMUX_READ) {
8556
res = read(p->subs[idx].dfd, buf, sizeof(buf));
8558
if (errno != ELAST) {
8559
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
8568
if (p->ringt == 1) {
8574
/* this only shows up if you have n of the dring patterns filled in */
8575
ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
8576
for (counter = 0; counter < 3; counter++) {
8577
/* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
8580
for (counter1 = 0; counter1 < 3; counter1++) {
8581
ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
8582
if (p->drings.ringnum[counter].ring[counter1] == -1) {
8583
ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
8584
curRingData[counter1]);
8586
} else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
8587
curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
8588
ast_verb(3, "Ring pattern matched in range: %d to %d\n",
8589
(p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
8590
(p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
8595
if (distMatches == 3) {
8596
/* The ring matches, set the context to whatever is for distinctive ring.. */
8597
ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
8598
ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
8599
ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
8604
/* Restore linear mode (if appropriate) for Caller*ID processing */
8605
dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8610
ast_log(LOG_WARNING, "Unable to get caller ID space\n");
8612
ast_log(LOG_WARNING, "Channel %s in prering "
8613
"state, but I have nothing to do. "
8614
"Terminating simple switch, should be "
8615
"restarted by the actual ring.\n",
8620
} else if (p->use_callerid && p->cid_start == CID_START_RING) {
8621
if (p->cid_signalling == CID_SIG_DTMF) {
8624
dahdi_setlinear(p->subs[idx].dfd, 0);
8627
struct ast_frame *f;
8628
res = ast_waitfor(chan, res);
8630
ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
8631
"Exiting simple switch\n");
8636
if (f->frametype == AST_FRAME_DTMF) {
8637
dtmfbuf[k++] = f->subclass;
8638
ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
8643
if (p->ringt_base == p->ringt)
8647
dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8648
/* Got cid and ring. */
8649
callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
8650
ast_log(LOG_DEBUG, "CID is '%s', flags %d\n",
8652
/* If first byte is NULL, we have no cid */
8653
if (!ast_strlen_zero(dtmfcid))
8657
/* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
8659
/* FSK Bell202 callerID */
8660
cs = callerid_new(p->cid_signalling);
8668
/* Clear the current ring data array so we dont have old data in it. */
8669
for (receivedRingT = 0; receivedRingT < ARRAY_LEN(curRingData); receivedRingT++)
8670
curRingData[receivedRingT] = 0;
8674
/* Check to see if context is what it should be, if not set to be. */
8675
if (strcmp(p->context,p->defcontext) != 0) {
8676
ast_copy_string(p->context, p->defcontext, sizeof(p->context));
8677
ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
8680
/* Take out of linear mode for Caller*ID processing */
8681
dahdi_setlinear(p->subs[idx].dfd, 0);
8683
i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
8684
if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
8685
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
8690
if (i & DAHDI_IOMUX_SIGEVENT) {
8691
res = dahdi_get_event(p->subs[idx].dfd);
8692
ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
8693
if (res == DAHDI_EVENT_NOALARM) {
8696
/* If we get a PR event, they hung up while processing calerid */
8697
if ( res == DAHDI_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
8698
ast_log(LOG_DEBUG, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
8699
p->polarity = POLARITY_IDLE;
8705
/* Let us detect callerid when the telco uses distinctive ring */
8707
curRingData[receivedRingT] = p->ringt;
8709
if (p->ringt < p->ringt_base/2)
8711
/* Increment the ringT counter so we can match it against
8712
values in chan_dahdi.conf for distinctive ring */
8713
if (++receivedRingT == ARRAY_LEN(curRingData))
8715
} else if (i & DAHDI_IOMUX_READ) {
8716
res = read(p->subs[idx].dfd, buf, sizeof(buf));
8718
if (errno != ELAST) {
8719
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
8728
if (p->ringt == 1) {
8733
res = callerid_feed(cs, buf, res, AST_LAW(p));
8735
ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
8739
else if (samples > (8000 * 10))
8744
callerid_get(cs, &name, &number, &flags);
8745
ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
8747
if (distinctiveringaftercid == 1) {
8748
/* Clear the current ring data array so we dont have old data in it. */
8749
for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
8750
curRingData[receivedRingT] = 0;
8753
ast_verb(3, "Detecting post-CID distinctive ring\n");
8755
i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
8756
if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
8757
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
8762
if (i & DAHDI_IOMUX_SIGEVENT) {
8763
res = dahdi_get_event(p->subs[idx].dfd);
8764
ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
8765
if (res == DAHDI_EVENT_NOALARM) {
8769
/* Let us detect callerid when the telco uses distinctive ring */
8771
curRingData[receivedRingT] = p->ringt;
8773
if (p->ringt < p->ringt_base/2)
8775
/* Increment the ringT counter so we can match it against
8776
values in chan_dahdi.conf for distinctive ring */
8777
if (++receivedRingT == ARRAY_LEN(curRingData))
8779
} else if (i & DAHDI_IOMUX_READ) {
8780
res = read(p->subs[idx].dfd, buf, sizeof(buf));
8782
if (errno != ELAST) {
8783
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
8792
if (p->ringt == 1) {
8799
if (p->usedistinctiveringdetection) {
8800
/* this only shows up if you have n of the dring patterns filled in */
8801
ast_verb(3, "Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
8803
for (counter = 0; counter < 3; counter++) {
8804
/* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
8806
/* this only shows up if you have n of the dring patterns filled in */
8807
ast_verb(3, "Checking %d,%d,%d\n",
8808
p->drings.ringnum[counter].ring[0],
8809
p->drings.ringnum[counter].ring[1],
8810
p->drings.ringnum[counter].ring[2]);
8812
for (counter1 = 0; counter1 < 3; counter1++) {
8813
ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
8814
if (p->drings.ringnum[counter].ring[counter1] == -1) {
8815
ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
8816
curRingData[counter1]);
8819
else if (curRingData[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
8820
curRingData[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
8821
ast_verb(3, "Ring pattern matched in range: %d to %d\n",
8822
(p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
8823
(p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
8827
if (distMatches == 3) {
8828
/* The ring matches, set the context to whatever is for distinctive ring.. */
8829
ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
8830
ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
8831
ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
8836
/* Restore linear mode (if appropriate) for Caller*ID processing */
8837
dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8842
ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
8845
ast_log(LOG_WARNING, "Unable to get caller ID space\n");
8851
ast_shrink_phone_number(number);
8852
ast_set_callerid(chan, number, name, number);
8855
ASTOBJ_UNREF(smdi_msg, ast_smdi_md_message_destroy);
8859
/* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
8860
if (flags & CID_MSGWAITING) {
8861
ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n", p->channel);
8862
notify_message(p->mailbox, 1);
8863
/* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
8864
if (p->mwimonitor_rpas) {
8868
} else if (flags & CID_NOMSGWAITING) {
8869
ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n", p->channel);
8870
notify_message(p->mailbox, 0);
8871
/* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
8872
if (p->mwimonitor_rpas) {
8878
ast_setstate(chan, AST_STATE_RING);
8880
p->ringt = p->ringt_base;
8881
res = ast_pbx_run(chan);
8884
ast_log(LOG_WARNING, "PBX exited non-zero\n");
8888
ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
8889
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8891
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
8893
res = tone_zone_play_tone(p->subs[idx].dfd, DAHDI_TONE_CONGESTION);
8895
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
8898
ast_mutex_lock(&ss_thread_lock);
8900
ast_cond_signal(&ss_thread_complete);
8901
ast_mutex_unlock(&ss_thread_lock);
8905
struct mwi_thread_data {
8906
struct dahdi_pvt *pvt;
8907
unsigned char buf[READ_SIZE];
8911
static int calc_energy(const unsigned char *buf, int len, int law)
8919
for (x = 0; x < len; x++)
8920
sum += abs(law == AST_FORMAT_ULAW ? AST_MULAW(buf[x]) : AST_ALAW(buf[x]));
8925
static void *mwi_thread(void *data)
8927
struct mwi_thread_data *mtd = data;
8928
struct callerid_state *cs;
8931
char *name, *number;
8934
unsigned int spill_done = 0;
8935
int spill_result = -1;
8937
if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
8938
mtd->pvt->mwimonitoractive = 0;
8943
callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
8945
bump_gains(mtd->pvt);
8948
i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
8949
if ((res = ioctl(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_IOMUX, &i))) {
8950
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
8954
if (i & DAHDI_IOMUX_SIGEVENT) {
8955
struct ast_channel *chan;
8957
/* If we get an event, screen out events that we do not act on.
8958
* Otherwise, cancel and go to the simple switch to let it deal with it.
8960
res = dahdi_get_event(mtd->pvt->subs[SUB_REAL].dfd);
8963
case DAHDI_EVENT_NEONMWI_ACTIVE:
8964
case DAHDI_EVENT_NEONMWI_INACTIVE:
8965
case DAHDI_EVENT_NONE:
8966
case DAHDI_EVENT_BITSCHANGED:
8968
case DAHDI_EVENT_NOALARM:
8969
mtd->pvt->inalarm = 0;
8970
ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", mtd->pvt->channel);
8971
manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
8972
"Channel: %d\r\n", mtd->pvt->channel);
8974
case DAHDI_EVENT_ALARM:
8975
mtd->pvt->inalarm = 1;
8976
res = get_alarms(mtd->pvt);
8977
handle_alarms(mtd->pvt, res);
8978
break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
8980
ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to ss_thread\n", res, event2str(res));
8983
restore_gains(mtd->pvt);
8984
mtd->pvt->ringt = mtd->pvt->ringt_base;
8986
if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, 0))) {
8987
if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
8988
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel);
8989
res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
8991
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", mtd->pvt->channel);
8998
ast_log(LOG_WARNING, "Could not create channel to handle call\n");
9001
} else if (i & DAHDI_IOMUX_READ) {
9002
if ((res = read(mtd->pvt->subs[SUB_REAL].dfd, mtd->buf, sizeof(mtd->buf))) < 0) {
9003
if (errno != ELAST) {
9004
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
9011
if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
9012
ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
9014
} else if (spill_result) {
9018
/* keep reading data until the energy level drops below the threshold
9019
so we don't get another 'trigger' on the remaining carrier signal
9021
if (calc_energy(mtd->buf, res, AST_LAW(mtd->pvt)) <= mwilevel)
9024
if (samples > (8000 * 4)) /*Termination case - time to give up*/
9029
if (spill_result == 1) {
9030
callerid_get(cs, &name, &number, &flags);
9031
if (flags & CID_MSGWAITING) {
9032
ast_log(LOG_NOTICE, "mwi: Have Messages on channel %d\n", mtd->pvt->channel);
9033
notify_message(mtd->pvt->mailbox, 1);
9034
} else if (flags & CID_NOMSGWAITING) {
9035
ast_log(LOG_NOTICE, "mwi: No Messages on channel %d\n", mtd->pvt->channel);
9036
notify_message(mtd->pvt->mailbox, 0);
9038
ast_log(LOG_NOTICE, "mwi: Status unknown on channel %d\n", mtd->pvt->channel);
9046
restore_gains(mtd->pvt);
9049
mtd->pvt->mwimonitoractive = 0;
9057
* The following three functions (mwi_send_init, mwi_send_process_buffer,
9058
* mwi_send_process_event) work with the do_monitor thread to generate mwi spills
9059
* that are sent out via FXA port on voicemail state change. The execution of
9060
* the mwi send is state driven and can either generate a ring pulse prior to
9061
* sending the fsk spill or simply send an fsk spill.
9063
static int mwi_send_init(struct dahdi_pvt * pvt)
9067
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
9068
/* Determine how this spill is to be sent */
9069
if (pvt->mwisend_rpas) {
9070
pvt->mwisend_data.mwisend_current = MWI_SEND_SA;
9071
pvt->mwisendactive = 1;
9072
} else if (pvt->mwisend_fsk) {
9073
pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
9074
pvt->mwisendactive = 1;
9076
pvt->mwisendactive = 0;
9081
pvt->mwisend_data.mwisend_current = MWI_SEND_SA;
9083
pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
9085
pvt->mwisendactive = 1;
9088
if (pvt->cidspill) {
9089
ast_log(LOG_WARNING, "cidspill already exists when trying to send FSK MWI\n");
9090
ast_free(pvt->cidspill);
9091
pvt->cidspill = NULL;
9095
pvt->cidspill = ast_calloc(1, MAX_CALLERID_SIZE);
9096
if (!pvt->cidspill) {
9097
pvt->mwisendactive = 0;
9100
x = DAHDI_FLUSH_BOTH;
9101
res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_FLUSH, &x);
9103
ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_ONHOOKTRANSFER, &x);
9104
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
9105
if (pvt->mwisend_fsk) {
9107
pvt->cidlen = vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL,
9108
AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
9110
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
9116
static int mwi_send_process_buffer(struct dahdi_pvt * pvt, int num_read)
9121
/* sanity check to catch if this had been interrupted previously
9122
* i.e. state says there is more to do but there is no spill allocated
9124
if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current && !pvt->cidspill) {
9125
pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
9126
} else if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
9127
/* Normal processing -- Perform mwi send action */
9128
switch ( pvt->mwisend_data.mwisend_current) {
9130
/* Send the Ring Pulse Signal Alert */
9131
res = ioctl(pvt->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &AS_RP_cadence);
9133
ast_log(LOG_WARNING, "Unable to set RP-AS ring cadence: %s\n", strerror(errno));
9136
res = dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RING);
9137
pvt->mwisend_data.mwisend_current = MWI_SEND_SA_WAIT;
9139
case MWI_SEND_SA_WAIT: /* do nothing until I get RINGEROFF event */
9141
case MWI_SEND_PAUSE: /* Wait between alert and spill - min of 500 mS*/
9142
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
9143
if (pvt->mwisend_fsk) {
9145
gettimeofday(&now, NULL);
9146
if ((int)(now.tv_sec - pvt->mwisend_data.pause.tv_sec) * 1000000 + (int)now.tv_usec - (int)pvt->mwisend_data.pause.tv_usec > 500000) {
9147
pvt->mwisend_data.mwisend_current = MWI_SEND_SPILL;
9149
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
9150
} else { /* support for mwisendtype=nofsk */
9151
pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP;
9155
case MWI_SEND_SPILL:
9156
/* We read some number of bytes. Write an equal amount of data */
9158
if (num_read > pvt->cidlen - pvt->cidpos)
9159
num_read = pvt->cidlen - pvt->cidpos;
9160
res = write(pvt->subs[SUB_REAL].dfd, pvt->cidspill + pvt->cidpos, num_read);
9163
if (pvt->cidpos >= pvt->cidlen) {
9164
pvt->mwisend_data.mwisend_current = MWI_SEND_CLEANUP;
9167
ast_log(LOG_WARNING, "MWI FSK Send Write failed: %s\n", strerror(errno));
9172
case MWI_SEND_CLEANUP:
9173
/* For now, do nothing */
9174
pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
9177
/* Should not get here, punt*/
9182
if (MWI_SEND_DONE == pvt->mwisend_data.mwisend_current) {
9183
if (pvt->cidspill) {
9184
ast_free(pvt->cidspill);
9185
pvt->cidspill = NULL;
9189
pvt->mwisendactive = 0;
9193
if (pvt->cidspill) {
9194
ast_free(pvt->cidspill);
9195
pvt->cidspill = NULL;
9199
pvt->mwisendactive = 0;
9203
static int mwi_send_process_event(struct dahdi_pvt * pvt, int event)
9207
if (MWI_SEND_DONE != pvt->mwisend_data.mwisend_current) {
9209
case DAHDI_EVENT_RINGEROFF:
9210
if(pvt->mwisend_data.mwisend_current == MWI_SEND_SA_WAIT) {
9213
if (dahdi_set_hook(pvt->subs[SUB_REAL].dfd, DAHDI_RINGOFF) ) {
9214
ast_log(LOG_WARNING, "Unable to finsh RP-AS: %s mwi send aborted\n", strerror(errno));
9216
ast_free(pvt->cidspill);
9217
pvt->cidspill = NULL;
9219
pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
9220
pvt->mwisendactive = 0;
9222
pvt->mwisend_data.mwisend_current = MWI_SEND_PAUSE;
9223
gettimeofday(&pvt->mwisend_data.pause, NULL);
9227
/* Going off hook, I need to punt this spill */
9228
case DAHDI_EVENT_RINGOFFHOOK:
9229
if (pvt->cidspill) {
9230
ast_free(pvt->cidspill);
9231
pvt->cidspill = NULL;
9235
pvt->mwisend_data.mwisend_current = MWI_SEND_DONE;
9236
pvt->mwisendactive = 0;
9238
case DAHDI_EVENT_RINGERON:
9239
case DAHDI_EVENT_HOOKCOMPLETE:
9248
/* destroy a DAHDI channel, identified by its number */
9249
static int dahdi_destroy_channel_bynum(int channel)
9251
struct dahdi_pvt *tmp = NULL;
9252
struct dahdi_pvt *prev = NULL;
9256
if (tmp->channel == channel) {
9257
int x = DAHDI_FLASH;
9258
ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
9259
destroy_channel(prev, tmp, 1);
9260
ast_module_unref(ast_module_info->self);
9261
return RESULT_SUCCESS;
9266
return RESULT_FAILURE;
9269
static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
9273
struct ast_channel *chan;
9275
/* Handle an event on a given channel for the monitor thread. */
9278
case DAHDI_EVENT_NONE:
9279
case DAHDI_EVENT_BITSCHANGED:
9281
case DAHDI_EVENT_WINKFLASH:
9282
case DAHDI_EVENT_RINGOFFHOOK:
9283
if (i->inalarm) break;
9284
if (i->radio) break;
9285
/* Got a ring/answer. What kind of channel are we? */
9290
res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
9291
i->fxsoffhookstate = 1;
9292
if (res && (errno == EBUSY))
9295
/* Cancel VMWI spill */
9296
ast_free(i->cidspill);
9301
/* The channel is immediately up. Start right away */
9302
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
9303
chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0);
9305
ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
9306
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
9308
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
9311
/* Check for callerid, digits, etc */
9312
chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0);
9314
if (has_voicemail(i))
9315
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
9317
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
9319
ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
9320
if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
9321
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
9322
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
9324
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
9328
ast_log(LOG_WARNING, "Unable to create channel\n");
9334
i->ringt = i->ringt_base;
9339
case SIG_FEATDMF_TA:
9342
case SIG_FGC_CAMAMF:
9348
case SIG_SF_FEATDMF:
9351
/* Check for callerid, digits, etc */
9352
if (i->cid_start == CID_START_POLARITY_IN) {
9353
chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
9355
chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0);
9359
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
9360
} else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
9361
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
9362
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
9364
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
9370
ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
9371
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
9373
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
9377
case DAHDI_EVENT_NOALARM:
9379
ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
9380
manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
9381
"Channel: %d\r\n", i->channel);
9383
case DAHDI_EVENT_ALARM:
9385
res = get_alarms(i);
9386
handle_alarms(i, res);
9387
/* fall thru intentionally */
9388
case DAHDI_EVENT_ONHOOK:
9391
/* Back on hook. Hang up. */
9397
case SIG_FEATDMF_TA:
9400
case SIG_FGC_CAMAMF:
9406
case SIG_SF_FEATDMF:
9413
case SIG_GR303FXSKS:
9414
dahdi_disable_ec(i);
9415
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
9416
dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
9418
case SIG_GR303FXOKS:
9420
dahdi_disable_ec(i);
9421
/* Diddle the battery for the zhone */
9423
dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
9426
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
9427
dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
9433
dahdi_disable_ec(i);
9434
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
9437
ast_log(LOG_WARNING, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
9438
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
9441
if (i->sig & __DAHDI_SIG_FXO) {
9442
i->fxsoffhookstate = 0;
9445
case DAHDI_EVENT_POLARITY:
9450
/* We have already got a PR before the channel was
9451
created, but it wasn't handled. We need polarity
9452
to be REV for remote hangup detection to work.
9453
At least in Spain */
9454
if (i->hanguponpolarityswitch)
9455
i->polarity = POLARITY_REV;
9456
if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) {
9457
i->polarity = POLARITY_REV;
9458
ast_verb(2, "Starting post polarity "
9459
"CID detection on channel %d\n",
9461
chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
9463
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
9464
} else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
9465
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
9470
ast_log(LOG_WARNING, "handle_init_event detected "
9471
"polarity reversal on non-FXO (SIG_FXS) "
9472
"interface %d\n", i->channel);
9475
case DAHDI_EVENT_REMOVED: /* destroy channel, will actually do so in do_monitor */
9477
"Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
9480
case DAHDI_EVENT_NEONMWI_ACTIVE:
9481
if (i->mwimonitor_neon) {
9482
notify_message(i->mailbox, 1);
9483
ast_log(LOG_NOTICE, "NEON MWI set for channel %d, mailbox %s \n", i->channel, i->mailbox);
9486
case DAHDI_EVENT_NEONMWI_INACTIVE:
9487
if (i->mwimonitor_neon) {
9488
notify_message(i->mailbox, 0);
9489
ast_log(LOG_NOTICE, "NEON MWI cleared for channel %d, mailbox %s\n", i->channel, i->mailbox);
9496
static void *do_monitor(void *data)
9498
int count, res, res2, spoint, pollres=0;
9499
struct dahdi_pvt *i;
9500
struct dahdi_pvt *last = NULL;
9501
struct dahdi_pvt *doomed;
9502
time_t thispass = 0, lastpass = 0;
9505
struct pollfd *pfds=NULL;
9507
/* This thread monitors all the frame relay interfaces which are not yet in use
9508
(and thus do not have a separate thread) indefinitely */
9509
/* From here on out, we die whenever asked */
9511
if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
9512
ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
9515
ast_debug(1, "Monitor starting...\n");
9517
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
9520
/* Lock the interface list */
9521
ast_mutex_lock(&iflock);
9522
if (!pfds || (lastalloc != ifcount)) {
9528
if (!(pfds = ast_calloc(1, ifcount * sizeof(*pfds)))) {
9529
ast_mutex_unlock(&iflock);
9533
lastalloc = ifcount;
9535
/* Build the stuff we're going to poll on, that is the socket of every
9536
dahdi_pvt that does not have an associated owner channel */
9540
if ((i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
9541
if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
9542
/* This needs to be watched, as it lacks an owner */
9543
pfds[count].fd = i->subs[SUB_REAL].dfd;
9544
pfds[count].events = POLLPRI;
9545
pfds[count].revents = 0;
9546
/* If we are monitoring for VMWI or sending CID, we need to
9547
read from the channel as well */
9548
if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
9549
pfds[count].events |= POLLIN;
9555
/* Okay, now that we know what to do, release the interface lock */
9556
ast_mutex_unlock(&iflock);
9558
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
9559
pthread_testcancel();
9560
/* Wait at least a second for something to happen */
9561
res = poll(pfds, count, 1000);
9562
pthread_testcancel();
9563
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
9565
/* Okay, poll has finished. Let's see what happened. */
9567
if ((errno != EAGAIN) && (errno != EINTR))
9568
ast_log(LOG_WARNING, "poll return %d: %s\n", res, strerror(errno));
9571
/* Alright, lock the interface list again, and let's look and see what has
9573
ast_mutex_lock(&iflock);
9576
lastpass = thispass;
9577
thispass = time(NULL);
9580
for (i = iflist;; i = i->next) {
9583
res = dahdi_destroy_channel_bynum(doomed->channel);
9585
ast_log(LOG_WARNING, "Couldn't find channel to destroy, hopefully another destroy operation just happened.\n");
9593
if (thispass != lastpass) {
9594
if (!found && ((i == last) || ((i == iflist) && !last))) {
9597
/* Only allow MWI to be initiated on a quiescent fxs port */
9598
if (!last->mwisendactive && last->sig & __DAHDI_SIG_FXO &&
9599
!last->fxsoffhookstate && !last->owner &&
9600
!ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3)) {
9601
res = has_voicemail(last);
9602
if (last->msgstate != res) {
9603
/* Set driver resources for signalling VMWI */
9604
res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
9606
/* TODO: This message will ALWAYS be generated on some cards; any way to restrict it to those cards where it is interesting? */
9607
ast_debug(3, "Unable to control message waiting led on channel %d: %s\n", last->channel, strerror(errno));
9609
/* If enabled for FSK spill then initiate it */
9610
if (mwi_send_init(last)) {
9611
ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
9613
last->msgstate = res;
9621
if ((i->subs[SUB_REAL].dfd > -1) && i->sig) {
9622
if (i->radio && !i->owner)
9624
res = dahdi_get_event(i->subs[SUB_REAL].dfd);
9627
ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
9628
/* Don't hold iflock while handling init events */
9629
ast_mutex_unlock(&iflock);
9630
doomed = handle_init_event(i, res);
9631
ast_mutex_lock(&iflock);
9635
pollres = ast_fdisset(pfds, i->subs[SUB_REAL].dfd, count, &spoint);
9636
if (pollres & POLLIN) {
9637
if (i->owner || i->subs[SUB_REAL].owner) {
9641
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d) in read...\n", i->subs[SUB_REAL].dfd);
9644
if (!i->mwimonitor_fsk && !i->mwisendactive) {
9645
ast_log(LOG_WARNING, "Whoa.... I'm not looking for MWI or sending MWI but am reading (%d)...\n", i->subs[SUB_REAL].dfd);
9648
res = read(i->subs[SUB_REAL].dfd, buf, sizeof(buf));
9650
if (i->mwimonitor_fsk) {
9651
if (calc_energy((unsigned char *) buf, res, AST_LAW(i)) > mwilevel) {
9652
pthread_attr_t attr;
9654
struct mwi_thread_data *mtd;
9656
pthread_attr_init(&attr);
9657
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
9659
ast_log(LOG_DEBUG, "Maybe some MWI on port %d!\n", i->channel);
9660
if ((mtd = ast_calloc(1, sizeof(*mtd)))) {
9662
memcpy(mtd->buf, buf, res);
9664
if (ast_pthread_create_background(&threadid, &attr, mwi_thread, mtd)) {
9665
ast_log(LOG_WARNING, "Unable to start mwi thread on channel %d\n", i->channel);
9668
i->mwimonitoractive = 1;
9672
if (i->mwisendactive) {
9673
mwi_send_process_buffer(i, res);
9676
ast_log(LOG_WARNING, "Read failed with %d: %s\n", res, strerror(errno));
9679
if (pollres & POLLPRI) {
9680
if (i->owner || i->subs[SUB_REAL].owner) {
9684
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d)...\n", i->subs[SUB_REAL].dfd);
9687
res = dahdi_get_event(i->subs[SUB_REAL].dfd);
9688
ast_debug(1, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
9689
/* Don't hold iflock while handling init events */
9690
ast_mutex_unlock(&iflock);
9691
if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
9692
doomed = handle_init_event(i, res);
9694
ast_mutex_lock(&iflock);
9698
ast_mutex_unlock(&iflock);
9705
static int restart_monitor(void)
9707
/* If we're supposed to be stopped -- stay stopped */
9708
if (monitor_thread == AST_PTHREADT_STOP)
9710
ast_mutex_lock(&monlock);
9711
if (monitor_thread == pthread_self()) {
9712
ast_mutex_unlock(&monlock);
9713
ast_log(LOG_WARNING, "Cannot kill myself\n");
9716
if (monitor_thread != AST_PTHREADT_NULL) {
9717
/* Wake up the thread */
9718
pthread_kill(monitor_thread, SIGURG);
9720
/* Start a new monitor */
9721
if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
9722
ast_mutex_unlock(&monlock);
9723
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
9727
ast_mutex_unlock(&monlock);
9731
#if defined(HAVE_PRI)
9732
static int pri_resolve_span(int *span, int channel, int offset, struct dahdi_spaninfo *si)
9736
/* Get appropriate trunk group if there is one */
9737
trunkgroup = pris[*span].mastertrunkgroup;
9739
/* Select a specific trunk group */
9740
for (x = 0; x < NUM_SPANS; x++) {
9741
if (pris[x].trunkgroup == trunkgroup) {
9746
ast_log(LOG_WARNING, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel, *span, trunkgroup);
9749
if (pris[*span].trunkgroup) {
9750
ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span, pris[*span].trunkgroup);
9752
} else if (pris[*span].mastertrunkgroup) {
9753
ast_log(LOG_WARNING, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span, pris[*span].mastertrunkgroup);
9756
if (si->totalchans == 31) {
9758
pris[*span].dchannels[0] = 16 + offset;
9759
} else if (si->totalchans == 24) {
9761
pris[*span].dchannels[0] = 24 + offset;
9762
} else if (si->totalchans == 3) {
9764
pris[*span].dchannels[0] = 3 + offset;
9766
ast_log(LOG_WARNING, "Unable to use span %d, since the D-channel cannot be located (unexpected span size of %d channels)\n", *span, si->totalchans);
9770
pris[*span].dchanavail[0] |= DCHAN_PROVISIONED;
9771
pris[*span].offset = offset;
9772
pris[*span].span = *span + 1;
9777
#endif /* defined(HAVE_PRI) */
9779
#if defined(HAVE_PRI)
9780
static int pri_create_trunkgroup(int trunkgroup, int *channels)
9782
struct dahdi_spaninfo si;
9783
struct dahdi_params p;
9788
for (x = 0; x < NUM_SPANS; x++) {
9789
if (pris[x].trunkgroup == trunkgroup) {
9790
ast_log(LOG_WARNING, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
9794
for (y = 0; y < NUM_DCHANS; y++) {
9797
memset(&si, 0, sizeof(si));
9798
memset(&p, 0, sizeof(p));
9799
fd = open("/dev/dahdi/channel", O_RDWR);
9801
ast_log(LOG_WARNING, "Failed to open channel: %s\n", strerror(errno));
9805
if (ioctl(fd, DAHDI_SPECIFY, &x)) {
9806
ast_log(LOG_WARNING, "Failed to specify channel %d: %s\n", channels[y], strerror(errno));
9810
if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
9811
ast_log(LOG_WARNING, "Failed to get channel parameters for channel %d: %s\n", channels[y], strerror(errno));
9814
if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
9815
ast_log(LOG_WARNING, "Failed go get span information on channel %d (span %d): %s\n", channels[y], p.spanno, strerror(errno));
9819
span = p.spanno - 1;
9820
if (pris[span].trunkgroup) {
9821
ast_log(LOG_WARNING, "Span %d is already provisioned for trunk group %d\n", span + 1, pris[span].trunkgroup);
9825
if (pris[span].pvts[0]) {
9826
ast_log(LOG_WARNING, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
9831
pris[span].trunkgroup = trunkgroup;
9832
pris[span].offset = channels[y] - p.chanpos;
9835
pris[ospan].dchannels[y] = channels[y];
9836
pris[ospan].dchanavail[y] |= DCHAN_PROVISIONED;
9837
pris[span].span = span + 1;
9842
#endif /* defined(HAVE_PRI) */
9844
#if defined(HAVE_PRI)
9845
static int pri_create_spanmap(int span, int trunkgroup, int logicalspan)
9847
if (pris[span].mastertrunkgroup) {
9848
ast_log(LOG_WARNING, "Span %d is already part of trunk group %d, cannot add to trunk group %d\n", span + 1, pris[span].mastertrunkgroup, trunkgroup);
9851
pris[span].mastertrunkgroup = trunkgroup;
9852
pris[span].prilogicalspan = logicalspan;
9855
#endif /* defined(HAVE_PRI) */
9857
#if defined(HAVE_SS7)
9858
static unsigned int parse_pointcode(const char *pcstring)
9860
unsigned int code1, code2, code3;
9863
numvals = sscanf(pcstring, "%30d-%30d-%30d", &code1, &code2, &code3);
9867
return (code1 << 16) | (code2 << 8) | code3;
9871
#endif /* defined(HAVE_SS7) */
9873
#if defined(HAVE_SS7)
9874
static struct dahdi_ss7 * ss7_resolve_linkset(int linkset)
9876
if ((linkset < 0) || (linkset >= NUM_SPANS))
9879
return &linksets[linkset - 1];
9881
#endif /* defined(HAVE_SS7) */
9884
static void dahdi_r2_destroy_links(void)
9890
for (; i < r2links_count; i++) {
9891
if (r2links[i]->r2master != AST_PTHREADT_NULL) {
9892
pthread_cancel(r2links[i]->r2master);
9893
pthread_join(r2links[i]->r2master, NULL);
9894
openr2_context_delete(r2links[i]->protocol_context);
9896
ast_free(r2links[i]);
9903
#define R2_LINK_CAPACITY 10
9904
static struct dahdi_mfcr2 *dahdi_r2_get_link(void)
9906
struct dahdi_mfcr2 *new_r2link = NULL;
9907
struct dahdi_mfcr2 **new_r2links = NULL;
9908
/* this function is called just when starting up and no monitor threads have been launched,
9909
no need to lock monitored_count member */
9910
if (!r2links_count || (r2links[r2links_count - 1]->monitored_count == R2_LINK_CAPACITY)) {
9911
new_r2link = ast_calloc(1, sizeof(**r2links));
9913
ast_log(LOG_ERROR, "Cannot allocate R2 link!\n");
9916
new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links)));
9918
ast_log(LOG_ERROR, "Cannot allocate R2 link!\n");
9919
ast_free(new_r2link);
9922
r2links = new_r2links;
9923
new_r2link->r2master = AST_PTHREADT_NULL;
9924
r2links[r2links_count] = new_r2link;
9926
ast_log(LOG_DEBUG, "Created new R2 link!\n");
9928
return r2links[r2links_count - 1];
9931
static int dahdi_r2_set_context(struct dahdi_mfcr2 *r2_link, const struct dahdi_chan_conf *conf)
9933
char tmplogdir[] = "/tmp";
9934
char logdir[OR2_MAX_PATH];
9937
r2_link->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface,
9938
&dahdi_r2_transcode_iface, conf->mfcr2.variant, conf->mfcr2.max_ani,
9939
conf->mfcr2.max_dnis);
9940
if (!r2_link->protocol_context) {
9943
openr2_context_set_log_level(r2_link->protocol_context, conf->mfcr2.loglevel);
9944
openr2_context_set_ani_first(r2_link->protocol_context, conf->mfcr2.get_ani_first);
9945
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
9946
openr2_context_set_skip_category_request(r2_link->protocol_context, conf->mfcr2.skip_category_request);
9948
openr2_context_set_mf_threshold(r2_link->protocol_context, threshold);
9949
openr2_context_set_mf_back_timeout(r2_link->protocol_context, conf->mfcr2.mfback_timeout);
9950
openr2_context_set_metering_pulse_timeout(r2_link->protocol_context, conf->mfcr2.metering_pulse_timeout);
9951
openr2_context_set_double_answer(r2_link->protocol_context, conf->mfcr2.double_answer);
9952
openr2_context_set_immediate_accept(r2_link->protocol_context, conf->mfcr2.immediate_accept);
9953
if (ast_strlen_zero(conf->mfcr2.logdir)) {
9954
if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
9955
ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
9958
snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", conf->mfcr2.logdir);
9959
if (snres >= sizeof(logdir)) {
9960
ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir);
9961
if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
9962
ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
9965
if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
9966
ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir);
9970
if (!ast_strlen_zero(conf->mfcr2.r2proto_file)) {
9971
if (openr2_context_configure_from_advanced_file(r2_link->protocol_context, conf->mfcr2.r2proto_file)) {
9972
ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file);
9975
r2_link->monitored_count = 0;
9980
/* converts a DAHDI sigtype to signalling as can be configured from
9982
* While both have basically the same values, this will later be the
9983
* place to add filters and sanity checks
9985
static int sigtype_to_signalling(int sigtype)
9990
static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, struct dahdi_pri *pri, int reloading)
9992
/* Make a dahdi_pvt structure for this interface (or CRV if "pri" is specified) */
9993
struct dahdi_pvt *tmp = NULL, *tmp2, *prev = NULL;
9995
struct dahdi_bufferinfo bi;
10001
struct dahdi_pvt **wlist;
10002
struct dahdi_pvt **wend;
10003
struct dahdi_params p;
10010
wlist = &pri->crvs;
10011
wend = &pri->crvend;
10019
if (!tmp2->destroy) {
10020
if (tmp2->channel == channel) {
10025
if (tmp2->channel > channel) {
10033
if (!here && reloading != 1) {
10034
if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
10039
ast_mutex_init(&tmp->lock);
10041
for (x = 0; x < 3; x++)
10042
tmp->subs[x].dfd = -1;
10043
tmp->channel = channel;
10044
tmp->priindication_oob = conf->chan.priindication_oob;
10048
int chan_sig = conf->chan.sig;
10050
if ((channel != CHAN_PSEUDO) && !pri) {
10052
snprintf(fn, sizeof(fn), "%d", channel);
10053
/* Open non-blocking */
10054
tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
10055
while (tmp->subs[SUB_REAL].dfd < 0 && reloading == 2 && count < 1000) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
10057
tmp->subs[SUB_REAL].dfd = dahdi_open(fn);
10060
/* Allocate a DAHDI structure */
10061
if (tmp->subs[SUB_REAL].dfd < 0) {
10062
ast_log(LOG_ERROR, "Unable to open channel %d: %s\nhere = %d, tmp->channel = %d, channel = %d\n", channel, strerror(errno), here, tmp->channel, channel);
10063
destroy_dahdi_pvt(&tmp);
10066
memset(&p, 0, sizeof(p));
10067
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
10069
ast_log(LOG_ERROR, "Unable to get parameters: %s\n", strerror(errno));
10070
destroy_dahdi_pvt(&tmp);
10073
if (conf->is_sig_auto)
10074
chan_sig = sigtype_to_signalling(p.sigtype);
10075
if (p.sigtype != (chan_sig & 0x3ffff)) {
10076
ast_log(LOG_ERROR, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel, sig2str(chan_sig), sig2str(p.sigtype));
10077
destroy_dahdi_pvt(&tmp);
10080
tmp->law = p.curlaw;
10081
tmp->span = p.spanno;
10082
span = p.spanno - 1;
10084
if (channel == CHAN_PSEUDO)
10086
else if ((chan_sig != SIG_FXOKS) && (chan_sig != SIG_FXSKS)) {
10087
ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
10092
if (chan_sig == SIG_SS7) {
10093
struct dahdi_ss7 *ss7;
10095
if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &clear)) {
10096
ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
10097
destroy_dahdi_pvt(&tmp);
10101
ss7 = ss7_resolve_linkset(cur_linkset);
10103
ast_log(LOG_ERROR, "Unable to find linkset %d\n", cur_linkset);
10104
destroy_dahdi_pvt(&tmp);
10107
if (cur_cicbeginswith < 0) {
10108
ast_log(LOG_ERROR, "Need to set cicbeginswith for the channels!\n");
10109
destroy_dahdi_pvt(&tmp);
10113
tmp->cic = cur_cicbeginswith++;
10115
/* DB: Add CIC's DPC information */
10116
tmp->dpc = cur_defaultdpc;
10119
tmp->ss7call = NULL;
10120
ss7->pvts[ss7->numchans++] = tmp;
10122
ast_copy_string(ss7->internationalprefix, conf->ss7.internationalprefix, sizeof(ss7->internationalprefix));
10123
ast_copy_string(ss7->nationalprefix, conf->ss7.nationalprefix, sizeof(ss7->nationalprefix));
10124
ast_copy_string(ss7->subscriberprefix, conf->ss7.subscriberprefix, sizeof(ss7->subscriberprefix));
10125
ast_copy_string(ss7->unknownprefix, conf->ss7.unknownprefix, sizeof(ss7->unknownprefix));
10127
ss7->called_nai = conf->ss7.called_nai;
10128
ss7->calling_nai = conf->ss7.calling_nai;
10132
if (chan_sig == SIG_MFCR2 && reloading != 1) {
10133
struct dahdi_mfcr2 *r2_link;
10134
r2_link = dahdi_r2_get_link();
10136
ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
10137
destroy_dahdi_pvt(&tmp);
10140
if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link, conf)) {
10141
ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
10142
destroy_dahdi_pvt(&tmp);
10145
if (r2_link->numchans == (sizeof(r2_link->pvts)/sizeof(r2_link->pvts[0]))) {
10146
ast_log(LOG_ERROR, "Cannot add more channels to this link!\n");
10147
destroy_dahdi_pvt(&tmp);
10150
r2_link->pvts[r2_link->numchans++] = tmp;
10151
tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
10152
tmp->subs[SUB_REAL].dfd,
10154
if (!tmp->r2chan) {
10155
openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
10156
ast_log(LOG_ERROR, "Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
10157
destroy_dahdi_pvt(&tmp);
10160
tmp->mfcr2 = r2_link;
10161
if (conf->mfcr2.call_files) {
10162
openr2_chan_enable_call_files(tmp->r2chan);
10164
openr2_chan_set_client_data(tmp->r2chan, tmp);
10165
/* cast seems to be needed to get rid of the annoying warning regarding format attribute */
10166
openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
10167
openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel);
10168
tmp->mfcr2_category = conf->mfcr2.category;
10169
tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
10170
tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
10171
tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
10172
tmp->mfcr2_accept_on_offer = conf->mfcr2.accept_on_offer;
10173
tmp->mfcr2call = 0;
10174
tmp->mfcr2_dnis_index = 0;
10175
tmp->mfcr2_ani_index = 0;
10176
r2_link->monitored_count++;
10180
if ((chan_sig == SIG_PRI) || (chan_sig == SIG_BRI) || (chan_sig == SIG_BRI_PTMP) || (chan_sig == SIG_GR303FXOKS) || (chan_sig == SIG_GR303FXSKS)) {
10186
if (((chan_sig == SIG_PRI) || (chan_sig == SIG_BRI) || (chan_sig == SIG_BRI_PTMP))
10187
&& ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &offset)) {
10188
ast_log(LOG_ERROR, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(errno));
10189
destroy_dahdi_pvt(&tmp);
10192
if (span >= NUM_SPANS) {
10193
ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
10194
destroy_dahdi_pvt(&tmp);
10197
struct dahdi_spaninfo si;
10199
if (ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SPANSTAT,&si) == -1) {
10200
ast_log(LOG_ERROR, "Unable to get span status: %s\n", strerror(errno));
10201
destroy_dahdi_pvt(&tmp);
10204
/* Store the logical span first based upon the real span */
10205
tmp->logicalspan = pris[span].prilogicalspan;
10206
pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
10208
ast_log(LOG_WARNING, "Channel %d: Unable to find locate channel/trunk group!\n", channel);
10209
destroy_dahdi_pvt(&tmp);
10212
if ((chan_sig == SIG_PRI) ||
10213
(chan_sig == SIG_BRI) ||
10214
(chan_sig == SIG_BRI_PTMP))
10215
myswitchtype = conf->pri.switchtype;
10217
myswitchtype = PRI_SWITCH_GR303_TMC;
10218
/* Make sure this isn't a d-channel */
10220
for (x = 0; x < NUM_SPANS; x++) {
10221
for (y = 0; y < NUM_DCHANS; y++) {
10222
if (pris[x].dchannels[y] == tmp->channel) {
10228
offset = p.chanpos;
10229
if (!matchesdchan) {
10230
if (pris[span].nodetype && (pris[span].nodetype != conf->pri.nodetype)) {
10231
ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
10232
destroy_dahdi_pvt(&tmp);
10235
if (pris[span].switchtype && (pris[span].switchtype != myswitchtype)) {
10236
ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
10237
destroy_dahdi_pvt(&tmp);
10240
if ((pris[span].dialplan) && (pris[span].dialplan != conf->pri.dialplan)) {
10241
ast_log(LOG_ERROR, "Span %d is already a %s dialing plan\n", span + 1, dialplan2str(pris[span].dialplan));
10242
destroy_dahdi_pvt(&tmp);
10245
if (!ast_strlen_zero(pris[span].idledial) && strcmp(pris[span].idledial, conf->pri.idledial)) {
10246
ast_log(LOG_ERROR, "Span %d already has idledial '%s'.\n", span + 1, conf->pri.idledial);
10247
destroy_dahdi_pvt(&tmp);
10250
if (!ast_strlen_zero(pris[span].idleext) && strcmp(pris[span].idleext, conf->pri.idleext)) {
10251
ast_log(LOG_ERROR, "Span %d already has idleext '%s'.\n", span + 1, conf->pri.idleext);
10252
destroy_dahdi_pvt(&tmp);
10255
if (pris[span].minunused && (pris[span].minunused != conf->pri.minunused)) {
10256
ast_log(LOG_ERROR, "Span %d already has minunused of %d.\n", span + 1, conf->pri.minunused);
10257
destroy_dahdi_pvt(&tmp);
10260
if (pris[span].minidle && (pris[span].minidle != conf->pri.minidle)) {
10261
ast_log(LOG_ERROR, "Span %d already has minidle of %d.\n", span + 1, conf->pri.minidle);
10262
destroy_dahdi_pvt(&tmp);
10265
if (pris[span].numchans >= MAX_CHANNELS) {
10266
ast_log(LOG_ERROR, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
10267
pris[span].trunkgroup);
10268
destroy_dahdi_pvt(&tmp);
10272
pris[span].sig = chan_sig;
10273
pris[span].nodetype = conf->pri.nodetype;
10274
pris[span].switchtype = myswitchtype;
10275
pris[span].nsf = conf->pri.nsf;
10276
pris[span].dialplan = conf->pri.dialplan;
10277
pris[span].localdialplan = conf->pri.localdialplan;
10278
pris[span].pvts[pris[span].numchans++] = tmp;
10279
pris[span].minunused = conf->pri.minunused;
10280
pris[span].minidle = conf->pri.minidle;
10281
pris[span].overlapdial = conf->pri.overlapdial;
10282
pris[span].qsigchannelmapping = conf->pri.qsigchannelmapping;
10283
pris[span].discardremoteholdretrieval = conf->pri.discardremoteholdretrieval;
10284
#ifdef HAVE_PRI_INBANDDISCONNECT
10285
pris[span].inbanddisconnect = conf->pri.inbanddisconnect;
10287
pris[span].facilityenable = conf->pri.facilityenable;
10288
ast_copy_string(pris[span].idledial, conf->pri.idledial, sizeof(pris[span].idledial));
10289
ast_copy_string(pris[span].idleext, conf->pri.idleext, sizeof(pris[span].idleext));
10290
ast_copy_string(pris[span].internationalprefix, conf->pri.internationalprefix, sizeof(pris[span].internationalprefix));
10291
ast_copy_string(pris[span].nationalprefix, conf->pri.nationalprefix, sizeof(pris[span].nationalprefix));
10292
ast_copy_string(pris[span].localprefix, conf->pri.localprefix, sizeof(pris[span].localprefix));
10293
ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix));
10294
ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix));
10295
pris[span].resetinterval = conf->pri.resetinterval;
10297
tmp->pri = &pris[span];
10298
tmp->prioffset = offset;
10301
ast_log(LOG_ERROR, "Channel %d is reserved for D-channel.\n", offset);
10302
destroy_dahdi_pvt(&tmp);
10307
tmp->prioffset = 0;
10311
chan_sig = tmp->sig;
10312
if (tmp->subs[SUB_REAL].dfd > -1) {
10313
memset(&p, 0, sizeof(p));
10314
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
10317
/* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
10318
switch (chan_sig) {
10326
case SIG_FEATDMF_TA:
10332
case SIG_FGC_CAMAMF:
10334
case SIG_SF_FEATDMF:
10341
/* XXX Waiting to hear back from Jim if these should be adjustable XXX */
10342
p.channo = channel;
10346
p.debouncetime = 5;
10349
p.channo = channel;
10350
/* Override timing settings based on config file */
10351
if (conf->timing.prewinktime >= 0)
10352
p.prewinktime = conf->timing.prewinktime;
10353
if (conf->timing.preflashtime >= 0)
10354
p.preflashtime = conf->timing.preflashtime;
10355
if (conf->timing.winktime >= 0)
10356
p.winktime = conf->timing.winktime;
10357
if (conf->timing.flashtime >= 0)
10358
p.flashtime = conf->timing.flashtime;
10359
if (conf->timing.starttime >= 0)
10360
p.starttime = conf->timing.starttime;
10361
if (conf->timing.rxwinktime >= 0)
10362
p.rxwinktime = conf->timing.rxwinktime;
10363
if (conf->timing.rxflashtime >= 0)
10364
p.rxflashtime = conf->timing.rxflashtime;
10365
if (conf->timing.debouncetime >= 0)
10366
p.debouncetime = conf->timing.debouncetime;
10369
/* dont set parms on a pseudo-channel (or CRV) */
10370
if (tmp->subs[SUB_REAL].dfd >= 0)
10372
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_PARAMS, &p);
10374
ast_log(LOG_ERROR, "Unable to set parameters: %s\n", strerror(errno));
10375
destroy_dahdi_pvt(&tmp);
10380
if (!here && (tmp->subs[SUB_REAL].dfd > -1)) {
10381
memset(&bi, 0, sizeof(bi));
10382
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
10384
bi.txbufpolicy = conf->chan.buf_policy;
10385
bi.rxbufpolicy = conf->chan.buf_policy;
10386
bi.numbufs = conf->chan.buf_no;
10387
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
10389
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno));
10392
ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno));
10394
tmp->buf_policy = conf->chan.buf_policy;
10395
tmp->buf_no = conf->chan.buf_no;
10396
tmp->usefaxbuffers = conf->chan.usefaxbuffers;
10397
tmp->faxbuf_policy = conf->chan.faxbuf_policy;
10398
tmp->faxbuf_no = conf->chan.faxbuf_no;
10399
/* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting
10400
* tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail.
10401
* The reason the ioctl call above failed should to be determined before worrying about the
10402
* faxbuffer-related ioctl calls */
10403
tmp->bufsize = bi.bufsize;
10406
tmp->immediate = conf->chan.immediate;
10407
tmp->transfertobusy = conf->chan.transfertobusy;
10408
if (chan_sig & __DAHDI_SIG_FXS) {
10409
tmp->mwimonitor_fsk = conf->chan.mwimonitor_fsk;
10410
tmp->mwimonitor_neon = conf->chan.mwimonitor_neon;
10411
tmp->mwimonitor_rpas = conf->chan.mwimonitor_rpas;
10413
tmp->sig = chan_sig;
10414
tmp->outsigmod = conf->chan.outsigmod;
10415
tmp->ringt_base = ringt_base;
10416
tmp->firstradio = 0;
10417
if ((chan_sig == SIG_FXOKS) || (chan_sig == SIG_FXOLS) || (chan_sig == SIG_FXOGS))
10418
tmp->permcallwaiting = conf->chan.callwaiting;
10420
tmp->permcallwaiting = 0;
10421
/* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
10423
tmp->drings = conf->chan.drings;
10425
/* 10 is a nice default. */
10426
if (tmp->drings.ringnum[0].range == 0)
10427
tmp->drings.ringnum[0].range = 10;
10428
if (tmp->drings.ringnum[1].range == 0)
10429
tmp->drings.ringnum[1].range = 10;
10430
if (tmp->drings.ringnum[2].range == 0)
10431
tmp->drings.ringnum[2].range = 10;
10433
tmp->usedistinctiveringdetection = usedistinctiveringdetection;
10434
tmp->callwaitingcallerid = conf->chan.callwaitingcallerid;
10435
tmp->threewaycalling = conf->chan.threewaycalling;
10436
tmp->adsi = conf->chan.adsi;
10437
tmp->use_smdi = conf->chan.use_smdi;
10438
tmp->permhidecallerid = conf->chan.hidecallerid;
10439
tmp->callreturn = conf->chan.callreturn;
10440
tmp->echocancel = conf->chan.echocancel;
10441
tmp->echotraining = conf->chan.echotraining;
10442
tmp->pulse = conf->chan.pulse;
10443
if (tmp->echocancel.head.tap_length) {
10444
tmp->echocanbridged = conf->chan.echocanbridged;
10446
if (conf->chan.echocanbridged)
10447
ast_log(LOG_NOTICE, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
10448
tmp->echocanbridged = 0;
10450
tmp->busydetect = conf->chan.busydetect;
10451
tmp->busycount = conf->chan.busycount;
10452
tmp->busy_tonelength = conf->chan.busy_tonelength;
10453
tmp->busy_quietlength = conf->chan.busy_quietlength;
10454
tmp->callprogress = conf->chan.callprogress;
10455
tmp->waitfordialtone = conf->chan.waitfordialtone;
10456
tmp->cancallforward = conf->chan.cancallforward;
10457
tmp->dtmfrelax = conf->chan.dtmfrelax;
10458
tmp->callwaiting = tmp->permcallwaiting;
10459
tmp->hidecallerid = tmp->permhidecallerid;
10460
tmp->channel = channel;
10461
tmp->stripmsd = conf->chan.stripmsd;
10462
tmp->use_callerid = conf->chan.use_callerid;
10463
tmp->cid_signalling = conf->chan.cid_signalling;
10464
tmp->cid_start = conf->chan.cid_start;
10465
tmp->dahditrcallerid = conf->chan.dahditrcallerid;
10466
tmp->restrictcid = conf->chan.restrictcid;
10467
tmp->use_callingpres = conf->chan.use_callingpres;
10468
tmp->priexclusive = conf->chan.priexclusive;
10469
if (tmp->usedistinctiveringdetection) {
10470
if (!tmp->use_callerid) {
10471
ast_log(LOG_NOTICE, "Distinctive Ring detect requires 'usecallerid' be on\n");
10472
tmp->use_callerid = 1;
10476
if (tmp->cid_signalling == CID_SIG_SMDI) {
10477
if (!tmp->use_smdi) {
10478
ast_log(LOG_WARNING, "SMDI callerid requires SMDI to be enabled, enabling...\n");
10482
if (tmp->use_smdi) {
10483
tmp->smdi_iface = ast_smdi_interface_find(conf->smdi_port);
10484
if (!(tmp->smdi_iface)) {
10485
ast_log(LOG_ERROR, "Invalid SMDI port specfied, disabling SMDI support\n");
10490
ast_copy_string(tmp->accountcode, conf->chan.accountcode, sizeof(tmp->accountcode));
10491
tmp->amaflags = conf->chan.amaflags;
10494
tmp->propconfno = -1;
10496
tmp->canpark = conf->chan.canpark;
10497
tmp->transfer = conf->chan.transfer;
10498
ast_copy_string(tmp->defcontext,conf->chan.context,sizeof(tmp->defcontext));
10499
ast_copy_string(tmp->language, conf->chan.language, sizeof(tmp->language));
10500
ast_copy_string(tmp->mohinterpret, conf->chan.mohinterpret, sizeof(tmp->mohinterpret));
10501
ast_copy_string(tmp->mohsuggest, conf->chan.mohsuggest, sizeof(tmp->mohsuggest));
10502
ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
10503
ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot));
10505
if ((tmp->sig != SIG_PRI) || (tmp->sig != SIG_SS7) || (tmp->sig != SIG_BRI) || (tmp->sig != SIG_BRI_PTMP) || (tmp->sig != SIG_MFCR2)) {
10506
ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
10507
ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
10509
tmp->cid_num[0] = '\0';
10510
tmp->cid_name[0] = '\0';
10512
ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
10513
if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) {
10514
char *mailbox, *context;
10515
mailbox = context = ast_strdupa(tmp->mailbox);
10516
strsep(&context, "@");
10517
if (ast_strlen_zero(context))
10518
context = "default";
10519
tmp->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
10520
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
10521
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
10522
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
10525
tmp->msgstate = -1;
10526
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10527
tmp->mwisend_setting = conf->chan.mwisend_setting;
10528
tmp->mwisend_fsk = conf->chan.mwisend_fsk;
10529
tmp->mwisend_rpas = conf->chan.mwisend_rpas;
10531
if (chan_sig & __DAHDI_SIG_FXO) {
10532
memset(&p, 0, sizeof(p));
10533
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
10535
tmp->fxsoffhookstate = p.rxisoffhook;
10537
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
10538
res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
10541
tmp->onhooktime = time(NULL);
10542
tmp->group = conf->chan.group;
10543
tmp->callgroup = conf->chan.callgroup;
10544
tmp->pickupgroup= conf->chan.pickupgroup;
10545
if (conf->chan.vars) {
10546
struct ast_variable *v, *tmpvar;
10547
for (v = conf->chan.vars ; v ; v = v->next) {
10548
if ((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
10549
tmpvar->next = tmp->vars;
10550
tmp->vars = tmpvar;
10554
tmp->cid_rxgain = conf->chan.cid_rxgain;
10555
tmp->rxgain = conf->chan.rxgain;
10556
tmp->txgain = conf->chan.txgain;
10557
tmp->tonezone = conf->chan.tonezone;
10558
if (tmp->subs[SUB_REAL].dfd > -1) {
10559
set_actual_gain(tmp->subs[SUB_REAL].dfd, 0, tmp->rxgain, tmp->txgain, tmp->law);
10561
ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax);
10564
if ((chan_sig != SIG_BRI) && (chan_sig != SIG_BRI_PTMP) && (chan_sig != SIG_PRI)
10565
&& (chan_sig != SIG_SS7) && (chan_sig != SIG_MFCR2))
10566
/* Hang it up to be sure it's good */
10567
dahdi_set_hook(tmp->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
10569
ioctl(tmp->subs[SUB_REAL].dfd,DAHDI_SETTONEZONE,&tmp->tonezone);
10571
/* the dchannel is down so put the channel in alarm */
10572
if (tmp->pri && !pri_is_up(tmp->pri))
10575
if ((res = get_alarms(tmp)) != DAHDI_ALARM_NONE) {
10577
handle_alarms(tmp, res);
10581
tmp->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
10582
tmp->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
10583
tmp->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
10584
tmp->sendcalleridafter = conf->chan.sendcalleridafter;
10586
tmp->locallyblocked = tmp->remotelyblocked = 0;
10587
if ((chan_sig == SIG_PRI) || (chan_sig == SIG_BRI) || (chan_sig == SIG_BRI_PTMP) || (chan_sig == SIG_SS7))
10588
tmp->inservice = 0;
10589
else /* We default to in service on protocols that don't have a reset */
10590
tmp->inservice = 1;
10593
if (tmp && !here) {
10594
/* nothing on the iflist */
10601
/* at least one member on the iflist */
10602
struct dahdi_pvt *working = *wlist;
10604
/* check if we maybe have to put it on the begining */
10605
if (working->channel > tmp->channel) {
10606
tmp->next = *wlist;
10608
(*wlist)->prev = tmp;
10611
/* go through all the members and put the member in the right place */
10613
/* in the middle */
10614
if (working->next) {
10615
if (working->channel < tmp->channel && working->next->channel > tmp->channel) {
10616
tmp->next = working->next;
10617
tmp->prev = working;
10618
working->next->prev = tmp;
10619
working->next = tmp;
10624
if (working->channel < tmp->channel) {
10625
working->next = tmp;
10627
tmp->prev = working;
10632
working = working->next;
10640
static inline int available(struct dahdi_pvt *p, int channelmatch, ast_group_t groupmatch, int *busy, int *channelmatched, int *groupmatched)
10643
struct dahdi_params par;
10645
/* First, check group matching */
10647
if ((p->group & groupmatch) != groupmatch)
10651
/* Check to see if we have a channel match */
10652
if (channelmatch != -1) {
10653
if (p->channel != channelmatch)
10655
*channelmatched = 1;
10657
/* We're at least busy at this point */
10659
if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
10662
/* If do not disturb, definitely not */
10665
/* If guard time, definitely not */
10666
if (p->guardtime && (time(NULL) < p->guardtime))
10669
if (p->locallyblocked || p->remotelyblocked)
10672
/* If no owner definitely available */
10677
if (p->resetting || p->call)
10702
/* Trust hook state */
10703
if (p->sig && !(p->radio || (p->oprmode < 0)))
10705
/* Check hook state */
10706
if (p->subs[SUB_REAL].dfd > -1) {
10707
memset(&par, 0, sizeof(par));
10708
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
10710
/* Assume not off hook on CVRS */
10712
par.rxisoffhook = 0;
10716
ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
10718
else if ((p->sig != SIG_FXSKS) && (p->sig != SIG_FXSGS) && (p->sig != SIG_FXSLS)) {
10719
if (par.rxisoffhook) {
10720
ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
10721
/* Not available when the other end is off hook */
10725
#ifdef DAHDI_CHECK_HOOKSTATE
10726
} else { /* FXO channel case (SIG_FXS--) */
10727
/* Channel bank (using CAS), "onhook" does not necessarily means out of service, so return 1 */
10728
if (par.rxbits > -1)
10730
/* TDM FXO card, "onhook" means out of service (no battery on the line) */
10731
if (par.rxisoffhook)
10741
/* If it's not an FXO, forget about call wait */
10742
if ((p->sig != SIG_FXOKS) && (p->sig != SIG_FXOLS) && (p->sig != SIG_FXOGS))
10745
if (!p->callwaiting) {
10746
/* If they don't have call waiting enabled, then for sure they're unavailable at this point */
10750
if (p->subs[SUB_CALLWAIT].dfd > -1) {
10751
/* If there is already a call waiting call, then we can't take a second one */
10755
if ((p->owner->_state != AST_STATE_UP) &&
10756
((p->owner->_state != AST_STATE_RINGING) || p->outgoing)) {
10757
/* If the current call is not up, then don't allow the call */
10760
if ((p->subs[SUB_THREEWAY].owner) && (!p->subs[SUB_THREEWAY].inthreeway)) {
10761
/* Can't take a call wait when the three way calling hasn't been merged yet. */
10768
/* This function can *ONLY* be used for copying pseudo (CHAN_PSEUDO) private
10769
structures; it makes no attempt to safely copy regular channel private
10770
structures that might contain reference-counted object pointers and other
10773
static struct dahdi_pvt *duplicate_pseudo(struct dahdi_pvt *src)
10775
struct dahdi_pvt *p;
10776
struct dahdi_bufferinfo bi;
10779
if ((p = ast_malloc(sizeof(*p)))) {
10780
memcpy(p, src, sizeof(struct dahdi_pvt));
10781
ast_mutex_init(&p->lock);
10782
p->subs[SUB_REAL].dfd = dahdi_open("/dev/dahdi/pseudo");
10783
if (p->subs[SUB_REAL].dfd < 0) {
10784
ast_log(LOG_ERROR, "Unable to dup channel: %s\n", strerror(errno));
10785
destroy_dahdi_pvt(&p);
10788
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_BUFINFO, &bi);
10790
bi.txbufpolicy = src->buf_policy;
10791
bi.rxbufpolicy = src->buf_policy;
10792
bi.numbufs = src->buf_no;
10793
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi);
10795
ast_log(LOG_WARNING, "Unable to set buffer policy on dup channel: %s\n", strerror(errno));
10798
ast_log(LOG_WARNING, "Unable to check buffer policy on dup channel: %s\n", strerror(errno));
10805
iflist->next->prev = p;
10809
#if defined(HAVE_PRI)
10810
static int pri_find_empty_chan(struct dahdi_pri *pri, int backwards)
10818
if (backwards && (x < 0))
10820
if (!backwards && (x >= pri->numchans))
10822
if (pri->pvts[x] && !pri->pvts[x]->inalarm && !pri->pvts[x]->owner) {
10823
ast_debug(1, "Found empty available channel %d/%d\n",
10824
pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
10834
#endif /* defined(HAVE_PRI) */
10836
static struct ast_channel *dahdi_request(const char *type, int format, void *data, int *cause)
10838
ast_group_t groupmatch = 0;
10839
int channelmatch = -1;
10840
int roundrobin = 0;
10843
struct dahdi_pvt *p;
10844
struct ast_channel *tmp = NULL;
10855
struct dahdi_pri *pri=NULL;
10857
struct dahdi_pvt *exitpvt, *start, *end;
10859
int channelmatched = 0;
10860
int groupmatched = 0;
10864
* Dial(DAHDI/pseudo[/extension])
10865
* Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension])
10866
* Dial(DAHDI/<trunk_group#>:<crv#>[c|r<cadance#>|d][/extension])
10867
* Dial(DAHDI/(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension])
10869
* g - channel group allocation search forward
10870
* G - channel group allocation search backward
10871
* r - channel group allocation round robin search forward
10872
* R - channel group allocation round robin search backward
10874
* c - Wait for DTMF digit to confirm answer
10875
* r<cadance#> - Set distintive ring cadance number
10876
* d - Force bearer capability for ISDN/SS7 call to digital.
10879
/* Assume we're locking the iflock */
10884
dest = ast_strdupa((char *)data);
10886
ast_log(LOG_WARNING, "Channel requested with no data\n");
10889
if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') {
10890
/* Retrieve the group number */
10893
stringp = dest + 1;
10894
s = strsep(&stringp, "/");
10895
if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10896
ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
10899
groupmatch = ((ast_group_t) 1 << x);
10900
if (toupper(dest[0]) == 'G') {
10901
if (dest[0] == 'G') {
10907
if (dest[0] == 'R') {
10909
p = round_robin[x]?round_robin[x]->prev:ifend;
10913
p = round_robin[x]?round_robin[x]->next:iflist;
10923
s = strsep(&stringp, "/");
10925
if (!strcasecmp(s, "pseudo")) {
10926
/* Special case for pseudo */
10931
else if ((res = sscanf(s, "%30d:%30d%1c%30d", &trunkgroup, &crv, &opt, &y)) > 1) {
10932
if ((trunkgroup < 1) || (crv < 1)) {
10933
ast_log(LOG_WARNING, "Unable to determine trunk group and CRV for data %s\n", (char *)data);
10937
for (x = 0; x < NUM_SPANS; x++) {
10938
if (pris[x].trunkgroup == trunkgroup) {
10947
ast_log(LOG_WARNING, "Unable to find trunk group %d\n", trunkgroup);
10950
channelmatch = crv;
10954
else if ((res = sscanf(s, "%30d%1c%30d", &x, &opt, &y)) < 1) {
10955
ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
10961
/* Search for an unowned channel */
10962
ast_mutex_lock(lock);
10964
while (p && !tmp) {
10966
round_robin[x] = p;
10968
ast_verbose("name = %s, %d, %d, %llu\n",p->owner ? p->owner->name : "<none>", p->channel, channelmatch, groupmatch);
10971
if (p && available(p, channelmatch, groupmatch, &busy, &channelmatched, &groupmatched)) {
10972
ast_debug(1, "Using channel %d\n", p->channel);
10976
callwait = (p->owner != NULL);
10978
if (pri && (p->subs[SUB_REAL].dfd < 0)) {
10979
if (p->sig != SIG_FXSKS) {
10980
/* Gotta find an actual channel to use for this
10981
CRV if this isn't a callwait */
10982
bearer = pri_find_empty_chan(pri, 0);
10984
ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
10988
pri_assign_bearer(p, pri, pri->pvts[bearer]);
10990
if (alloc_sub(p, 0)) {
10991
ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
10995
ast_debug(1, "Allocated placeholder pseudo channel\n");
11003
ast_mutex_lock(&p->lock);
11004
if (p->mfcr2call) {
11005
ast_mutex_unlock(&p->lock);
11006
ast_log(LOG_DEBUG, "Yay!, someone just beat us in the race for channel %d.\n", p->channel);
11010
ast_mutex_unlock(&p->lock);
11013
if (p->channel == CHAN_PSEUDO) {
11014
p = duplicate_pseudo(p);
11020
if (alloc_sub(p, SUB_CALLWAIT)) {
11026
tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
11032
/* Log owner to bearer channel, too */
11033
p->bearer->owner = tmp;
11036
/* Make special notes */
11039
/* Confirm answer */
11040
p->confirmanswer = 1;
11041
} else if (opt == 'r') {
11042
/* Distinctive ring */
11044
ast_log(LOG_WARNING, "Distinctive ring missing identifier in '%s'\n", (char *)data);
11046
p->distinctivering = y;
11047
} else if (opt == 'd') {
11048
/* If this is an ISDN call, make it digital */
11051
tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
11053
ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
11056
/* Note if the call is a call waiting call */
11057
if (tmp && callwait)
11058
tmp->cdrflags |= AST_CDR_CALLWAIT;
11071
/* stop when you roll to the one that we started from */
11075
ast_mutex_unlock(lock);
11078
*cause = AST_CAUSE_BUSY;
11080
if (channelmatched) {
11082
*cause = AST_CAUSE_BUSY;
11083
} else if (groupmatched) {
11084
*cause = AST_CAUSE_CONGESTION;
11091
#if defined(HAVE_PRI) || defined(HAVE_SS7)
11092
static int dahdi_setlaw(int dfd, int law)
11094
return ioctl(dfd, DAHDI_SETLAW, &law);
11096
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
11098
#if defined(HAVE_SS7)
11099
static int ss7_find_cic(struct dahdi_ss7 *linkset, int cic, unsigned int dpc)
11103
for (i = 0; i < linkset->numchans; i++) {
11104
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && linkset->pvts[i]->cic == cic)) {
11111
#endif /* defined(HAVE_SS7) */
11113
#if defined(HAVE_SS7)
11114
static void ss7_handle_cqm(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
11116
unsigned char status[32];
11117
struct dahdi_pvt *p = NULL;
11120
for (i = 0; i < linkset->numchans; i++) {
11121
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
11122
p = linkset->pvts[i];
11123
offset = p->cic - startcic;
11124
status[offset] = 0;
11125
if (p->locallyblocked)
11126
status[offset] |= (1 << 0) | (1 << 4);
11127
if (p->remotelyblocked)
11128
status[offset] |= (1 << 1) | (1 << 5);
11131
status[offset] |= (1 << 3);
11133
status[offset] |= (1 << 2);
11135
status[offset] |= 0x3 << 2;
11140
isup_cqr(linkset->ss7, startcic, endcic, dpc, status);
11142
ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n");
11145
#endif /* defined(HAVE_SS7) */
11147
#if defined(HAVE_SS7)
11148
static inline void ss7_hangup_cics(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
11152
for (i = 0; i < linkset->numchans; i++) {
11153
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
11154
ast_mutex_lock(&linkset->pvts[i]->lock);
11155
if (linkset->pvts[i]->owner)
11156
linkset->pvts[i]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11157
ast_mutex_unlock(&linkset->pvts[i]->lock);
11161
#endif /* defined(HAVE_SS7) */
11163
#if defined(HAVE_SS7)
11164
static inline void ss7_block_cics(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block)
11168
for (i = 0; i < linkset->numchans; i++) {
11169
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) {
11172
linkset->pvts[i]->remotelyblocked = block;
11174
linkset->pvts[i]->remotelyblocked = block;
11178
#endif /* defined(HAVE_SS7) */
11180
#if defined(HAVE_SS7)
11181
static void ss7_inservice(struct dahdi_ss7 *linkset, int startcic, int endcic, unsigned int dpc)
11185
for (i = 0; i < linkset->numchans; i++) {
11186
if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))))
11187
linkset->pvts[i]->inservice = 1;
11190
#endif /* defined(HAVE_SS7) */
11192
#if defined(HAVE_SS7)
11193
static void ss7_reset_linkset(struct dahdi_ss7 *linkset)
11195
int i, startcic = -1, endcic, dpc;
11197
if (linkset->numchans <= 0)
11200
startcic = linkset->pvts[0]->cic;
11201
/* DB: CIC's DPC fix */
11202
dpc = linkset->pvts[0]->dpc;
11204
for (i = 0; i < linkset->numchans; i++) {
11205
if (linkset->pvts[i+1] && linkset->pvts[i+1]->dpc == dpc && ((linkset->pvts[i+1]->cic - linkset->pvts[i]->cic) == 1) && (linkset->pvts[i]->cic - startcic < 31)) {
11208
endcic = linkset->pvts[i]->cic;
11209
ast_verbose("Resetting CICs %d to %d\n", startcic, endcic);
11210
isup_grs(linkset->ss7, startcic, endcic, dpc);
11212
/* DB: CIC's DPC fix */
11213
if (linkset->pvts[i+1]) {
11214
startcic = linkset->pvts[i+1]->cic;
11215
dpc = linkset->pvts[i+1]->dpc;
11220
#endif /* defined(HAVE_SS7) */
11222
#if defined(HAVE_SS7)
11223
static void dahdi_loopback(struct dahdi_pvt *p, int enable)
11225
if (p->loopedback != enable) {
11226
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
11227
ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel, strerror(errno));
11230
p->loopedback = enable;
11233
#endif /* defined(HAVE_SS7) */
11235
#if defined(HAVE_SS7)
11236
/* XXX: This function is assumed to be called with the private channel lock and linkset lock held */
11237
static void ss7_start_call(struct dahdi_pvt *p, struct dahdi_ss7 *linkset)
11239
struct ss7 *ss7 = linkset->ss7;
11242
struct ast_channel *c;
11245
if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
11246
ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", p->channel, law, strerror(errno));
11248
if (linkset->type == SS7_ITU)
11249
law = DAHDI_LAW_ALAW;
11251
law = DAHDI_LAW_MULAW;
11253
res = dahdi_setlaw(p->subs[SUB_REAL].dfd, law);
11255
ast_log(LOG_WARNING, "Unable to set law on channel %d\n", p->channel);
11257
if (!(linkset->flags & LINKSET_FLAG_EXPLICITACM)) {
11259
isup_acm(ss7, p->ss7call);
11262
ast_mutex_unlock(&linkset->lock);
11263
c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, law, 0);
11266
ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic);
11267
/* Holding this lock is assumed entering the function */
11268
ast_mutex_lock(&linkset->lock);
11271
ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic);
11273
dahdi_enable_ec(p);
11275
/* We only reference these variables in the context of the ss7_linkset function
11276
* when receiving either and IAM or a COT message. Since they are only accessed
11277
* from this context, we should be safe to unlock around them */
11279
ast_mutex_unlock(&p->lock);
11281
if (!ast_strlen_zero(p->charge_number)) {
11282
pbx_builtin_setvar_helper(c, "SS7_CHARGE_NUMBER", p->charge_number);
11283
/* Clear this after we set it */
11284
p->charge_number[0] = 0;
11286
if (!ast_strlen_zero(p->gen_add_number)) {
11287
pbx_builtin_setvar_helper(c, "SS7_GENERIC_ADDRESS", p->gen_add_number);
11288
/* Clear this after we set it */
11289
p->gen_add_number[0] = 0;
11291
if (!ast_strlen_zero(p->jip_number)) {
11292
pbx_builtin_setvar_helper(c, "SS7_JIP", p->jip_number);
11293
/* Clear this after we set it */
11294
p->jip_number[0] = 0;
11296
if (!ast_strlen_zero(p->gen_dig_number)) {
11297
pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGITS", p->gen_dig_number);
11298
/* Clear this after we set it */
11299
p->gen_dig_number[0] = 0;
11301
if (!ast_strlen_zero(p->orig_called_num)) {
11302
pbx_builtin_setvar_helper(c, "SS7_ORIG_CALLED_NUM", p->orig_called_num);
11303
/* Clear this after we set it */
11304
p->orig_called_num[0] = 0;
11307
snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_type);
11308
pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGTYPE", tmp);
11309
/* Clear this after we set it */
11310
p->gen_dig_type = 0;
11312
snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_scheme);
11313
pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGSCHEME", tmp);
11314
/* Clear this after we set it */
11315
p->gen_dig_scheme = 0;
11317
if (!ast_strlen_zero(p->lspi_ident)) {
11318
pbx_builtin_setvar_helper(c, "SS7_LSPI_IDENT", p->lspi_ident);
11319
/* Clear this after we set it */
11320
p->lspi_ident[0] = 0;
11323
snprintf(tmp, sizeof(tmp), "%d", p->call_ref_ident);
11324
pbx_builtin_setvar_helper(c, "SS7_CALLREF_IDENT", tmp);
11325
/* Clear this after we set it */
11326
p->call_ref_ident = 0;
11328
snprintf(tmp, sizeof(tmp), "%d", p->call_ref_pc);
11329
pbx_builtin_setvar_helper(c, "SS7_CALLREF_PC", tmp);
11330
/* Clear this after we set it */
11331
p->call_ref_pc = 0;
11333
snprintf(tmp, sizeof(tmp), "%d", p->calling_party_cat);
11334
pbx_builtin_setvar_helper(c, "SS7_CALLING_PARTY_CATEGORY", tmp);
11335
/* Clear this after we set it */
11336
p->calling_party_cat = 0;
11338
if (!ast_strlen_zero(p->redirecting_num)) {
11339
pbx_builtin_setvar_helper(c, "SS7_REDIRECTING_NUMBER", p->redirecting_num);
11340
/* Clear this after we set it */
11341
p->redirecting_num[0] = 0;
11343
if (!ast_strlen_zero(p->generic_name)) {
11344
pbx_builtin_setvar_helper(c, "SS7_GENERIC_NAME", p->generic_name);
11345
/* Clear this after we set it */
11346
p->generic_name[0] = 0;
11349
ast_mutex_lock(&p->lock);
11350
ast_mutex_lock(&linkset->lock);
11352
#endif /* defined(HAVE_SS7) */
11354
#if defined(HAVE_SS7)
11355
static void ss7_apply_plan_to_number(char *buf, size_t size, const struct dahdi_ss7 *ss7, const char *number, const unsigned nai)
11357
if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */
11364
case SS7_NAI_INTERNATIONAL:
11365
snprintf(buf, size, "%s%s", ss7->internationalprefix, number);
11367
case SS7_NAI_NATIONAL:
11368
snprintf(buf, size, "%s%s", ss7->nationalprefix, number);
11370
case SS7_NAI_SUBSCRIBER:
11371
snprintf(buf, size, "%s%s", ss7->subscriberprefix, number);
11373
case SS7_NAI_UNKNOWN:
11374
snprintf(buf, size, "%s%s", ss7->unknownprefix, number);
11377
snprintf(buf, size, "%s", number);
11381
#endif /* defined(HAVE_SS7) */
11383
#if defined(HAVE_SS7)
11384
static int ss7_pres_scr2cid_pres(char presentation_ind, char screening_ind)
11386
return ((presentation_ind & 0x3) << 5) | (screening_ind & 0x3);
11388
#endif /* defined(HAVE_SS7) */
11390
#if defined(HAVE_SS7)
11391
static void *ss7_linkset(void *data)
11394
struct timeval *next = NULL, tv;
11395
struct dahdi_ss7 *linkset = (struct dahdi_ss7 *) data;
11396
struct ss7 *ss7 = linkset->ss7;
11397
ss7_event *e = NULL;
11398
struct dahdi_pvt *p;
11400
struct pollfd pollers[NUM_DCHANS];
11408
ast_mutex_lock(&linkset->lock);
11409
if ((next = ss7_schedule_next(ss7))) {
11411
tv.tv_sec = next->tv_sec - tv.tv_sec;
11412
tv.tv_usec = next->tv_usec - tv.tv_usec;
11413
if (tv.tv_usec < 0) {
11414
tv.tv_usec += 1000000;
11417
if (tv.tv_sec < 0) {
11421
nextms = tv.tv_sec * 1000;
11422
nextms += tv.tv_usec / 1000;
11424
ast_mutex_unlock(&linkset->lock);
11426
for (i = 0; i < linkset->numsigchans; i++) {
11427
pollers[i].fd = linkset->fds[i];
11428
pollers[i].events = ss7_pollflags(ss7, linkset->fds[i]);
11429
pollers[i].revents = 0;
11432
res = poll(pollers, linkset->numsigchans, nextms);
11433
if ((res < 0) && (errno != EINTR)) {
11434
ast_log(LOG_ERROR, "poll(%s)\n", strerror(errno));
11436
ast_mutex_lock(&linkset->lock);
11437
ss7_schedule_run(ss7);
11438
ast_mutex_unlock(&linkset->lock);
11442
ast_mutex_lock(&linkset->lock);
11443
for (i = 0; i < linkset->numsigchans; i++) {
11444
if (pollers[i].revents & POLLPRI) {
11446
if (ioctl(pollers[i].fd, DAHDI_GETEVENT, &x)) {
11447
ast_log(LOG_ERROR, "Error in exception retrieval!\n");
11450
case DAHDI_EVENT_OVERRUN:
11451
ast_debug(1, "Overrun detected!\n");
11453
case DAHDI_EVENT_BADFCS:
11454
ast_debug(1, "Bad FCS\n");
11456
case DAHDI_EVENT_ABORT:
11457
ast_debug(1, "HDLC Abort\n");
11459
case DAHDI_EVENT_ALARM:
11460
ast_log(LOG_ERROR, "Alarm on link!\n");
11461
linkset->linkstate[i] |= (LINKSTATE_DOWN | LINKSTATE_INALARM);
11462
linkset->linkstate[i] &= ~LINKSTATE_UP;
11463
ss7_link_alarm(ss7, pollers[i].fd);
11465
case DAHDI_EVENT_NOALARM:
11466
ast_log(LOG_ERROR, "Alarm cleared on link\n");
11467
linkset->linkstate[i] &= ~(LINKSTATE_INALARM | LINKSTATE_DOWN);
11468
linkset->linkstate[i] |= LINKSTATE_STARTING;
11469
ss7_link_noalarm(ss7, pollers[i].fd);
11472
ast_log(LOG_ERROR, "Got exception %d!\n", x);
11477
if (pollers[i].revents & POLLIN) {
11478
res = ss7_read(ss7, pollers[i].fd);
11481
if (pollers[i].revents & POLLOUT) {
11482
res = ss7_write(ss7, pollers[i].fd);
11484
ast_debug(1, "Error in write %s\n", strerror(errno));
11489
while ((e = ss7_check_event(ss7))) {
11492
if (linkset->state != LINKSET_STATE_UP) {
11493
ast_verbose("--- SS7 Up ---\n");
11494
ss7_reset_linkset(linkset);
11496
linkset->state = LINKSET_STATE_UP;
11498
case SS7_EVENT_DOWN:
11499
ast_verbose("--- SS7 Down ---\n");
11500
linkset->state = LINKSET_STATE_DOWN;
11501
for (i = 0; i < linkset->numchans; i++) {
11502
struct dahdi_pvt *p = linkset->pvts[i];
11508
ast_verbose("MTP2 link up (SLC %d)\n", e->gen.data);
11510
case MTP2_LINK_DOWN:
11511
ast_log(LOG_WARNING, "MTP2 link down (SLC %d)\n", e->gen.data);
11513
case ISUP_EVENT_CPG:
11514
chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc);
11516
ast_log(LOG_WARNING, "CPG on unconfigured CIC %d\n", e->cpg.cic);
11519
p = linkset->pvts[chanpos];
11520
ast_mutex_lock(&p->lock);
11521
switch (e->cpg.event) {
11522
case CPG_EVENT_ALERTING:
11524
p->subs[SUB_REAL].needringing = 1;
11526
case CPG_EVENT_PROGRESS:
11527
case CPG_EVENT_INBANDINFO:
11529
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
11530
ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic);
11531
dahdi_queue_frame(p, &f, linkset);
11534
if (p->dsp && p->dsp_features) {
11535
ast_dsp_set_features(p->dsp, p->dsp_features);
11536
p->dsp_features = 0;
11541
ast_debug(1, "Do not handle CPG with event type 0x%x\n", e->cpg.event);
11544
ast_mutex_unlock(&p->lock);
11546
case ISUP_EVENT_RSC:
11547
ast_verbose("Resetting CIC %d\n", e->rsc.cic);
11548
chanpos = ss7_find_cic(linkset, e->rsc.cic, e->rsc.opc);
11550
ast_log(LOG_WARNING, "RSC on unconfigured CIC %d\n", e->rsc.cic);
11553
p = linkset->pvts[chanpos];
11554
ast_mutex_lock(&p->lock);
11556
p->remotelyblocked = 0;
11558
isup_set_call_dpc(e->rsc.call, dpc);
11562
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11563
ast_mutex_unlock(&p->lock);
11564
isup_rlc(ss7, e->rsc.call);
11566
case ISUP_EVENT_GRS:
11567
ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic);
11568
chanpos = ss7_find_cic(linkset, e->grs.startcic, e->grs.opc);
11570
ast_log(LOG_WARNING, "GRS on unconfigured CIC %d\n", e->grs.startcic);
11573
p = linkset->pvts[chanpos];
11574
isup_gra(ss7, e->grs.startcic, e->grs.endcic, e->grs.opc);
11575
ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0);
11576
ss7_hangup_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc);
11578
case ISUP_EVENT_CQM:
11579
ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic);
11580
ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic, e->cqm.opc);
11582
case ISUP_EVENT_GRA:
11583
ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
11584
ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc);
11585
ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status, 1);
11587
case ISUP_EVENT_IAM:
11588
ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num);
11589
chanpos = ss7_find_cic(linkset, e->iam.cic, e->iam.opc);
11591
ast_log(LOG_WARNING, "IAM on unconfigured CIC %d\n", e->iam.cic);
11592
isup_rel(ss7, e->iam.call, -1);
11595
p = linkset->pvts[chanpos];
11596
ast_mutex_lock(&p->lock);
11598
if (p->ss7call == e->iam.call) {
11599
ast_mutex_unlock(&p->lock);
11600
ast_log(LOG_WARNING, "Duplicate IAM requested on CIC %d\n", e->iam.cic);
11603
ast_mutex_unlock(&p->lock);
11604
ast_log(LOG_WARNING, "Ring requested on CIC %d already in use!\n", e->iam.cic);
11610
p->ss7call = e->iam.call;
11611
isup_set_call_dpc(p->ss7call, dpc);
11613
if ((p->use_callerid) && (!ast_strlen_zero(e->iam.calling_party_num))) {
11614
ss7_apply_plan_to_number(p->cid_num, sizeof(p->cid_num), linkset, e->iam.calling_party_num, e->iam.calling_nai);
11615
p->callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind);
11619
if (p->immediate) {
11621
p->exten[1] = '\0';
11622
} else if (!ast_strlen_zero(e->iam.called_party_num)) {
11624
ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, e->iam.called_party_num, e->iam.called_nai);
11625
st = strchr(p->exten, '#');
11629
p->exten[0] = '\0';
11631
p->cid_ani[0] = '\0';
11632
if ((p->use_callerid) && (!ast_strlen_zero(e->iam.generic_name)))
11633
ast_copy_string(p->cid_name, e->iam.generic_name, sizeof(p->cid_name));
11635
p->cid_name[0] = '\0';
11637
p->cid_ani2 = e->iam.oli_ani2;
11639
ast_copy_string(p->charge_number, e->iam.charge_number, sizeof(p->charge_number));
11640
ast_copy_string(p->gen_add_number, e->iam.gen_add_number, sizeof(p->gen_add_number));
11641
p->gen_add_type = e->iam.gen_add_type;
11642
p->gen_add_nai = e->iam.gen_add_nai;
11643
p->gen_add_pres_ind = e->iam.gen_add_pres_ind;
11644
p->gen_add_num_plan = e->iam.gen_add_num_plan;
11645
ast_copy_string(p->gen_dig_number, e->iam.gen_dig_number, sizeof(p->gen_dig_number));
11646
p->gen_dig_type = e->iam.gen_dig_type;
11647
p->gen_dig_scheme = e->iam.gen_dig_scheme;
11648
ast_copy_string(p->jip_number, e->iam.jip_number, sizeof(p->jip_number));
11649
ast_copy_string(p->orig_called_num, e->iam.orig_called_num, sizeof(p->orig_called_num));
11650
ast_copy_string(p->redirecting_num, e->iam.redirecting_num, sizeof(p->redirecting_num));
11651
ast_copy_string(p->generic_name, e->iam.generic_name, sizeof(p->generic_name));
11652
p->calling_party_cat = e->iam.calling_party_cat;
11655
if (!ast_strlen_zero(e->iam.called_party_num))
11656
ss7_apply_plan_to_number(p->dnid, sizeof(p->dnid), linkset, e->iam.called_party_num, e->iam.called_nai);
11658
if (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
11660
if (e->iam.cot_check_required) {
11661
dahdi_loopback(p, 1);
11663
ss7_start_call(p, linkset);
11665
ast_debug(1, "Call on CIC for unconfigured extension %s\n", p->exten);
11666
p->alreadyhungup = 1;
11667
isup_rel(ss7, e->iam.call, AST_CAUSE_UNALLOCATED);
11669
ast_mutex_unlock(&p->lock);
11671
case ISUP_EVENT_COT:
11672
chanpos = ss7_find_cic(linkset, e->cot.cic, e->cot.opc);
11674
ast_log(LOG_WARNING, "COT on unconfigured CIC %d\n", e->cot.cic);
11675
isup_rel(ss7, e->cot.call, -1);
11678
p = linkset->pvts[chanpos];
11680
ast_mutex_lock(&p->lock);
11682
if (p->loopedback) {
11683
dahdi_loopback(p, 0);
11684
ss7_start_call(p, linkset);
11687
ast_mutex_unlock(&p->lock);
11690
case ISUP_EVENT_CCR:
11691
ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic);
11692
chanpos = ss7_find_cic(linkset, e->ccr.cic, e->ccr.opc);
11694
ast_log(LOG_WARNING, "CCR on unconfigured CIC %d\n", e->ccr.cic);
11698
p = linkset->pvts[chanpos];
11700
ast_mutex_lock(&p->lock);
11701
dahdi_loopback(p, 1);
11702
ast_mutex_unlock(&p->lock);
11704
isup_lpa(linkset->ss7, e->ccr.cic, p->dpc);
11706
case ISUP_EVENT_CVT:
11707
ast_debug(1, "Got CVT request on CIC %d\n", e->cvt.cic);
11708
chanpos = ss7_find_cic(linkset, e->cvt.cic, e->cvt.opc);
11710
ast_log(LOG_WARNING, "CVT on unconfigured CIC %d\n", e->cvt.cic);
11714
p = linkset->pvts[chanpos];
11716
ast_mutex_lock(&p->lock);
11717
dahdi_loopback(p, 1);
11718
ast_mutex_unlock(&p->lock);
11720
isup_cvr(linkset->ss7, e->cvt.cic, p->dpc);
11722
case ISUP_EVENT_REL:
11723
chanpos = ss7_find_cic(linkset, e->rel.cic, e->rel.opc);
11725
ast_log(LOG_WARNING, "REL on unconfigured CIC %d\n", e->rel.cic);
11728
p = linkset->pvts[chanpos];
11729
ast_mutex_lock(&p->lock);
11731
p->owner->hangupcause = e->rel.cause;
11732
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
11733
} else if (!p->restartpending)
11734
ast_log(LOG_WARNING, "REL on channel (CIC %d) without owner!\n", p->cic);
11736
/* End the loopback if we have one */
11737
dahdi_loopback(p, 0);
11739
isup_rlc(ss7, e->rel.call);
11742
ast_mutex_unlock(&p->lock);
11744
case ISUP_EVENT_ACM:
11745
chanpos = ss7_find_cic(linkset, e->acm.cic, e->acm.opc);
11747
ast_log(LOG_WARNING, "ACM on unconfigured CIC %d\n", e->acm.cic);
11748
isup_rel(ss7, e->acm.call, -1);
11751
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
11753
p = linkset->pvts[chanpos];
11755
ast_debug(1, "Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->cic);
11757
if (e->acm.call_ref_ident > 0) {
11758
p->rlt = 1; /* Setting it but not using it here*/
11761
ast_mutex_lock(&p->lock);
11762
dahdi_queue_frame(p, &f, linkset);
11765
/* Send alerting if subscriber is free */
11766
if (e->acm.called_party_status_ind == 1) {
11768
p->subs[SUB_REAL].needringing = 1;
11770
ast_mutex_unlock(&p->lock);
11773
case ISUP_EVENT_CGB:
11774
chanpos = ss7_find_cic(linkset, e->cgb.startcic, e->cgb.opc);
11776
ast_log(LOG_WARNING, "CGB on unconfigured CIC %d\n", e->cgb.startcic);
11779
p = linkset->pvts[chanpos];
11780
ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, 1);
11781
isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, e->cgb.type);
11783
case ISUP_EVENT_CGU:
11784
chanpos = ss7_find_cic(linkset, e->cgu.startcic, e->cgu.opc);
11786
ast_log(LOG_WARNING, "CGU on unconfigured CIC %d\n", e->cgu.startcic);
11789
p = linkset->pvts[chanpos];
11790
ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, 0);
11791
isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, e->cgu.type);
11793
case ISUP_EVENT_UCIC:
11794
chanpos = ss7_find_cic(linkset, e->ucic.cic, e->ucic.opc);
11796
ast_log(LOG_WARNING, "UCIC on unconfigured CIC %d\n", e->ucic.cic);
11799
p = linkset->pvts[chanpos];
11800
ast_debug(1, "Unequiped Circuit Id Code on CIC %d\n", e->ucic.cic);
11801
ast_mutex_lock(&p->lock);
11802
p->remotelyblocked = 1;
11804
ast_mutex_unlock(&p->lock); //doesn't require a SS7 acknowledgement
11806
case ISUP_EVENT_BLO:
11807
chanpos = ss7_find_cic(linkset, e->blo.cic, e->blo.opc);
11809
ast_log(LOG_WARNING, "BLO on unconfigured CIC %d\n", e->blo.cic);
11812
p = linkset->pvts[chanpos];
11813
ast_debug(1, "Blocking CIC %d\n", e->blo.cic);
11814
ast_mutex_lock(&p->lock);
11815
p->remotelyblocked = 1;
11816
ast_mutex_unlock(&p->lock);
11817
isup_bla(linkset->ss7, e->blo.cic, p->dpc);
11819
case ISUP_EVENT_BLA:
11820
chanpos = ss7_find_cic(linkset, e->bla.cic, e->bla.opc);
11822
ast_log(LOG_WARNING, "BLA on unconfigured CIC %d\n", e->bla.cic);
11825
ast_debug(1, "Blocking CIC %d\n", e->bla.cic);
11826
p = linkset->pvts[chanpos];
11827
ast_mutex_lock(&p->lock);
11828
p->locallyblocked = 1;
11829
ast_mutex_unlock(&p->lock);
11831
case ISUP_EVENT_UBL:
11832
chanpos = ss7_find_cic(linkset, e->ubl.cic, e->ubl.opc);
11834
ast_log(LOG_WARNING, "UBL on unconfigured CIC %d\n", e->ubl.cic);
11837
p = linkset->pvts[chanpos];
11838
ast_debug(1, "Unblocking CIC %d\n", e->ubl.cic);
11839
ast_mutex_lock(&p->lock);
11840
p->remotelyblocked = 0;
11841
ast_mutex_unlock(&p->lock);
11842
isup_uba(linkset->ss7, e->ubl.cic, p->dpc);
11844
case ISUP_EVENT_UBA:
11845
chanpos = ss7_find_cic(linkset, e->uba.cic, e->uba.opc);
11847
ast_log(LOG_WARNING, "UBA on unconfigured CIC %d\n", e->uba.cic);
11850
p = linkset->pvts[chanpos];
11851
ast_debug(1, "Unblocking CIC %d\n", e->uba.cic);
11852
ast_mutex_lock(&p->lock);
11853
p->locallyblocked = 0;
11854
ast_mutex_unlock(&p->lock);
11856
case ISUP_EVENT_CON:
11857
case ISUP_EVENT_ANM:
11858
if (e->e == ISUP_EVENT_CON)
11863
chanpos = ss7_find_cic(linkset, cic, (e->e == ISUP_EVENT_ANM) ? e->anm.opc : e->con.opc);
11865
ast_log(LOG_WARNING, "ANM/CON on unconfigured CIC %d\n", cic);
11866
isup_rel(ss7, (e->e == ISUP_EVENT_ANM) ? e->anm.call : e->con.call, -1);
11869
p = linkset->pvts[chanpos];
11870
ast_mutex_lock(&p->lock);
11871
p->subs[SUB_REAL].needanswer = 1;
11872
if (p->dsp && p->dsp_features) {
11873
ast_dsp_set_features(p->dsp, p->dsp_features);
11874
p->dsp_features = 0;
11876
dahdi_enable_ec(p);
11877
ast_mutex_unlock(&p->lock);
11880
case ISUP_EVENT_RLC:
11881
chanpos = ss7_find_cic(linkset, e->rlc.cic, e->rlc.opc);
11883
ast_log(LOG_WARNING, "RLC on unconfigured CIC %d\n", e->rlc.cic);
11886
p = linkset->pvts[chanpos];
11887
ast_mutex_lock(&p->lock);
11888
if (p->alreadyhungup)
11891
ast_log(LOG_NOTICE, "Received RLC out and we haven't sent REL. Ignoring.\n");
11892
ast_mutex_unlock(&p->lock);
11895
case ISUP_EVENT_FAA:
11896
chanpos = ss7_find_cic(linkset, e->faa.cic, e->faa.opc);
11898
ast_log(LOG_WARNING, "FAA on unconfigured CIC %d\n", e->faa.cic);
11901
p = linkset->pvts[chanpos];
11902
ast_debug(1, "FAA received on CIC %d\n", e->faa.cic);
11903
ast_mutex_lock(&p->lock);
11904
if (p->alreadyhungup){
11906
ast_log(LOG_NOTICE, "Received FAA and we haven't sent FAR. Ignoring.\n");
11908
ast_mutex_unlock(&p->lock);
11912
ast_debug(1, "Unknown event %s\n", ss7_event2str(e->e));
11916
ast_mutex_unlock(&linkset->lock);
11921
#endif /* defined(HAVE_SS7) */
11923
#if defined(HAVE_SS7)
11924
static void dahdi_ss7_message(struct ss7 *ss7, char *s)
11929
for (i = 0; i < NUM_SPANS; i++)
11930
if (linksets[i].ss7 == ss7)
11933
ast_verbose("[%d] %s", i+1, s);
11935
ast_verbose("%s", s);
11938
#endif /* defined(HAVE_SS7) */
11940
#if defined(HAVE_SS7)
11941
static void dahdi_ss7_error(struct ss7 *ss7, char *s)
11946
for (i = 0; i < NUM_SPANS; i++)
11947
if (linksets[i].ss7 == ss7)
11951
ast_log(LOG_ERROR, "%s", s);
11954
#endif /* defined(HAVE_SS7) */
11956
#if defined(HAVE_OPENR2)
11957
static void *mfcr2_monitor(void *data)
11959
struct dahdi_mfcr2 *mfcr2 = data;
11960
/* we should be using pthread_key_create
11961
and allocate pollers dynamically.
11962
I think do_monitor() could be leaking, since it
11963
could be cancelled at any time and is not
11964
using thread keys, why?, */
11965
struct pollfd pollers[sizeof(mfcr2->pvts)];
11973
/* now that we're ready to get calls, unblock our side and
11974
get current line state */
11975
for (i = 0; i < mfcr2->numchans; i++) {
11976
openr2_chan_set_idle(mfcr2->pvts[i]->r2chan);
11977
openr2_chan_handle_cas(mfcr2->pvts[i]->r2chan);
11980
/* we trust here that the mfcr2 channel list will not ever change once
11981
the module is loaded */
11983
for (i = 0; i < mfcr2->numchans; i++) {
11984
pollers[i].revents = 0;
11985
pollers[i].events = 0;
11986
if (mfcr2->pvts[i]->owner) {
11989
if (!mfcr2->pvts[i]->r2chan) {
11990
ast_log(LOG_DEBUG, "Wow, no r2chan on channel %d\n", mfcr2->pvts[i]->channel);
11994
openr2_chan_enable_read(mfcr2->pvts[i]->r2chan);
11995
pollers[i].events = POLLIN | POLLPRI;
11996
pollers[i].fd = mfcr2->pvts[i]->subs[SUB_REAL].dfd;
12002
if (pollsize == 0) {
12004
ast_log(LOG_DEBUG, "Monitor thread going idle since everybody has an owner\n");
12007
poll(NULL, 0, maxsleep);
12011
/* probably poll() is a valid cancel point, lets just be on the safe side
12012
by calling pthread_testcancel */
12013
pthread_testcancel();
12014
res = poll(pollers, mfcr2->numchans, maxsleep);
12015
pthread_testcancel();
12016
if ((res < 0) && (errno != EINTR)) {
12017
ast_log(LOG_ERROR, "going out, poll failed: %s\n", strerror(errno));
12020
/* do we want to allow to cancel while processing events? */
12021
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
12022
for (i = 0; i < mfcr2->numchans; i++) {
12023
if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
12024
openr2_chan_process_event(mfcr2->pvts[i]->r2chan);
12027
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
12029
ast_log(LOG_NOTICE, "Quitting MFC/R2 monitor thread\n");
12032
#endif /* HAVE_OPENR2 */
12034
#if defined(HAVE_PRI)
12035
static struct dahdi_pvt *pri_find_crv(struct dahdi_pri *pri, int crv)
12037
struct dahdi_pvt *p;
12040
if (p->channel == crv)
12046
#endif /* defined(HAVE_PRI) */
12048
#if defined(HAVE_PRI)
12049
static int pri_find_principle(struct dahdi_pri *pri, int channel)
12052
int span = PRI_SPAN(channel);
12054
struct dahdi_params param;
12055
int principle = -1;
12056
int explicit = PRI_EXPLICIT(channel);
12057
channel = PRI_CHANNEL(channel);
12060
spanfd = pri_active_dchan_fd(pri);
12061
memset(¶m, 0, sizeof(param));
12062
if (ioctl(spanfd, DAHDI_GET_PARAMS, ¶m))
12064
span = pris[param.spanno - 1].prilogicalspan;
12067
for (x = 0; x < pri->numchans; x++) {
12068
if (pri->pvts[x] && (pri->pvts[x]->prioffset == channel) && (pri->pvts[x]->logicalspan == span)) {
12076
#endif /* defined(HAVE_PRI) */
12078
#if defined(HAVE_PRI)
12079
static int pri_fixup_principle(struct dahdi_pri *pri, int principle, q931_call *c)
12082
struct dahdi_pvt *crv;
12088
if ((principle > -1) &&
12089
(principle < pri->numchans) &&
12090
(pri->pvts[principle]) &&
12091
(pri->pvts[principle]->call == c))
12093
/* First, check for other bearers */
12094
for (x = 0; x < pri->numchans; x++) {
12097
if (pri->pvts[x]->call == c) {
12098
/* Found our call */
12099
if (principle != x) {
12100
struct dahdi_pvt *new = pri->pvts[principle], *old = pri->pvts[x];
12102
ast_verb(3, "Moving call from channel %d to channel %d\n",
12103
old->channel, new->channel);
12105
ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
12106
old->channel, new->channel, new->channel);
12109
/* Fix it all up now */
12110
new->owner = old->owner;
12113
ast_string_field_build(new->owner, name,
12114
"DAHDI/%d:%d-%d", pri->trunkgroup,
12116
new->owner->tech_pvt = new;
12117
ast_channel_set_fd(new->owner, 0, new->subs[SUB_REAL].dfd);
12118
new->subs[SUB_REAL].owner = old->subs[SUB_REAL].owner;
12119
old->subs[SUB_REAL].owner = NULL;
12121
ast_log(LOG_WARNING, "Whoa, there's no owner, and we're having to fix up channel %d to channel %d\n", old->channel, new->channel);
12122
new->call = old->call;
12125
/* Copy any DSP that may be present */
12126
new->dsp = old->dsp;
12127
new->dsp_features = old->dsp_features;
12129
old->dsp_features = 0;
12134
/* Now check for a CRV with no bearer */
12137
if (crv->call == c) {
12138
/* This is our match... Perform some basic checks */
12140
ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
12141
else if (pri->pvts[principle]->owner)
12142
ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
12144
/* Looks good. Drop the pseudo channel now, clear up the assignment, and
12145
wakeup the potential sleeper */
12146
dahdi_close_sub(crv, SUB_REAL);
12147
pri->pvts[principle]->call = crv->call;
12148
pri_assign_bearer(crv, pri, pri->pvts[principle]);
12149
ast_debug(1, "Assigning bearer %d/%d to CRV %d:%d\n",
12150
pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
12151
pri->trunkgroup, crv->channel);
12152
wakeup_sub(crv, SUB_REAL, pri);
12158
ast_log(LOG_WARNING, "Call specified, but not found?\n");
12161
#endif /* defined(HAVE_PRI) */
12163
#if defined(HAVE_PRI)
12164
static void *do_idle_thread(void *vchan)
12166
struct ast_channel *chan = vchan;
12167
struct dahdi_pvt *pvt = chan->tech_pvt;
12168
struct ast_frame *f;
12170
/* Wait up to 30 seconds for an answer */
12171
int newms, ms = 30000;
12172
ast_verb(3, "Initiating idle call on channel %s\n", chan->name);
12173
snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
12174
if (ast_call(chan, ex, 0)) {
12175
ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", chan->name, ex);
12179
while ((newms = ast_waitfor(chan, ms)) > 0) {
12180
f = ast_read(chan);
12185
if (f->frametype == AST_FRAME_CONTROL) {
12186
switch (f->subclass) {
12187
case AST_CONTROL_ANSWER:
12188
/* Launch the PBX */
12189
ast_copy_string(chan->exten, pvt->pri->idleext, sizeof(chan->exten));
12190
ast_copy_string(chan->context, pvt->pri->idlecontext, sizeof(chan->context));
12191
chan->priority = 1;
12192
ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", chan->name, chan->exten, chan->context);
12194
/* It's already hungup, return immediately */
12196
case AST_CONTROL_BUSY:
12197
ast_verb(4, "Idle channel '%s' busy, waiting...\n", chan->name);
12199
case AST_CONTROL_CONGESTION:
12200
ast_verb(4, "Idle channel '%s' congested, waiting...\n", chan->name);
12207
/* Hangup the channel since nothing happend */
12211
#endif /* defined(HAVE_PRI) */
12213
#if defined(HAVE_PRI)
12214
#ifndef PRI_RESTART
12215
#error "Upgrade your libpri"
12217
static void dahdi_pri_message(struct pri *pri, char *s)
12220
int dchan = -1, span = -1;
12221
int dchancount = 0;
12224
for (x = 0; x < NUM_SPANS; x++) {
12225
for (y = 0; y < NUM_DCHANS; y++) {
12226
if (pris[x].dchans[y])
12229
if (pris[x].dchans[y] == pri)
12238
if (dchancount > 1 && (span > -1))
12239
ast_verbose("[Span %d D-Channel %d]%s", span, dchan, s);
12240
else if (span > -1)
12241
ast_verbose("%d %s", span+1, s);
12243
ast_verbose("%s", s);
12245
ast_verbose("%s", s);
12247
ast_mutex_lock(&pridebugfdlock);
12249
if (pridebugfd >= 0) {
12250
if (write(pridebugfd, s, strlen(s)) < 0) {
12251
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
12255
ast_mutex_unlock(&pridebugfdlock);
12257
#endif /* defined(HAVE_PRI) */
12259
#if defined(HAVE_PRI)
12260
static void dahdi_pri_error(struct pri *pri, char *s)
12263
int dchan = -1, span = -1;
12264
int dchancount = 0;
12267
for (x = 0; x < NUM_SPANS; x++) {
12268
for (y = 0; y < NUM_DCHANS; y++) {
12269
if (pris[x].dchans[y])
12272
if (pris[x].dchans[y] == pri)
12281
if ((dchancount > 1) && (span > -1))
12282
ast_log(LOG_ERROR, "[Span %d D-Channel %d] PRI: %s", span, dchan, s);
12283
else if (span > -1)
12284
ast_log(LOG_ERROR, "%d %s", span+1, s);
12286
ast_log(LOG_ERROR, "%s", s);
12288
ast_log(LOG_ERROR, "%s", s);
12290
ast_mutex_lock(&pridebugfdlock);
12292
if (pridebugfd >= 0) {
12293
if (write(pridebugfd, s, strlen(s)) < 0) {
12294
ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
12298
ast_mutex_unlock(&pridebugfdlock);
12300
#endif /* defined(HAVE_PRI) */
12302
#if defined(HAVE_PRI)
12303
static int pri_check_restart(struct dahdi_pri *pri)
12307
} while ((pri->resetpos < pri->numchans) &&
12308
(!pri->pvts[pri->resetpos] ||
12309
pri->pvts[pri->resetpos]->call ||
12310
pri->pvts[pri->resetpos]->resetting));
12311
if (pri->resetpos < pri->numchans) {
12312
/* Mark the channel as resetting and restart it */
12313
pri->pvts[pri->resetpos]->resetting = 1;
12314
pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
12316
pri->resetting = 0;
12317
time(&pri->lastreset);
12321
#endif /* defined(HAVE_PRI) */
12323
#if defined(HAVE_PRI)
12324
static int pri_hangup_all(struct dahdi_pvt *p, struct dahdi_pri *pri)
12328
ast_mutex_unlock(&pri->lock);
12329
ast_mutex_lock(&p->lock);
12332
for (x = 0; x < 3; x++) {
12333
while (p->subs[x].owner && ast_channel_trylock(p->subs[x].owner)) {
12335
DEADLOCK_AVOIDANCE(&p->lock);
12337
if (p->subs[x].owner) {
12338
ast_queue_hangup_with_cause(p->subs[x].owner, AST_CAUSE_PRE_EMPTED);
12339
ast_channel_unlock(p->subs[x].owner);
12343
ast_mutex_unlock(&p->lock);
12344
ast_mutex_lock(&pri->lock);
12347
#endif /* defined(HAVE_PRI) */
12349
#if defined(HAVE_PRI)
12350
static char * redirectingreason2str(int redirectingreason)
12352
switch (redirectingreason) {
12360
return "UNCONDITIONAL";
12362
return "NOREDIRECT";
12365
#endif /* defined(HAVE_PRI) */
12367
#if defined(HAVE_PRI)
12368
static void apply_plan_to_number(char *buf, size_t size, const struct dahdi_pri *pri, const char *number, const int plan)
12370
if (pri->dialplan == -2) { /* autodetect the TON but leave the number untouched */
12371
snprintf(buf, size, "%s", number);
12374
if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */
12381
case PRI_INTERNATIONAL_ISDN: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
12382
snprintf(buf, size, "%s%s", pri->internationalprefix, number);
12384
case PRI_NATIONAL_ISDN: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
12385
snprintf(buf, size, "%s%s", pri->nationalprefix, number);
12387
case PRI_LOCAL_ISDN: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
12388
snprintf(buf, size, "%s%s", pri->localprefix, number);
12390
case PRI_PRIVATE: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
12391
snprintf(buf, size, "%s%s", pri->privateprefix, number);
12393
case PRI_UNKNOWN: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
12394
snprintf(buf, size, "%s%s", pri->unknownprefix, number);
12396
default: /* other Q.931 dialplan => don't twiddle with callingnum */
12397
snprintf(buf, size, "%s", number);
12401
#endif /* defined(HAVE_PRI) */
12403
#if defined(HAVE_PRI)
12404
static void *pri_dchannel(void *vpri)
12406
struct dahdi_pri *pri = vpri;
12408
struct pollfd fds[NUM_DCHANS];
12415
struct ast_channel *c;
12416
struct timeval tv, lowest, *next;
12417
struct timeval lastidle = ast_tvnow();
12421
struct ast_channel *idle;
12427
struct dahdi_pvt *crv;
12428
pthread_t threadid;
12430
char plancallingnum[256];
12431
char plancallingani[256];
12432
char calledtonstr[10];
12434
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
12436
gettimeofday(&lastidle, NULL);
12437
if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
12438
/* Need to do idle dialing, check to be sure though */
12439
cc = strchr(pri->idleext, '@');
12443
ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
12445
/* Extensions may not be loaded yet */
12446
if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
12447
ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
12452
ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
12455
for (i = 0; i < NUM_DCHANS; i++) {
12456
if (!pri->dchannels[i])
12458
fds[i].fd = pri->fds[i];
12459
fds[i].events = POLLIN | POLLPRI;
12460
fds[i].revents = 0;
12464
ast_mutex_lock(&pri->lock);
12465
if ((pri->switchtype != PRI_SWITCH_GR303_TMC) && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) {
12466
if (pri->resetting && pri_is_up(pri)) {
12467
if (pri->resetpos < 0)
12468
pri_check_restart(pri);
12470
if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) {
12471
pri->resetting = 1;
12472
pri->resetpos = -1;
12476
/* Look for any idle channels if appropriate */
12477
if (doidling && pri_is_up(pri)) {
12481
for (x = pri->numchans; x >= 0; x--) {
12482
if (pri->pvts[x] && !pri->pvts[x]->owner &&
12483
!pri->pvts[x]->call) {
12484
if (haveidles < pri->minunused) {
12486
} else if (!pri->pvts[x]->resetting) {
12490
} else if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall)
12493
if (nextidle > -1) {
12494
if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
12495
/* Don't create a new idle call more than once per second */
12496
snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
12497
idle = dahdi_request("DAHDI", AST_FORMAT_ULAW, idlen, &cause);
12499
pri->pvts[nextidle]->isidlecall = 1;
12500
if (ast_pthread_create_background(&p, NULL, do_idle_thread, idle)) {
12501
ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", idle->name);
12502
dahdi_hangup(idle);
12505
ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
12506
lastidle = ast_tvnow();
12508
} else if ((haveidles < pri->minunused) &&
12509
(activeidles > pri->minidle)) {
12510
/* Mark something for hangup if there is something
12511
that can be hungup */
12512
for (x = pri->numchans; x >= 0; x--) {
12513
/* find a candidate channel */
12514
if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
12515
pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12517
/* Stop if we have enough idle channels or
12518
can't spare any more active idle ones */
12519
if ((haveidles >= pri->minunused) ||
12520
(activeidles <= pri->minidle))
12526
/* Start with reasonable max */
12527
lowest = ast_tv(60, 0);
12528
for (i = 0; i < NUM_DCHANS; i++) {
12529
/* Find lowest available d-channel */
12530
if (!pri->dchannels[i])
12532
if ((next = pri_schedule_next(pri->dchans[i]))) {
12533
/* We need relative time here */
12534
tv = ast_tvsub(*next, ast_tvnow());
12535
if (tv.tv_sec < 0) {
12538
if (doidling || pri->resetting) {
12539
if (tv.tv_sec > 1) {
12543
if (tv.tv_sec > 60) {
12544
tv = ast_tv(60, 0);
12547
} else if (doidling || pri->resetting) {
12548
/* Make sure we stop at least once per second if we're
12549
monitoring idle channels */
12552
/* Don't poll for more than 60 seconds */
12553
tv = ast_tv(60, 0);
12555
if (!i || ast_tvcmp(tv, lowest) < 0) {
12559
ast_mutex_unlock(&pri->lock);
12561
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
12562
pthread_testcancel();
12564
res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
12565
pthread_testcancel();
12566
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
12568
ast_mutex_lock(&pri->lock);
12570
for (which = 0; which < NUM_DCHANS; which++) {
12571
if (!pri->dchans[which])
12573
/* Just a timeout, run the scheduler */
12574
e = pri_schedule_run(pri->dchans[which]);
12578
} else if (res > -1) {
12579
for (which = 0; which < NUM_DCHANS; which++) {
12580
if (!pri->dchans[which])
12582
if (fds[which].revents & POLLPRI) {
12583
/* Check for an event */
12585
res = ioctl(pri->fds[which], DAHDI_GETEVENT, &x);
12587
ast_log(LOG_NOTICE, "PRI got event: %s (%d) on %s D-channel of span %d\n", event2str(x), x, pri_order(which), pri->span);
12588
manager_event(EVENT_FLAG_SYSTEM, "PRIEvent",
12590
"PRIEventCode: %d\r\n"
12591
"D-channel: %s\r\n"
12599
/* Keep track of alarm state */
12600
if (x == DAHDI_EVENT_ALARM) {
12601
pri->dchanavail[which] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
12602
pri_find_dchan(pri);
12603
} else if (x == DAHDI_EVENT_NOALARM) {
12604
pri->dchanavail[which] |= DCHAN_NOTINALARM;
12605
pri_restart(pri->dchans[which]);
12608
ast_debug(1, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
12609
} else if (fds[which].revents & POLLIN) {
12610
e = pri_check_event(pri->dchans[which]);
12615
} else if (errno != EINTR)
12616
ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
12620
pri_dump_event(pri->dchans[which], e);
12622
if (e->e != PRI_EVENT_DCHAN_DOWN) {
12623
if (!(pri->dchanavail[which] & DCHAN_UP)) {
12624
ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
12626
pri->dchanavail[which] |= DCHAN_UP;
12627
} else if (pri->sig != SIG_BRI_PTMP) {
12628
if (pri->dchanavail[which] & DCHAN_UP) {
12629
ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
12631
pri->dchanavail[which] &= ~DCHAN_UP;
12634
if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
12635
/* Must be an NFAS group that has the secondary dchan active */
12636
pri->pri = pri->dchans[which];
12639
case PRI_EVENT_DCHAN_UP:
12640
if (!pri->pri) pri_find_dchan(pri);
12642
/* Note presense of D-channel */
12643
time(&pri->lastreset);
12645
/* Restart in 5 seconds */
12646
if (pri->resetinterval > -1) {
12647
pri->lastreset -= pri->resetinterval;
12648
pri->lastreset += 5;
12650
pri->resetting = 0;
12651
/* Take the channels from inalarm condition */
12652
for (i = 0; i < pri->numchans; i++)
12653
if (pri->pvts[i]) {
12654
pri->pvts[i]->inalarm = 0;
12657
case PRI_EVENT_DCHAN_DOWN:
12658
pri_find_dchan(pri);
12659
if (!pri_is_up(pri)) {
12660
pri->resetting = 0;
12661
/* Hangup active channels and put them in alarm mode */
12662
for (i = 0; i < pri->numchans; i++) {
12663
struct dahdi_pvt *p = pri->pvts[i];
12665
if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
12666
/* T309 is not enabled : hangup calls when alarm occurs */
12668
if (p->pri && p->pri->pri) {
12669
pri_hangup(p->pri->pri, p->call, -1);
12670
pri_destroycall(p->pri->pri, p->call);
12673
ast_log(LOG_WARNING, "The PRI Call have not been destroyed\n");
12676
pri_hangup_all(p->realcall, pri);
12677
} else if (p->owner)
12678
p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12680
/* For PTMP connections with non persistent layer 2 we want
12681
* to *not* declare inalarm unless there actually is an alarm */
12682
if (p->sig != SIG_BRI_PTMP) {
12689
case PRI_EVENT_RESTART:
12690
if (e->restart.channel > -1) {
12691
chanpos = pri_find_principle(pri, e->restart.channel);
12693
ast_log(LOG_WARNING, "Restart requested on odd/unavailable channel number %d/%d on span %d\n",
12694
PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
12696
ast_verb(3, "B-channel %d/%d restarted on span %d\n",
12697
PRI_SPAN(e->restart.channel), PRI_CHANNEL(e->restart.channel), pri->span);
12698
ast_mutex_lock(&pri->pvts[chanpos]->lock);
12699
if (pri->pvts[chanpos]->call) {
12700
pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
12701
pri->pvts[chanpos]->call = NULL;
12703
/* Force soft hangup if appropriate */
12704
if (pri->pvts[chanpos]->realcall)
12705
pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
12706
else if (pri->pvts[chanpos]->owner)
12707
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12708
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12711
ast_verb(3, "Restart on requested on entire span %d\n", pri->span);
12712
for (x = 0; x < pri->numchans; x++)
12713
if (pri->pvts[x]) {
12714
ast_mutex_lock(&pri->pvts[x]->lock);
12715
if (pri->pvts[x]->call) {
12716
pri_destroycall(pri->pri, pri->pvts[x]->call);
12717
pri->pvts[x]->call = NULL;
12719
if (pri->pvts[x]->realcall)
12720
pri_hangup_all(pri->pvts[x]->realcall, pri);
12721
else if (pri->pvts[x]->owner)
12722
pri->pvts[x]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12723
ast_mutex_unlock(&pri->pvts[x]->lock);
12727
case PRI_EVENT_KEYPAD_DIGIT:
12728
chanpos = pri_find_principle(pri, e->digit.channel);
12730
ast_log(LOG_WARNING, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n",
12731
PRI_SPAN(e->digit.channel), PRI_CHANNEL(e->digit.channel), pri->span);
12733
chanpos = pri_fixup_principle(pri, chanpos, e->digit.call);
12734
if (chanpos > -1) {
12735
ast_mutex_lock(&pri->pvts[chanpos]->lock);
12736
/* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
12737
if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) {
12738
/* how to do that */
12739
int digitlen = strlen(e->digit.digits);
12742
for (i = 0; i < digitlen; i++) {
12743
digit = e->digit.digits[i];
12745
struct ast_frame f = { AST_FRAME_DTMF, digit, };
12746
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12750
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12755
case PRI_EVENT_INFO_RECEIVED:
12756
chanpos = pri_find_principle(pri, e->ring.channel);
12758
ast_log(LOG_WARNING, "INFO received on unconfigured channel %d/%d span %d\n",
12759
PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
12761
chanpos = pri_fixup_principle(pri, chanpos, e->ring.call);
12762
if (chanpos > -1) {
12763
ast_mutex_lock(&pri->pvts[chanpos]->lock);
12764
/* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
12765
if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) {
12766
/* how to do that */
12767
int digitlen = strlen(e->ring.callednum);
12770
for (i = 0; i < digitlen; i++) {
12771
digit = e->ring.callednum[i];
12773
struct ast_frame f = { AST_FRAME_DTMF, digit, };
12774
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
12778
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12782
case PRI_EVENT_RING:
12784
if (e->ring.channel == -1)
12785
chanpos = pri_find_empty_chan(pri, 1);
12787
chanpos = pri_find_principle(pri, e->ring.channel);
12788
/* if no channel specified find one empty */
12790
ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d/%d span %d\n",
12791
PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
12793
ast_mutex_lock(&pri->pvts[chanpos]->lock);
12794
if (pri->pvts[chanpos]->owner) {
12795
if (pri->pvts[chanpos]->call == e->ring.call) {
12796
ast_log(LOG_WARNING, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
12797
PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
12798
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12801
/* This is where we handle initial glare */
12802
ast_debug(1, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiate channel.\n",
12803
PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), pri->span);
12804
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12809
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12811
if ((chanpos < 0) && (e->ring.flexible))
12812
chanpos = pri_find_empty_chan(pri, 1);
12813
if (chanpos > -1) {
12814
ast_mutex_lock(&pri->pvts[chanpos]->lock);
12815
if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
12816
/* Should be safe to lock CRV AFAIK while bearer is still locked */
12817
crv = pri_find_crv(pri, pri_get_crv(pri->pri, e->ring.call, NULL));
12819
ast_mutex_lock(&crv->lock);
12820
if (!crv || crv->owner) {
12821
pri->pvts[chanpos]->call = NULL;
12824
crv->owner->_softhangup |= AST_SOFTHANGUP_DEV;
12825
ast_log(LOG_WARNING, "Call received for busy CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
12827
ast_log(LOG_NOTICE, "Call received for unconfigured CRV %d on span %d\n", pri_get_crv(pri->pri, e->ring.call, NULL), pri->span);
12828
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_INVALID_CALL_REFERENCE);
12830
ast_mutex_unlock(&crv->lock);
12831
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
12835
pri->pvts[chanpos]->call = e->ring.call;
12836
apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan);
12837
if (pri->pvts[chanpos]->use_callerid) {
12838
ast_shrink_phone_number(plancallingnum);
12839
ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
12841
if (!ast_strlen_zero(e->ring.callingani)) {
12842
apply_plan_to_number(plancallingani, sizeof(plancallingani), pri, e->ring.callingani, e->ring.callingplanani);
12843
ast_shrink_phone_number(plancallingani);
12844
ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani, sizeof(pri->pvts[chanpos]->cid_ani));
12846
pri->pvts[chanpos]->cid_ani[0] = '\0';
12849
ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
12850
pri->pvts[chanpos]->cid_ton = e->ring.callingplan; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
12852
pri->pvts[chanpos]->cid_num[0] = '\0';
12853
pri->pvts[chanpos]->cid_ani[0] = '\0';
12854
pri->pvts[chanpos]->cid_name[0] = '\0';
12855
pri->pvts[chanpos]->cid_ton = 0;
12857
apply_plan_to_number(pri->pvts[chanpos]->rdnis, sizeof(pri->pvts[chanpos]->rdnis), pri,
12858
e->ring.redirectingnum, e->ring.callingplanrdnis);
12859
/* If immediate=yes go to s|1 */
12860
if (pri->pvts[chanpos]->immediate) {
12861
ast_verb(3, "Going to extension s|1 because of immediate=yes\n");
12862
pri->pvts[chanpos]->exten[0] = 's';
12863
pri->pvts[chanpos]->exten[1] = '\0';
12865
/* Get called number */
12866
else if (!ast_strlen_zero(e->ring.callednum)) {
12867
ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
12868
ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
12869
} else if (pri->overlapdial)
12870
pri->pvts[chanpos]->exten[0] = '\0';
12872
/* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */
12873
pri->pvts[chanpos]->exten[0] = 's';
12874
pri->pvts[chanpos]->exten[1] = '\0';
12876
/* Set DNID on all incoming calls -- even immediate */
12877
if (!ast_strlen_zero(e->ring.callednum))
12878
ast_copy_string(pri->pvts[chanpos]->dnid, e->ring.callednum, sizeof(pri->pvts[chanpos]->dnid));
12879
/* No number yet, but received "sending complete"? */
12880
if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
12881
ast_verb(3, "Going to extension s|1 because of Complete received\n");
12882
pri->pvts[chanpos]->exten[0] = 's';
12883
pri->pvts[chanpos]->exten[1] = '\0';
12886
/* Make sure extension exists (or in overlap dial mode, can exist) */
12887
if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
12888
ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
12891
if (pri->switchtype != PRI_SWITCH_GR303_TMC) {
12892
/* Set to audio mode at this point */
12894
if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &law) == -1)
12895
ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n", pri->pvts[chanpos]->channel, law, strerror(errno));
12897
if (e->ring.layer1 == PRI_LAYER_1_ALAW)
12898
law = DAHDI_LAW_ALAW;
12900
law = DAHDI_LAW_MULAW;
12901
res = dahdi_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].dfd, law);
12903
ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel);
12904
res = set_actual_gain(pri->pvts[chanpos]->subs[SUB_REAL].dfd, 0, pri->pvts[chanpos]->rxgain, pri->pvts[chanpos]->txgain, law);
12906
ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pri->pvts[chanpos]->channel);
12907
if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
12908
/* Just announce proceeding */
12909
pri->pvts[chanpos]->proceeding = 1;
12910
pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
12912
if (pri->switchtype != PRI_SWITCH_GR303_TMC)
12913
pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
12915
pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
12917
/* Get the use_callingpres state */
12918
pri->pvts[chanpos]->callingpres = e->ring.callingpres;
12921
if (!e->ring.complete
12922
&& (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
12923
&& ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
12925
* Release the PRI lock while we create the channel
12926
* so other threads can send D channel messages.
12928
ast_mutex_unlock(&pri->lock);
12930
/* Set bearer and such */
12931
pri_assign_bearer(crv, pri, pri->pvts[chanpos]);
12932
c = dahdi_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
12933
pri->pvts[chanpos]->owner = &inuse;
12934
ast_debug(1, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel);
12936
c = dahdi_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype);
12938
ast_mutex_lock(&pri->lock);
12940
if (!ast_strlen_zero(e->ring.callingsubaddr)) {
12941
pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
12943
if (e->ring.ani2 >= 0) {
12944
snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
12945
pbx_builtin_setvar_helper(c, "ANI2", ani2str);
12946
pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
12949
#ifdef SUPPORT_USERUSER
12950
if (!ast_strlen_zero(e->ring.useruserinfo)) {
12951
pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
12955
snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
12956
pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
12957
if (e->ring.redirectingreason >= 0)
12958
pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
12960
if (c && !ast_pthread_create_detached(&threadid, NULL, ss_thread, c)) {
12961
ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
12962
plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
12963
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
12965
ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
12966
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
12970
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
12971
pri->pvts[chanpos]->call = NULL;
12976
* Release the PRI lock while we create the channel
12977
* so other threads can send D channel messages.
12979
ast_mutex_unlock(&pri->lock);
12980
c = dahdi_new(pri->pvts[chanpos], AST_STATE_RING, 0, SUB_REAL, law, e->ring.ctype);
12981
ast_mutex_lock(&pri->lock);
12984
* It is reasonably safe to set the following
12985
* channel variables while the PRI and DAHDI private
12986
* structures are locked. The PBX has not been
12987
* started yet and it is unlikely that any other task
12988
* will do anything with the channel we have just
12991
if (!ast_strlen_zero(e->ring.callingsubaddr)) {
12992
pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
12994
if (e->ring.ani2 >= 0) {
12995
snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
12996
pbx_builtin_setvar_helper(c, "ANI2", ani2str);
12997
pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
13000
#ifdef SUPPORT_USERUSER
13001
if (!ast_strlen_zero(e->ring.useruserinfo)) {
13002
pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
13006
if (e->ring.redirectingreason >= 0)
13007
pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
13009
snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
13010
pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
13012
if (c && !ast_pbx_start(c)) {
13013
ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
13014
plancallingnum, pri->pvts[chanpos]->exten,
13015
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
13017
dahdi_enable_ec(pri->pvts[chanpos]);
13019
ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
13020
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
13024
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
13025
pri->pvts[chanpos]->call = NULL;
13030
ast_verb(3, "Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n",
13031
pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context, pri->pvts[chanpos]->cid_num, pri->pvts[chanpos]->logicalspan,
13032
pri->pvts[chanpos]->prioffset, pri->span);
13033
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
13034
pri->pvts[chanpos]->call = NULL;
13035
pri->pvts[chanpos]->exten[0] = '\0';
13038
ast_mutex_unlock(&crv->lock);
13039
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13041
if (e->ring.flexible)
13042
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
13044
pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
13047
case PRI_EVENT_RINGING:
13048
chanpos = pri_find_principle(pri, e->ringing.channel);
13050
ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d/%d span %d\n",
13051
PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
13053
chanpos = pri_fixup_principle(pri, chanpos, e->ringing.call);
13055
ast_log(LOG_WARNING, "Ringing requested on channel %d/%d not in use on span %d\n",
13056
PRI_SPAN(e->ringing.channel), PRI_CHANNEL(e->ringing.channel), pri->span);
13058
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13059
if (ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
13060
dahdi_enable_ec(pri->pvts[chanpos]);
13061
pri->pvts[chanpos]->subs[SUB_REAL].needringing = 1;
13062
pri->pvts[chanpos]->alerting = 1;
13064
ast_debug(1, "Deferring ringing notification because of extra digits to dial...\n");
13067
#ifdef PRI_PROGRESS_MASK
13068
e->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE
13070
e->ringing.progress == 8
13073
/* Now we can do call progress detection */
13074
if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
13075
/* RINGING detection isn't required because we got ALERTING signal */
13076
ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features & ~DSP_PROGRESS_RINGING);
13077
pri->pvts[chanpos]->dsp_features = 0;
13081
#ifdef SUPPORT_USERUSER
13082
if (!ast_strlen_zero(e->ringing.useruserinfo)) {
13083
struct ast_channel *owner = pri->pvts[chanpos]->owner;
13084
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13085
pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->ringing.useruserinfo);
13086
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13090
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13094
case PRI_EVENT_PROGRESS:
13095
/* Get chan value if e->e is not PRI_EVNT_RINGING */
13096
chanpos = pri_find_principle(pri, e->proceeding.channel);
13097
if (chanpos > -1) {
13098
if ((!pri->pvts[chanpos]->progress)
13099
#ifdef PRI_PROGRESS_MASK
13100
|| (e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE)
13102
|| (e->proceeding.progress == 8)
13105
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, };
13107
if (e->proceeding.cause > -1) {
13108
ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
13110
/* Work around broken, out of spec USER_BUSY cause in a progress message */
13111
if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
13112
if (pri->pvts[chanpos]->owner) {
13113
ast_verb(3, "PROGRESS with 'user busy' received, signalling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
13115
pri->pvts[chanpos]->owner->hangupcause = e->proceeding.cause;
13116
f.subclass = AST_CONTROL_BUSY;
13121
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13122
ast_debug(1, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
13123
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
13124
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13126
#ifdef PRI_PROGRESS_MASK
13127
e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
13129
e->proceeding.progress == 8
13132
/* Now we can do call progress detection */
13133
if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
13134
ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
13135
pri->pvts[chanpos]->dsp_features = 0;
13137
/* Bring voice path up */
13138
f.subclass = AST_CONTROL_PROGRESS;
13139
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13141
pri->pvts[chanpos]->progress = 1;
13142
pri->pvts[chanpos]->dialing = 0;
13143
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13147
case PRI_EVENT_PROCEEDING:
13148
chanpos = pri_find_principle(pri, e->proceeding.channel);
13149
if (chanpos > -1) {
13150
if (!pri->pvts[chanpos]->proceeding) {
13151
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_PROCEEDING, };
13153
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13154
ast_debug(1, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
13155
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,pri->span);
13156
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13158
#ifdef PRI_PROGRESS_MASK
13159
e->proceeding.progressmask & PRI_PROG_INBAND_AVAILABLE
13161
e->proceeding.progress == 8
13164
/* Now we can do call progress detection */
13165
if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
13166
ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
13167
pri->pvts[chanpos]->dsp_features = 0;
13169
/* Bring voice path up */
13170
f.subclass = AST_CONTROL_PROGRESS;
13171
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13173
pri->pvts[chanpos]->proceeding = 1;
13174
pri->pvts[chanpos]->dialing = 0;
13175
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13179
case PRI_EVENT_FACNAME:
13180
chanpos = pri_find_principle(pri, e->facname.channel);
13182
ast_log(LOG_WARNING, "Facility Name requested on unconfigured channel %d/%d span %d\n",
13183
PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
13185
chanpos = pri_fixup_principle(pri, chanpos, e->facname.call);
13187
ast_log(LOG_WARNING, "Facility Name requested on channel %d/%d not in use on span %d\n",
13188
PRI_SPAN(e->facname.channel), PRI_CHANNEL(e->facname.channel), pri->span);
13190
/* Re-use *69 field for PRI */
13191
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13192
ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num));
13193
ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name));
13194
pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1;
13195
dahdi_enable_ec(pri->pvts[chanpos]);
13196
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13200
case PRI_EVENT_ANSWER:
13201
chanpos = pri_find_principle(pri, e->answer.channel);
13203
ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n",
13204
PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
13206
chanpos = pri_fixup_principle(pri, chanpos, e->answer.call);
13208
ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n",
13209
PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span);
13211
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13212
/* Now we can do call progress detection */
13214
/* We changed this so it turns on the DSP no matter what... progress or no progress.
13215
* By this time, we need DTMF detection and other features that were previously disabled
13217
if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) {
13218
ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features);
13219
pri->pvts[chanpos]->dsp_features = 0;
13221
if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) {
13222
ast_debug(1, "Starting up GR-303 trunk now that we got CONNECT...\n");
13224
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
13226
if (errno != EINPROGRESS) {
13227
ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
13230
} else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
13231
pri->pvts[chanpos]->dialing = 1;
13232
/* Send any "w" waited stuff */
13233
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_DIAL, &pri->pvts[chanpos]->dop);
13235
ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno));
13236
pri->pvts[chanpos]->dop.dialstr[0] = '\0';
13238
ast_debug(1, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr);
13240
pri->pvts[chanpos]->dop.dialstr[0] = '\0';
13241
} else if (pri->pvts[chanpos]->confirmanswer) {
13242
ast_debug(1, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel);
13244
pri->pvts[chanpos]->dialing = 0;
13245
pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1;
13246
/* Enable echo cancellation if it's not on already */
13247
dahdi_enable_ec(pri->pvts[chanpos]);
13250
#ifdef SUPPORT_USERUSER
13251
if (!ast_strlen_zero(e->answer.useruserinfo)) {
13252
struct ast_channel *owner = pri->pvts[chanpos]->owner;
13253
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13254
pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo);
13255
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13259
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13263
case PRI_EVENT_HANGUP:
13264
chanpos = pri_find_principle(pri, e->hangup.channel);
13266
ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n",
13267
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13269
chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
13270
if (chanpos > -1) {
13271
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13272
if (!pri->pvts[chanpos]->alreadyhungup) {
13273
/* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
13274
pri->pvts[chanpos]->alreadyhungup = 1;
13275
if (pri->pvts[chanpos]->realcall)
13276
pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
13277
else if (pri->pvts[chanpos]->owner) {
13278
/* Queue a BUSY instead of a hangup if our cause is appropriate */
13279
pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
13280
switch (pri->pvts[chanpos]->owner->_state) {
13281
case AST_STATE_BUSY:
13283
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13286
switch (e->hangup.cause) {
13287
case PRI_CAUSE_USER_BUSY:
13288
pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
13290
case PRI_CAUSE_CALL_REJECTED:
13291
case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
13292
case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
13293
case PRI_CAUSE_SWITCH_CONGESTION:
13294
case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
13295
case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
13296
pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
13299
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13304
ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n",
13305
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause);
13307
pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
13308
pri->pvts[chanpos]->call = NULL;
13310
if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
13311
ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n",
13312
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13313
pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
13314
pri->pvts[chanpos]->resetting = 1;
13316
if (e->hangup.aoc_units > -1)
13317
ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
13318
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
13320
#ifdef SUPPORT_USERUSER
13321
if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) {
13322
struct ast_channel *owner = pri->pvts[chanpos]->owner;
13323
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13324
pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
13325
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13329
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13331
ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n",
13332
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13336
#ifndef PRI_EVENT_HANGUP_REQ
13337
#error please update libpri
13339
case PRI_EVENT_HANGUP_REQ:
13340
chanpos = pri_find_principle(pri, e->hangup.channel);
13342
ast_log(LOG_WARNING, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
13343
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13345
chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
13346
if (chanpos > -1) {
13347
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13348
if (pri->pvts[chanpos]->realcall)
13349
pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
13350
else if (pri->pvts[chanpos]->owner) {
13351
pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause;
13352
switch (pri->pvts[chanpos]->owner->_state) {
13353
case AST_STATE_BUSY:
13355
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13358
switch (e->hangup.cause) {
13359
case PRI_CAUSE_USER_BUSY:
13360
pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1;
13362
case PRI_CAUSE_CALL_REJECTED:
13363
case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
13364
case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
13365
case PRI_CAUSE_SWITCH_CONGESTION:
13366
case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
13367
case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
13368
pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1;
13371
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13376
ast_verb(3, "Channel %d/%d, span %d got hangup request, cause %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span, e->hangup.cause);
13377
if (e->hangup.aoc_units > -1)
13378
ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
13379
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
13381
pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
13382
pri->pvts[chanpos]->call = NULL;
13384
if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) {
13385
ast_verb(3, "Forcing restart of channel %d/%d span %d since channel reported in use\n",
13386
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13387
pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
13388
pri->pvts[chanpos]->resetting = 1;
13391
#ifdef SUPPORT_USERUSER
13392
if (!ast_strlen_zero(e->hangup.useruserinfo)) {
13393
struct ast_channel *owner = pri->pvts[chanpos]->owner;
13394
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13395
pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
13396
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13400
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13402
ast_log(LOG_WARNING, "Hangup REQ on bad channel %d/%d on span %d\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13406
case PRI_EVENT_HANGUP_ACK:
13407
chanpos = pri_find_principle(pri, e->hangup.channel);
13409
ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n",
13410
PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13412
chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call);
13413
if (chanpos > -1) {
13414
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13415
pri->pvts[chanpos]->call = NULL;
13416
pri->pvts[chanpos]->resetting = 0;
13417
if (pri->pvts[chanpos]->owner) {
13418
ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span);
13421
#ifdef SUPPORT_USERUSER
13422
if (!ast_strlen_zero(e->hangup.useruserinfo)) {
13423
struct ast_channel *owner = pri->pvts[chanpos]->owner;
13424
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13425
pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo);
13426
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13430
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13434
case PRI_EVENT_CONFIG_ERR:
13435
ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->trunkgroup, e->err.err);
13437
case PRI_EVENT_RESTART_ACK:
13438
chanpos = pri_find_principle(pri, e->restartack.channel);
13440
/* Sometime switches (e.g. I421 / British Telecom) don't give us the
13441
channel number, so we have to figure it out... This must be why
13442
everybody resets exactly a channel at a time. */
13443
for (x = 0; x < pri->numchans; x++) {
13444
if (pri->pvts[x] && pri->pvts[x]->resetting) {
13446
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13447
ast_debug(1, "Assuming restart ack is really for channel %d/%d span %d\n", pri->pvts[chanpos]->logicalspan,
13448
pri->pvts[chanpos]->prioffset, pri->span);
13449
if (pri->pvts[chanpos]->realcall)
13450
pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
13451
else if (pri->pvts[chanpos]->owner) {
13452
ast_log(LOG_WARNING, "Got restart ack on channel %d/%d with owner on span %d\n", pri->pvts[chanpos]->logicalspan,
13453
pri->pvts[chanpos]->prioffset, pri->span);
13454
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13456
pri->pvts[chanpos]->resetting = 0;
13457
ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
13458
pri->pvts[chanpos]->prioffset, pri->span);
13459
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13460
if (pri->resetting)
13461
pri_check_restart(pri);
13466
ast_log(LOG_WARNING, "Restart ACK requested on strange channel %d/%d span %d\n",
13467
PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
13470
if (pri->pvts[chanpos]) {
13471
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13472
if (pri->pvts[chanpos]->realcall)
13473
pri_hangup_all(pri->pvts[chanpos]->realcall, pri);
13474
else if (pri->pvts[chanpos]->owner) {
13475
ast_log(LOG_WARNING, "Got restart ack on channel %d/%d span %d with owner\n",
13476
PRI_SPAN(e->restartack.channel), PRI_CHANNEL(e->restartack.channel), pri->span);
13477
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
13479
pri->pvts[chanpos]->resetting = 0;
13480
pri->pvts[chanpos]->inservice = 1;
13481
ast_verb(3, "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
13482
pri->pvts[chanpos]->prioffset, pri->span);
13483
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13484
if (pri->resetting)
13485
pri_check_restart(pri);
13489
case PRI_EVENT_SETUP_ACK:
13490
chanpos = pri_find_principle(pri, e->setup_ack.channel);
13492
ast_log(LOG_WARNING, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
13493
PRI_SPAN(e->setup_ack.channel), PRI_CHANNEL(e->setup_ack.channel), pri->span);
13495
chanpos = pri_fixup_principle(pri, chanpos, e->setup_ack.call);
13496
if (chanpos > -1) {
13497
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13498
pri->pvts[chanpos]->setup_ack = 1;
13499
/* Send any queued digits */
13500
for (x = 0;x < strlen(pri->pvts[chanpos]->dialdest); x++) {
13501
ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
13502
pri_information(pri->pri, pri->pvts[chanpos]->call,
13503
pri->pvts[chanpos]->dialdest[x]);
13505
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13507
ast_log(LOG_WARNING, "Unable to move channel %d!\n", e->setup_ack.channel);
13510
case PRI_EVENT_NOTIFY:
13511
chanpos = pri_find_principle(pri, e->notify.channel);
13513
ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
13514
PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
13515
} else if (!pri->discardremoteholdretrieval) {
13516
struct ast_frame f = { AST_FRAME_CONTROL, };
13517
ast_mutex_lock(&pri->pvts[chanpos]->lock);
13518
switch (e->notify.info) {
13519
case PRI_NOTIFY_REMOTE_HOLD:
13520
f.subclass = AST_CONTROL_HOLD;
13521
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13523
case PRI_NOTIFY_REMOTE_RETRIEVAL:
13524
f.subclass = AST_CONTROL_UNHOLD;
13525
dahdi_queue_frame(pri->pvts[chanpos], &f, pri);
13528
ast_mutex_unlock(&pri->pvts[chanpos]->lock);
13532
ast_debug(1, "Event: %d\n", e->e);
13535
ast_mutex_unlock(&pri->lock);
13537
/* Never reached */
13540
#endif /* defined(HAVE_PRI) */
13542
#if defined(HAVE_PRI)
13543
static int start_pri(struct dahdi_pri *pri)
13546
struct dahdi_params p;
13547
struct dahdi_bufferinfo bi;
13548
struct dahdi_spaninfo si;
13551
for (i = 0; i < NUM_DCHANS; i++) {
13552
if (!pri->dchannels[i])
13554
pri->fds[i] = open("/dev/dahdi/channel", O_RDWR);
13555
x = pri->dchannels[i];
13556
if ((pri->fds[i] < 0) || (ioctl(pri->fds[i],DAHDI_SPECIFY,&x) == -1)) {
13557
ast_log(LOG_ERROR, "Unable to open D-channel %d (%s)\n", x, strerror(errno));
13560
memset(&p, 0, sizeof(p));
13561
res = ioctl(pri->fds[i], DAHDI_GET_PARAMS, &p);
13563
dahdi_close_pri_fd(pri, i);
13564
ast_log(LOG_ERROR, "Unable to get parameters for D-channel %d (%s)\n", x, strerror(errno));
13567
if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
13568
dahdi_close_pri_fd(pri, i);
13569
ast_log(LOG_ERROR, "D-channel %d is not in HDLC/FCS mode.\n", x);
13572
memset(&si, 0, sizeof(si));
13573
res = ioctl(pri->fds[i], DAHDI_SPANSTAT, &si);
13575
dahdi_close_pri_fd(pri, i);
13576
ast_log(LOG_ERROR, "Unable to get span state for D-channel %d (%s)\n", x, strerror(errno));
13579
pri->dchanavail[i] |= DCHAN_NOTINALARM;
13581
pri->dchanavail[i] &= ~DCHAN_NOTINALARM;
13582
memset(&bi, 0, sizeof(bi));
13583
bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
13584
bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
13587
if (ioctl(pri->fds[i], DAHDI_SET_BUFINFO, &bi)) {
13588
ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", x, strerror(errno));
13589
dahdi_close_pri_fd(pri, i);
13592
switch (pri->sig) {
13594
pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
13597
pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
13600
pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
13603
/* Force overlap dial if we're doing GR-303! */
13604
if (pri->switchtype == PRI_SWITCH_GR303_TMC)
13605
pri->overlapdial |= DAHDI_OVERLAPDIAL_BOTH;
13606
pri_set_overlapdial(pri->dchans[i],(pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)?1:0);
13607
#ifdef HAVE_PRI_PROG_W_CAUSE
13608
pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
13610
#ifdef HAVE_PRI_INBANDDISCONNECT
13611
pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
13613
/* Enslave to master if appropriate */
13615
pri_enslave(pri->dchans[0], pri->dchans[i]);
13616
if (!pri->dchans[i]) {
13617
dahdi_close_pri_fd(pri, i);
13618
ast_log(LOG_ERROR, "Unable to create PRI structure\n");
13621
pri_set_debug(pri->dchans[i], DEFAULT_PRI_DEBUG);
13622
pri_set_nsf(pri->dchans[i], pri->nsf);
13623
#ifdef PRI_GETSET_TIMERS
13624
for (x = 0; x < PRI_MAX_TIMERS; x++) {
13625
if (pritimers[x] != 0)
13626
pri_set_timer(pri->dchans[i], x, pritimers[x]);
13630
/* Assume primary is the one we use */
13631
pri->pri = pri->dchans[0];
13632
pri->resetpos = -1;
13633
if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
13634
for (i = 0; i < NUM_DCHANS; i++) {
13635
if (!pri->dchannels[i])
13637
dahdi_close_pri_fd(pri, i);
13639
ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
13644
#endif /* defined(HAVE_PRI) */
13646
#if defined(HAVE_PRI)
13647
static char *complete_span_helper(const char *line, const char *word, int pos, int state, int rpos)
13655
for (which = span = 0; span < NUM_SPANS; span++) {
13656
if (pris[span].pri && ++which > state) {
13657
if (asprintf(&ret, "%d", span + 1) < 0) { /* user indexes start from 1 */
13658
ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
13665
#endif /* defined(HAVE_PRI) */
13667
#if defined(HAVE_PRI)
13668
static char *complete_span_4(const char *line, const char *word, int pos, int state)
13670
return complete_span_helper(line,word,pos,state,3);
13672
#endif /* defined(HAVE_PRI) */
13674
#if defined(HAVE_PRI)
13675
static char *handle_pri_set_debug_file(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13680
e->command = "pri set debug file";
13681
e->usage = "Usage: pri set debug file [output-file]\n"
13682
" Sends PRI debug output to the specified output file\n";
13688
return CLI_SHOWUSAGE;
13690
if (ast_strlen_zero(a->argv[4]))
13691
return CLI_SHOWUSAGE;
13693
myfd = open(a->argv[4], O_CREAT|O_WRONLY, AST_FILE_MODE);
13695
ast_cli(a->fd, "Unable to open '%s' for writing\n", a->argv[4]);
13696
return CLI_SUCCESS;
13699
ast_mutex_lock(&pridebugfdlock);
13701
if (pridebugfd >= 0)
13705
ast_copy_string(pridebugfilename,a->argv[4],sizeof(pridebugfilename));
13706
ast_mutex_unlock(&pridebugfdlock);
13707
ast_cli(a->fd, "PRI debug output will be sent to '%s'\n", a->argv[4]);
13708
return CLI_SUCCESS;
13710
#endif /* defined(HAVE_PRI) */
13712
#if defined(HAVE_PRI)
13713
static char *handle_pri_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13720
e->command = "pri set debug {on|off|0|1|2} span";
13722
"Usage: pri set debug {<level>|on|off} span <span>\n"
13723
" Enables debugging on a given PRI span\n";
13726
return complete_span_4(a->line, a->word, a->pos, a->n);
13729
return CLI_SHOWUSAGE;
13732
if (!strcasecmp(a->argv[3], "on")) {
13734
} else if (!strcasecmp(a->argv[3], "off")) {
13737
level = atoi(a->argv[3]);
13739
span = atoi(a->argv[5]);
13740
if ((span < 1) || (span > NUM_SPANS)) {
13741
ast_cli(a->fd, "Invalid span %s. Should be a number %d to %d\n", a->argv[5], 1, NUM_SPANS);
13742
return CLI_SUCCESS;
13744
if (!pris[span-1].pri) {
13745
ast_cli(a->fd, "No PRI running on span %d\n", span);
13746
return CLI_SUCCESS;
13748
for (x = 0; x < NUM_DCHANS; x++) {
13749
if (pris[span-1].dchans[x]) {
13751
pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
13752
PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
13753
PRI_DEBUG_Q921_STATE);
13754
ast_cli(a->fd, "Enabled debugging on span %d\n", span);
13755
} else if (level == 0) {
13756
pri_set_debug(pris[span-1].dchans[x], 0);
13757
//close the file if it's set
13758
ast_mutex_lock(&pridebugfdlock);
13761
ast_cli(a->fd, "PRI debug output to file disabled\n");
13762
ast_mutex_unlock(&pridebugfdlock);
13764
pri_set_debug(pris[span-1].dchans[x], PRI_DEBUG_APDU |
13765
PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE |
13766
PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_STATE);
13767
ast_cli(a->fd, "Enabled debugging on span %d\n", span);
13771
return CLI_SUCCESS;
13773
#endif /* defined(HAVE_PRI) */
13775
#if defined(HAVE_PRI)
13776
static void build_status(char *s, size_t len, int status, int active)
13778
if (!s || len < 1) {
13782
if (status & DCHAN_PROVISIONED)
13783
strncat(s, "Provisioned, ", len - strlen(s) - 1);
13784
if (!(status & DCHAN_NOTINALARM))
13785
strncat(s, "In Alarm, ", len - strlen(s) - 1);
13786
if (status & DCHAN_UP)
13787
strncat(s, "Up", len - strlen(s) - 1);
13789
strncat(s, "Down", len - strlen(s) - 1);
13791
strncat(s, ", Active", len - strlen(s) - 1);
13793
strncat(s, ", Standby", len - strlen(s) - 1);
13796
#endif /* defined(HAVE_PRI) */
13798
#if defined(HAVE_PRI)
13799
static char *handle_pri_show_spans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13807
e->command = "pri show spans";
13809
"Usage: pri show spans\n"
13810
" Displays PRI Information\n";
13817
return CLI_SHOWUSAGE;
13819
for (span = 0; span < NUM_SPANS; span++) {
13820
if (pris[span].pri) {
13821
for (x = 0; x < NUM_DCHANS; x++) {
13822
if (pris[span].dchannels[x]) {
13823
build_status(status, sizeof(status), pris[span].dchanavail[x], pris[span].dchans[x] == pris[span].pri);
13824
ast_cli(a->fd, "PRI span %d/%d: %s\n", span + 1, x, status);
13829
return CLI_SUCCESS;
13831
#endif /* defined(HAVE_PRI) */
13833
#if defined(HAVE_PRI)
13834
static char *handle_pri_show_span(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13841
e->command = "pri show span";
13843
"Usage: pri show span <span>\n"
13844
" Displays PRI Information on a given PRI span\n";
13847
return complete_span_4(a->line, a->word, a->pos, a->n);
13851
return CLI_SHOWUSAGE;
13852
span = atoi(a->argv[3]);
13853
if ((span < 1) || (span > NUM_SPANS)) {
13854
ast_cli(a->fd, "Invalid span '%s'. Should be a number from %d to %d\n", a->argv[3], 1, NUM_SPANS);
13855
return CLI_SUCCESS;
13857
if (!pris[span-1].pri) {
13858
ast_cli(a->fd, "No PRI running on span %d\n", span);
13859
return CLI_SUCCESS;
13861
for (x = 0; x < NUM_DCHANS; x++) {
13862
if (pris[span-1].dchannels[x]) {
13863
#ifdef PRI_DUMP_INFO_STR
13864
char *info_str = NULL;
13866
ast_cli(a->fd, "%s D-channel: %d\n", pri_order(x), pris[span-1].dchannels[x]);
13867
build_status(status, sizeof(status), pris[span-1].dchanavail[x], pris[span-1].dchans[x] == pris[span-1].pri);
13868
ast_cli(a->fd, "Status: %s\n", status);
13869
#ifdef PRI_DUMP_INFO_STR
13870
info_str = pri_dump_info_str(pris[span-1].pri);
13872
ast_cli(a->fd, "%s", info_str);
13873
ast_free(info_str);
13876
pri_dump_info(pris[span-1].pri);
13878
ast_cli(a->fd, "Overlap Recv: %s\n\n", (pris[span-1].overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
13881
return CLI_SUCCESS;
13883
#endif /* defined(HAVE_PRI) */
13885
#if defined(HAVE_PRI)
13886
static char *handle_pri_show_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13895
e->command = "pri show debug";
13897
"Usage: pri show debug\n"
13898
" Show the debug state of pri spans\n";
13904
for (span = 0; span < NUM_SPANS; span++) {
13905
if (pris[span].pri) {
13906
for (x = 0; x < NUM_DCHANS; x++) {
13908
if (pris[span].dchans[x]) {
13909
debug = pri_get_debug(pris[span].dchans[x]);
13910
ast_cli(a->fd, "Span %d: Debug: %s\tIntense: %s\n", span+1, (debug&PRI_DEBUG_Q931_STATE)? "Yes" : "No" ,(debug&PRI_DEBUG_Q921_RAW)? "Yes" : "No" );
13917
ast_mutex_lock(&pridebugfdlock);
13918
if (pridebugfd >= 0)
13919
ast_cli(a->fd, "Logging PRI debug to file %s\n", pridebugfilename);
13920
ast_mutex_unlock(&pridebugfdlock);
13923
ast_cli(a->fd, "No debug set or no PRI running\n");
13924
return CLI_SUCCESS;
13926
#endif /* defined(HAVE_PRI) */
13928
#if defined(HAVE_PRI)
13929
static char *handle_pri_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13933
e->command = "pri show version";
13935
"Usage: pri show version\n"
13936
"Show libpri version information\n";
13942
ast_cli(a->fd, "libpri version: %s\n", pri_get_version());
13944
return CLI_SUCCESS;
13946
#endif /* defined(HAVE_PRI) */
13948
#if defined(HAVE_PRI)
13949
static struct ast_cli_entry dahdi_pri_cli[] = {
13950
AST_CLI_DEFINE(handle_pri_debug, "Enables PRI debugging on a span"),
13951
AST_CLI_DEFINE(handle_pri_show_spans, "Displays PRI Information"),
13952
AST_CLI_DEFINE(handle_pri_show_span, "Displays PRI Information"),
13953
AST_CLI_DEFINE(handle_pri_show_debug, "Displays current PRI debug settings"),
13954
AST_CLI_DEFINE(handle_pri_set_debug_file, "Sends PRI debug output to the specified file"),
13955
AST_CLI_DEFINE(handle_pri_version, "Displays libpri version"),
13957
#endif /* defined(HAVE_PRI) */
13961
static char *handle_mfcr2_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13965
e->command = "mfcr2 show version";
13967
"Usage: mfcr2 show version\n"
13968
" Shows the version of the OpenR2 library being used.\n";
13973
ast_cli(a->fd, "OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
13974
return CLI_SUCCESS;
13977
static char *handle_mfcr2_show_variants(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13979
#define FORMAT "%4s %40s\n"
13981
int numvariants = 0;
13982
const openr2_variant_entry_t *variants;
13985
e->command = "mfcr2 show variants";
13987
"Usage: mfcr2 show variants\n"
13988
" Shows the list of MFC/R2 variants supported.\n";
13993
if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
13994
ast_cli(a->fd, "Failed to get list of variants.\n");
13995
return CLI_FAILURE;
13997
ast_cli(a->fd, FORMAT, "Variant Code", "Country");
13998
for (i = 0; i < numvariants; i++) {
13999
ast_cli(a->fd, FORMAT, variants[i].name, variants[i].country);
14001
return CLI_SUCCESS;
14005
static char *handle_mfcr2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14007
#define FORMAT "%4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
14008
int filtertype = 0;
14013
struct dahdi_pvt *p;
14014
openr2_context_t *r2context;
14015
openr2_variant_t r2variant;
14018
e->command = "mfcr2 show channels [group|context]";
14020
"Usage: mfcr2 show channels [group <group> | context <context>]\n"
14021
" Shows the DAHDI channels configured with MFC/R2 signaling.\n";
14026
if (!((a->argc == 3) || (a->argc == 5))) {
14027
return CLI_SHOWUSAGE;
14029
if (a->argc == 5) {
14030
if (!strcasecmp(a->argv[3], "group")) {
14031
targetnum = atoi(a->argv[4]);
14032
if ((targetnum < 0) || (targetnum > 63))
14033
return CLI_SHOWUSAGE;
14034
targetnum = 1 << targetnum;
14036
} else if (!strcasecmp(a->argv[3], "context")) {
14039
return CLI_SHOWUSAGE;
14042
ast_cli(a->fd, FORMAT, "Chan", "Variant", "Max ANI", "Max DNIS", "ANI First", "Immediate Accept", "Tx CAS", "Rx CAS");
14043
ast_mutex_lock(&iflock);
14045
for (p = iflist; p; p = p->next) {
14046
if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
14050
switch(filtertype) {
14051
case 1: /* mfcr2 show channels group <group> */
14052
if (p->group != targetnum) {
14056
case 2: /* mfcr2 show channels context <context> */
14057
if (strcasecmp(p->context, a->argv[4])) {
14065
r2context = openr2_chan_get_context(p->r2chan);
14066
r2variant = openr2_context_get_variant(r2context);
14067
snprintf(channo, sizeof(channo), "%d", p->channel);
14068
snprintf(anino, sizeof(anino), "%d", openr2_context_get_max_ani(r2context));
14069
snprintf(dnisno, sizeof(dnisno), "%d", openr2_context_get_max_dnis(r2context));
14070
ast_cli(a->fd, FORMAT, channo, openr2_proto_get_variant_string(r2variant),
14071
anino, dnisno, openr2_context_get_ani_first(r2context) ? "Yes" : "No",
14072
openr2_context_get_immediate_accept(r2context) ? "Yes" : "No",
14073
openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
14075
ast_mutex_unlock(&iflock);
14076
return CLI_SUCCESS;
14080
static char *handle_mfcr2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14082
struct dahdi_pvt *p = NULL;
14084
char *toklevel = NULL;
14085
char *saveptr = NULL;
14086
char *logval = NULL;
14087
openr2_log_level_t loglevel = OR2_LOG_NOTHING;
14088
openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
14091
e->command = "mfcr2 set debug";
14093
"Usage: mfcr2 set debug <loglevel> <channel>\n"
14094
" Set a new logging level for the specified channel.\n"
14095
" If no channel is specified the logging level will be applied to all channels.\n";
14101
return CLI_SHOWUSAGE;
14103
channo = (a->argc == 5) ? atoi(a->argv[4]) : -1;
14104
logval = ast_strdupa(a->argv[3]);
14105
toklevel = strtok_r(logval, ",", &saveptr);
14106
if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14107
ast_cli(a->fd, "Invalid MFC/R2 logging level '%s'.\n", a->argv[3]);
14108
return CLI_FAILURE;
14109
} else if (OR2_LOG_NOTHING == tmplevel) {
14110
loglevel = tmplevel;
14112
loglevel |= tmplevel;
14113
while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
14114
if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
14115
ast_cli(a->fd, "Ignoring invalid logging level: '%s'.\n", toklevel);
14118
loglevel |= tmplevel;
14121
ast_mutex_lock(&iflock);
14122
for (p = iflist; p; p = p->next) {
14123
if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
14126
if ((channo != -1) && (p->channel != channo )) {
14129
openr2_chan_set_log_level(p->r2chan, loglevel);
14130
if (channo != -1) {
14131
ast_cli(a->fd, "MFC/R2 debugging set to '%s' for channel %d.\n", a->argv[3], p->channel);
14135
if ((channo != -1) && !p) {
14136
ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
14138
if (channo == -1) {
14139
ast_cli(a->fd, "MFC/R2 debugging set to '%s' for all channels.\n", a->argv[3]);
14141
ast_mutex_unlock(&iflock);
14142
return CLI_SUCCESS;
14145
static char *handle_mfcr2_call_files(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14147
struct dahdi_pvt *p = NULL;
14151
e->command = "mfcr2 call files [on|off]";
14153
"Usage: mfcr2 call files [on|off] <channel>\n"
14154
" Enable call files creation on the specified channel.\n"
14155
" If no channel is specified call files creation policy will be applied to all channels.\n";
14161
return CLI_SHOWUSAGE;
14163
channo = (a->argc == 5) ? atoi(a->argv[4]) : -1;
14164
ast_mutex_lock(&iflock);
14165
for (p = iflist; p; p = p->next) {
14166
if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
14169
if ((channo != -1) && (p->channel != channo )) {
14172
if (ast_true(a->argv[3])) {
14173
openr2_chan_enable_call_files(p->r2chan);
14175
openr2_chan_disable_call_files(p->r2chan);
14177
if (channo != -1) {
14178
if (ast_true(a->argv[3])) {
14179
ast_cli(a->fd, "MFC/R2 call files enabled for channel %d.\n", p->channel);
14181
ast_cli(a->fd, "MFC/R2 call files disabled for channel %d.\n", p->channel);
14186
if ((channo != -1) && !p) {
14187
ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
14189
if (channo == -1) {
14190
if (ast_true(a->argv[3])) {
14191
ast_cli(a->fd, "MFC/R2 Call files enabled for all channels.\n");
14193
ast_cli(a->fd, "MFC/R2 Call files disabled for all channels.\n");
14196
ast_mutex_unlock(&iflock);
14197
return CLI_SUCCESS;
14200
static char *handle_mfcr2_set_idle(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14202
struct dahdi_pvt *p = NULL;
14206
e->command = "mfcr2 set idle";
14208
"Usage: mfcr2 set idle <channel>\n"
14209
" DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
14210
" Force the given channel into IDLE state.\n"
14211
" If no channel is specified, all channels will be set to IDLE.\n";
14216
channo = (a->argc == 4) ? atoi(a->argv[3]) : -1;
14217
ast_mutex_lock(&iflock);
14218
for (p = iflist; p; p = p->next) {
14219
if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
14222
if ((channo != -1) && (p->channel != channo )) {
14225
openr2_chan_set_idle(p->r2chan);
14226
ast_mutex_lock(&p->lock);
14227
p->locallyblocked = 0;
14229
ast_mutex_unlock(&p->lock);
14230
if (channo != -1) {
14234
if ((channo != -1) && !p) {
14235
ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
14237
ast_mutex_unlock(&iflock);
14238
return CLI_SUCCESS;
14241
static char *handle_mfcr2_set_blocked(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14243
struct dahdi_pvt *p = NULL;
14247
e->command = "mfcr2 set blocked";
14249
"Usage: mfcr2 set blocked <channel>\n"
14250
" DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
14251
" Force the given channel into BLOCKED state.\n"
14252
" If no channel is specified, all channels will be set to BLOCKED.\n";
14257
channo = (a->argc == 4) ? atoi(a->argv[3]) : -1;
14258
ast_mutex_lock(&iflock);
14259
for (p = iflist; p; p = p->next) {
14260
if (!(p->sig & SIG_MFCR2) || !p->r2chan) {
14263
if ((channo != -1) && (p->channel != channo )) {
14266
openr2_chan_set_blocked(p->r2chan);
14267
ast_mutex_lock(&p->lock);
14268
p->locallyblocked = 1;
14269
ast_mutex_unlock(&p->lock);
14270
if (channo != -1) {
14274
if ((channo != -1) && !p) {
14275
ast_cli(a->fd, "MFC/R2 channel %d not found.\n", channo);
14277
ast_mutex_unlock(&iflock);
14278
return CLI_SUCCESS;
14281
static struct ast_cli_entry dahdi_mfcr2_cli[] = {
14282
AST_CLI_DEFINE(handle_mfcr2_version, "Show OpenR2 library version"),
14283
AST_CLI_DEFINE(handle_mfcr2_show_variants, "Show supported MFC/R2 variants"),
14284
AST_CLI_DEFINE(handle_mfcr2_show_channels, "Show MFC/R2 channels"),
14285
AST_CLI_DEFINE(handle_mfcr2_set_debug, "Set MFC/R2 channel logging level"),
14286
AST_CLI_DEFINE(handle_mfcr2_call_files, "Enable/Disable MFC/R2 call files"),
14287
AST_CLI_DEFINE(handle_mfcr2_set_idle, "Reset MFC/R2 channel forcing it to IDLE"),
14288
AST_CLI_DEFINE(handle_mfcr2_set_blocked, "Reset MFC/R2 channel forcing it to BLOCKED"),
14291
#endif /* HAVE_OPENR2 */
14293
static char *dahdi_destroy_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14299
e->command = "dahdi destroy channel";
14301
"Usage: dahdi destroy channel <chan num>\n"
14302
" DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
14308
return CLI_SHOWUSAGE;
14310
channel = atoi(a->argv[3]);
14311
ret = dahdi_destroy_channel_bynum(channel);
14312
return ( RESULT_SUCCESS == ret ) ? CLI_SUCCESS : CLI_FAILURE;
14315
static void dahdi_softhangup_all(void)
14317
struct dahdi_pvt *p;
14319
ast_mutex_lock(&iflock);
14320
for (p = iflist; p; p = p->next) {
14321
ast_mutex_lock(&p->lock);
14322
if (p->owner && !p->restartpending) {
14323
if (ast_channel_trylock(p->owner)) {
14324
if (option_debug > 2)
14325
ast_verbose("Avoiding deadlock\n");
14326
/* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
14327
ast_mutex_unlock(&p->lock);
14328
ast_mutex_unlock(&iflock);
14331
if (option_debug > 2)
14332
ast_verbose("Softhanging up on %s\n", p->owner->name);
14333
ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_EXPLICIT);
14334
p->restartpending = 1;
14335
num_restart_pending++;
14336
ast_channel_unlock(p->owner);
14338
ast_mutex_unlock(&p->lock);
14340
ast_mutex_unlock(&iflock);
14343
static int setup_dahdi(int reload);
14344
static int dahdi_restart(void)
14346
#if defined(HAVE_PRI) || defined(HAVE_SS7)
14350
struct dahdi_pvt *p;
14352
ast_mutex_lock(&restart_lock);
14353
ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
14354
dahdi_softhangup_all();
14355
ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n");
14357
dahdi_r2_destroy_links();
14360
#if defined(HAVE_PRI)
14361
for (i = 0; i < NUM_SPANS; i++) {
14362
if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) {
14363
cancel_code = pthread_cancel(pris[i].master);
14364
pthread_kill(pris[i].master, SIGURG);
14365
ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) pris[i].master, cancel_code);
14366
pthread_join(pris[i].master, NULL);
14367
ast_debug(4, "Joined thread of span %d\n", i);
14372
#if defined(HAVE_SS7)
14373
for (i = 0; i < NUM_SPANS; i++) {
14374
if (linksets[i].master && (linksets[i].master != AST_PTHREADT_NULL)) {
14375
cancel_code = pthread_cancel(linksets[i].master);
14376
pthread_kill(linksets[i].master, SIGURG);
14377
ast_debug(4, "Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i, (void *) linksets[i].master, cancel_code);
14378
pthread_join(linksets[i].master, NULL);
14379
ast_debug(4, "Joined thread of span %d\n", i);
14384
ast_mutex_lock(&monlock);
14385
if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
14386
cancel_code = pthread_cancel(monitor_thread);
14387
pthread_kill(monitor_thread, SIGURG);
14388
ast_debug(4, "Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread, cancel_code);
14389
pthread_join(monitor_thread, NULL);
14390
ast_debug(4, "Joined monitor thread\n");
14392
monitor_thread = AST_PTHREADT_NULL; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
14394
ast_mutex_lock(&ss_thread_lock);
14395
while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
14396
int x = DAHDI_FLASH;
14397
ast_debug(3, "Waiting on %d ss_thread(s) to finish\n", ss_thread_count);
14399
for (p = iflist; p; p = p->next) {
14401
ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
14403
ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
14406
/* ensure any created channels before monitor threads were stopped are hungup */
14407
dahdi_softhangup_all();
14408
ast_verb(4, "Final softhangup of all DAHDI channels complete.\n");
14409
destroy_all_channels();
14410
ast_debug(1, "Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
14412
ast_mutex_unlock(&monlock);
14415
for (i = 0; i < NUM_SPANS; i++) {
14416
for (j = 0; j < NUM_DCHANS; j++)
14417
dahdi_close_pri_fd(&(pris[i]), j);
14420
memset(pris, 0, sizeof(pris));
14421
for (i = 0; i < NUM_SPANS; i++) {
14422
ast_mutex_init(&pris[i].lock);
14423
pris[i].offset = -1;
14424
pris[i].master = AST_PTHREADT_NULL;
14425
for (j = 0; j < NUM_DCHANS; j++)
14426
pris[i].fds[j] = -1;
14428
pri_set_error(dahdi_pri_error);
14429
pri_set_message(dahdi_pri_message);
14432
for (i = 0; i < NUM_SPANS; i++) {
14433
for (j = 0; j < NUM_DCHANS; j++)
14434
dahdi_close_ss7_fd(&(linksets[i]), j);
14437
memset(linksets, 0, sizeof(linksets));
14438
for (i = 0; i < NUM_SPANS; i++) {
14439
ast_mutex_init(&linksets[i].lock);
14440
linksets[i].master = AST_PTHREADT_NULL;
14441
for (j = 0; j < NUM_DCHANS; j++)
14442
linksets[i].fds[j] = -1;
14444
ss7_set_error(dahdi_ss7_error);
14445
ss7_set_message(dahdi_ss7_message);
14448
if (setup_dahdi(2) != 0) {
14449
ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
14450
ast_mutex_unlock(&ss_thread_lock);
14453
ast_mutex_unlock(&ss_thread_lock);
14454
ast_mutex_unlock(&restart_lock);
14458
static char *dahdi_restart_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14462
e->command = "dahdi restart";
14464
"Usage: dahdi restart\n"
14465
" Restarts the DAHDI channels: destroys them all and then\n"
14466
" re-reads them from chan_dahdi.conf.\n"
14467
" Note that this will STOP any running CALL on DAHDI channels.\n"
14474
return CLI_SHOWUSAGE;
14476
if (dahdi_restart() != 0)
14477
return CLI_FAILURE;
14478
return CLI_SUCCESS;
14481
static int action_dahdirestart(struct mansession *s, const struct message *m)
14483
if (dahdi_restart() != 0) {
14484
astman_send_error(s, m, "Failed rereading DAHDI configuration");
14487
astman_send_ack(s, m, "DAHDIRestart: Success");
14491
static char *dahdi_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14493
#define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n"
14494
#define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s\n"
14495
unsigned int targetnum = 0;
14496
int filtertype = 0;
14497
struct dahdi_pvt *tmp = NULL;
14498
char tmps[20] = "";
14499
char statestr[20] = "";
14500
char blockstr[20] = "";
14502
struct dahdi_pvt *start;
14505
struct dahdi_pri *pri = NULL;
14510
e->command = "dahdi show channels [trunkgroup|group|context]";
14512
"Usage: dahdi show channels [ trunkgroup <trunkgroup> | group <group> | context <context> ]\n"
14513
" Shows a list of available channels with optional filtering\n"
14514
" <group> must be a number between 0 and 63\n";
14523
/* syntax: dahdi show channels [ group <group> | context <context> | trunkgroup <trunkgroup> ] */
14525
if (!((a->argc == 3) || (a->argc == 5)))
14526
return CLI_SHOWUSAGE;
14528
if (a->argc == 5) {
14530
if (!strcasecmp(a->argv[3], "trunkgroup")) {
14531
/* this option requires no special handling, so leave filtertype to zero */
14532
if ((trunkgroup = atoi(a->argv[4])) < 1)
14533
return CLI_SHOWUSAGE;
14534
for (x = 0; x < NUM_SPANS; x++) {
14535
if (pris[x].trunkgroup == trunkgroup) {
14544
ast_cli(a->fd, "No such trunk group %d\n", trunkgroup);
14545
return CLI_FAILURE;
14549
if (!strcasecmp(a->argv[3], "group")) {
14550
targetnum = atoi(a->argv[4]);
14551
if ((targetnum < 0) || (targetnum > 63))
14552
return CLI_SHOWUSAGE;
14553
targetnum = 1 << targetnum;
14555
} else if (!strcasecmp(a->argv[3], "context")) {
14560
ast_mutex_lock(lock);
14562
ast_cli(a->fd, FORMAT2, pri ? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State");
14564
ast_cli(a->fd, FORMAT2, "Chan", "Extension", "Context", "Language", "MOH Interpret", "Blocked", "State");
14570
switch(filtertype) {
14571
case 1: /* dahdi show channels group <group> */
14572
if (!(tmp->group & targetnum)) {
14577
case 2: /* dahdi show channels context <context> */
14578
if (strcasecmp(tmp->context, a->argv[4])) {
14587
if (tmp->channel > 0) {
14588
snprintf(tmps, sizeof(tmps), "%d", tmp->channel);
14590
ast_copy_string(tmps, "pseudo", sizeof(tmps));
14592
if (tmp->locallyblocked)
14597
if (tmp->remotelyblocked)
14602
blockstr[2] = '\0';
14604
snprintf(statestr, sizeof(statestr), "%s", "In Service");
14606
ast_cli(a->fd, FORMAT, tmps, tmp->exten, tmp->context, tmp->language, tmp->mohinterpret, blockstr, statestr);
14609
ast_mutex_unlock(lock);
14610
return CLI_SUCCESS;
14615
static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14618
struct dahdi_pvt *tmp = NULL;
14619
struct dahdi_confinfo ci;
14620
struct dahdi_params ps;
14623
struct dahdi_pvt *start;
14627
struct dahdi_pri *pri=NULL;
14631
e->command = "dahdi show channel";
14633
"Usage: dahdi show channel <chan num>\n"
14634
" Detailed information about a given channel\n";
14644
return CLI_SHOWUSAGE;
14646
if ((c = strchr(a->argv[3], ':'))) {
14647
if (sscanf(a->argv[3], "%30d:%30d", &trunkgroup, &channel) != 2)
14648
return CLI_SHOWUSAGE;
14649
if ((trunkgroup < 1) || (channel < 1))
14650
return CLI_SHOWUSAGE;
14651
for (x = 0; x < NUM_SPANS; x++) {
14652
if (pris[x].trunkgroup == trunkgroup) {
14661
ast_cli(a->fd, "No such trunk group %d\n", trunkgroup);
14662
return CLI_FAILURE;
14666
channel = atoi(a->argv[3]);
14668
ast_mutex_lock(lock);
14671
if (tmp->channel == channel) {
14674
ast_cli(a->fd, "Trunk/CRV: %d/%d\n", trunkgroup, tmp->channel);
14677
ast_cli(a->fd, "Channel: %d\n", tmp->channel);
14678
ast_cli(a->fd, "File Descriptor: %d\n", tmp->subs[SUB_REAL].dfd);
14679
ast_cli(a->fd, "Span: %d\n", tmp->span);
14680
ast_cli(a->fd, "Extension: %s\n", tmp->exten);
14681
ast_cli(a->fd, "Dialing: %s\n", tmp->dialing ? "yes" : "no");
14682
ast_cli(a->fd, "Context: %s\n", tmp->context);
14683
ast_cli(a->fd, "Caller ID: %s\n", tmp->cid_num);
14684
ast_cli(a->fd, "Calling TON: %d\n", tmp->cid_ton);
14685
ast_cli(a->fd, "Caller ID name: %s\n", tmp->cid_name);
14686
ast_cli(a->fd, "Mailbox: %s\n", S_OR(tmp->mailbox, "none"));
14688
struct ast_variable *v;
14689
ast_cli(a->fd, "Variables:\n");
14690
for (v = tmp->vars ; v ; v = v->next)
14691
ast_cli(a->fd, " %s = %s\n", v->name, v->value);
14693
ast_cli(a->fd, "Destroy: %d\n", tmp->destroy);
14694
ast_cli(a->fd, "InAlarm: %d\n", tmp->inalarm);
14695
ast_cli(a->fd, "Signalling Type: %s\n", sig2str(tmp->sig));
14696
ast_cli(a->fd, "Radio: %d\n", tmp->radio);
14697
ast_cli(a->fd, "Owner: %s\n", tmp->owner ? tmp->owner->name : "<None>");
14698
ast_cli(a->fd, "Real: %s%s%s\n", tmp->subs[SUB_REAL].owner ? tmp->subs[SUB_REAL].owner->name : "<None>", tmp->subs[SUB_REAL].inthreeway ? " (Confed)" : "", tmp->subs[SUB_REAL].linear ? " (Linear)" : "");
14699
ast_cli(a->fd, "Callwait: %s%s%s\n", tmp->subs[SUB_CALLWAIT].owner ? tmp->subs[SUB_CALLWAIT].owner->name : "<None>", tmp->subs[SUB_CALLWAIT].inthreeway ? " (Confed)" : "", tmp->subs[SUB_CALLWAIT].linear ? " (Linear)" : "");
14700
ast_cli(a->fd, "Threeway: %s%s%s\n", tmp->subs[SUB_THREEWAY].owner ? tmp->subs[SUB_THREEWAY].owner->name : "<None>", tmp->subs[SUB_THREEWAY].inthreeway ? " (Confed)" : "", tmp->subs[SUB_THREEWAY].linear ? " (Linear)" : "");
14701
ast_cli(a->fd, "Confno: %d\n", tmp->confno);
14702
ast_cli(a->fd, "Propagated Conference: %d\n", tmp->propconfno);
14703
ast_cli(a->fd, "Real in conference: %d\n", tmp->inconference);
14704
ast_cli(a->fd, "DSP: %s\n", tmp->dsp ? "yes" : "no");
14705
ast_cli(a->fd, "Busy Detection: %s\n", tmp->busydetect ? "yes" : "no");
14706
if (tmp->busydetect) {
14707
#if defined(BUSYDETECT_TONEONLY)
14708
ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_TONEONLY\n");
14709
#elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
14710
ast_cli(a->fd, " Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
14712
#ifdef BUSYDETECT_DEBUG
14713
ast_cli(a->fd, " Busy Detector Debug: Enabled\n");
14715
ast_cli(a->fd, " Busy Count: %d\n", tmp->busycount);
14716
ast_cli(a->fd, " Busy Pattern: %d,%d\n", tmp->busy_tonelength, tmp->busy_quietlength);
14718
ast_cli(a->fd, "TDD: %s\n", tmp->tdd ? "yes" : "no");
14719
ast_cli(a->fd, "Relax DTMF: %s\n", tmp->dtmfrelax ? "yes" : "no");
14720
ast_cli(a->fd, "Dialing/CallwaitCAS: %d/%d\n", tmp->dialing, tmp->callwaitcas);
14721
ast_cli(a->fd, "Default law: %s\n", tmp->law == DAHDI_LAW_MULAW ? "ulaw" : tmp->law == DAHDI_LAW_ALAW ? "alaw" : "unknown");
14722
ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no");
14723
ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no");
14724
ast_cli(a->fd, "DND: %s\n", tmp->dnd ? "yes" : "no");
14725
ast_cli(a->fd, "Echo Cancellation:\n");
14727
if (tmp->echocancel.head.tap_length) {
14728
ast_cli(a->fd, "\t%d taps\n", tmp->echocancel.head.tap_length);
14729
for (x = 0; x < tmp->echocancel.head.param_count; x++) {
14730
ast_cli(a->fd, "\t\t%s: %ud\n", tmp->echocancel.params[x].name, tmp->echocancel.params[x].value);
14732
ast_cli(a->fd, "\t%scurrently %s\n", tmp->echocanbridged ? "" : "(unless TDM bridged) ", tmp->echocanon ? "ON" : "OFF");
14734
ast_cli(a->fd, "\tnone\n");
14736
ast_cli(a->fd, "Wait for dialtone: %dms\n", tmp->waitfordialtone);
14738
ast_cli(a->fd, "Master Channel: %d\n", tmp->master->channel);
14739
for (x = 0; x < MAX_SLAVES; x++) {
14740
if (tmp->slaves[x])
14741
ast_cli(a->fd, "Slave Channel: %d\n", tmp->slaves[x]->channel);
14745
char calldir[OR2_MAX_PATH];
14746
openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
14747
openr2_variant_t r2variant = openr2_context_get_variant(r2context);
14748
ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
14749
ast_cli(a->fd, "MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
14750
ast_cli(a->fd, "MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
14751
ast_cli(a->fd, "MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
14752
ast_cli(a->fd, "MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ? "Yes" : "No");
14753
ast_cli(a->fd, "MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
14754
ast_cli(a->fd, "MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
14755
ast_cli(a->fd, "MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
14756
ast_cli(a->fd, "MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ? "Yes" : "No");
14757
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
14758
ast_cli(a->fd, "MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ? "Yes" : "No");
14760
ast_cli(a->fd, "MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ? "Yes" : "No");
14761
ast_cli(a->fd, "MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ? "Yes" : "No");
14762
ast_cli(a->fd, "MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ? "Yes" : "No");
14763
ast_cli(a->fd, "MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ? "Yes" : "No");
14764
ast_cli(a->fd, "MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ? "Yes" : "No");
14765
ast_cli(a->fd, "MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
14766
ast_cli(a->fd, "MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
14767
ast_cli(a->fd, "MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
14768
ast_cli(a->fd, "MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
14769
ast_cli(a->fd, "MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
14770
ast_cli(a->fd, "MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
14771
ast_cli(a->fd, "MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir, sizeof(calldir)));
14776
ast_cli(a->fd, "CIC: %d\n", tmp->cic);
14781
ast_cli(a->fd, "PRI Flags: ");
14782
if (tmp->resetting)
14783
ast_cli(a->fd, "Resetting ");
14785
ast_cli(a->fd, "Call ");
14787
ast_cli(a->fd, "Bearer ");
14788
ast_cli(a->fd, "\n");
14789
if (tmp->logicalspan)
14790
ast_cli(a->fd, "PRI Logical Span: %d\n", tmp->logicalspan);
14792
ast_cli(a->fd, "PRI Logical Span: Implicit\n");
14795
memset(&ci, 0, sizeof(ci));
14796
ps.channo = tmp->channel;
14797
if (tmp->subs[SUB_REAL].dfd > -1) {
14798
memset(&ci, 0, sizeof(ci));
14799
if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONF, &ci)) {
14800
ast_cli(a->fd, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, ci.confmode);
14802
if (!ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GETCONFMUTE, &x)) {
14803
ast_cli(a->fd, "Actual Confmute: %s\n", x ? "Yes" : "No");
14805
memset(&ps, 0, sizeof(ps));
14806
if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &ps) < 0) {
14807
ast_log(LOG_WARNING, "Failed to get parameters on channel %d: %s\n", tmp->channel, strerror(errno));
14809
ast_cli(a->fd, "Hookstate (FXS only): %s\n", ps.rxisoffhook ? "Offhook" : "Onhook");
14812
ast_mutex_unlock(lock);
14813
return CLI_SUCCESS;
14818
ast_cli(a->fd, "Unable to find given channel %d\n", channel);
14819
ast_mutex_unlock(lock);
14820
return CLI_FAILURE;
14823
static char *handle_dahdi_show_cadences(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14828
e->command = "dahdi show cadences";
14830
"Usage: dahdi show cadences\n"
14831
" Shows all cadences currently defined\n";
14836
for (i = 0; i < num_cadence; i++) {
14838
char tmp[16], tmp2[64];
14839
snprintf(tmp, sizeof(tmp), "r%d: ", i + 1);
14840
term_color(output, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(output));
14842
for (j = 0; j < 16; j++) {
14843
if (cadences[i].ringcadence[j] == 0)
14845
snprintf(tmp, sizeof(tmp), "%d", cadences[i].ringcadence[j]);
14846
if (cidrings[i] * 2 - 1 == j)
14847
term_color(tmp2, tmp, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp2) - 1);
14849
term_color(tmp2, tmp, COLOR_GREEN, COLOR_BLACK, sizeof(tmp2) - 1);
14851
strncat(output, ",", sizeof(output) - strlen(output) - 1);
14852
strncat(output, tmp2, sizeof(output) - strlen(output) - 1);
14854
ast_cli(a->fd,"%s\n",output);
14856
return CLI_SUCCESS;
14859
/* Based on irqmiss.c */
14860
static char *dahdi_show_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14862
#define FORMAT "%-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
14863
#define FORMAT2 "%-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
14869
struct dahdi_spaninfo s;
14873
e->command = "dahdi show status";
14875
"Usage: dahdi show status\n"
14876
" Shows a list of DAHDI cards with status\n";
14881
ctl = open("/dev/dahdi/ctl", O_RDWR);
14883
ast_cli(a->fd, "No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
14884
return CLI_FAILURE;
14886
ast_cli(a->fd, FORMAT2, "Description", "Alarms", "IRQ", "bpviol", "CRC4", "Framing", "Coding", "Options", "LBO");
14888
for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
14890
res = ioctl(ctl, DAHDI_SPANSTAT, &s);
14894
alarmstr[0] = '\0';
14895
if (s.alarms > 0) {
14896
if (s.alarms & DAHDI_ALARM_BLUE)
14897
strcat(alarmstr, "BLU/");
14898
if (s.alarms & DAHDI_ALARM_YELLOW)
14899
strcat(alarmstr, "YEL/");
14900
if (s.alarms & DAHDI_ALARM_RED)
14901
strcat(alarmstr, "RED/");
14902
if (s.alarms & DAHDI_ALARM_LOOPBACK)
14903
strcat(alarmstr, "LB/");
14904
if (s.alarms & DAHDI_ALARM_RECOVER)
14905
strcat(alarmstr, "REC/");
14906
if (s.alarms & DAHDI_ALARM_NOTOPEN)
14907
strcat(alarmstr, "NOP/");
14908
if (!strlen(alarmstr))
14909
strcat(alarmstr, "UUU/");
14910
if (strlen(alarmstr)) {
14911
/* Strip trailing / */
14912
alarmstr[strlen(alarmstr) - 1] = '\0';
14916
strcpy(alarmstr, "OK");
14918
strcpy(alarmstr, "UNCONFIGURED");
14921
ast_cli(a->fd, FORMAT, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
14922
s.lineconfig & DAHDI_CONFIG_D4 ? "D4" :
14923
s.lineconfig & DAHDI_CONFIG_ESF ? "ESF" :
14924
s.lineconfig & DAHDI_CONFIG_CCS ? "CCS" :
14926
s.lineconfig & DAHDI_CONFIG_B8ZS ? "B8ZS" :
14927
s.lineconfig & DAHDI_CONFIG_HDB3 ? "HDB3" :
14928
s.lineconfig & DAHDI_CONFIG_AMI ? "AMI" :
14930
s.lineconfig & DAHDI_CONFIG_CRC4 ?
14931
s.lineconfig & DAHDI_CONFIG_NOTOPEN ? "CRC4/YEL" : "CRC4" : "YEL",
14937
return CLI_SUCCESS;
14942
static char *dahdi_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14944
int pseudo_fd = -1;
14945
struct dahdi_versioninfo vi;
14949
e->command = "dahdi show version";
14951
"Usage: dahdi show version\n"
14952
" Shows the DAHDI version in use\n";
14957
if ((pseudo_fd = open("/dev/dahdi/ctl", O_RDONLY)) < 0) {
14958
ast_cli(a->fd, "Failed to open control file to get version.\n");
14959
return CLI_SUCCESS;
14962
strcpy(vi.version, "Unknown");
14963
strcpy(vi.echo_canceller, "Unknown");
14965
if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
14966
ast_cli(a->fd, "Failed to get DAHDI version: %s\n", strerror(errno));
14968
ast_cli(a->fd, "DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
14972
return CLI_SUCCESS;
14975
static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
14980
struct dahdi_hwgain hwgain;
14981
struct dahdi_pvt *tmp = NULL;
14985
e->command = "dahdi set hwgain";
14987
"Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
14988
" Sets the hardware gain on a a given channel, overriding the\n"
14989
" value provided at module loadtime, whether the channel is in\n"
14990
" use or not. Changes take effect immediately.\n"
14991
" <rx|tx> which direction do you want to change (relative to our module)\n"
14992
" <chan num> is the channel number relative to the device\n"
14993
" <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
15000
return CLI_SHOWUSAGE;
15002
if (!strcasecmp("rx", a->argv[3]))
15004
else if (!strcasecmp("tx", a->argv[3]))
15007
return CLI_SHOWUSAGE;
15009
channel = atoi(a->argv[4]);
15010
gain = atof(a->argv[5])*10.0;
15012
ast_mutex_lock(&iflock);
15014
for (tmp = iflist; tmp; tmp = tmp->next) {
15016
if (tmp->channel != channel)
15019
if (tmp->subs[SUB_REAL].dfd == -1)
15022
hwgain.newgain = gain;
15024
if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) {
15025
ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno));
15026
ast_mutex_unlock(&iflock);
15027
return CLI_FAILURE;
15029
ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n",
15030
tx ? "tx" : "rx", gain, (float)gain/10.0, channel);
15034
ast_mutex_unlock(&iflock);
15037
return CLI_SUCCESS;
15039
ast_cli(a->fd, "Unable to find given channel %d\n", channel);
15040
return CLI_FAILURE;
15044
static char *dahdi_set_swgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15051
struct dahdi_pvt *tmp = NULL;
15055
e->command = "dahdi set swgain";
15057
"Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
15058
" Sets the software gain on a a given channel, overriding the\n"
15059
" value provided at module loadtime, whether the channel is in\n"
15060
" use or not. Changes take effect immediately.\n"
15061
" <rx|tx> which direction do you want to change (relative to our module)\n"
15062
" <chan num> is the channel number relative to the device\n"
15063
" <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
15072
return CLI_SHOWUSAGE;
15074
if (!strcasecmp("rx", a->argv[3]))
15076
else if (!strcasecmp("tx", a->argv[3]))
15079
return CLI_SHOWUSAGE;
15081
channel = atoi(a->argv[4]);
15082
gain = atof(a->argv[5]);
15084
ast_mutex_lock(lock);
15085
for (tmp = iflist; tmp; tmp = tmp->next) {
15087
if (tmp->channel != channel)
15090
if (tmp->subs[SUB_REAL].dfd == -1)
15094
res = set_actual_txgain(tmp->subs[SUB_REAL].dfd, channel, gain, tmp->law);
15096
res = set_actual_rxgain(tmp->subs[SUB_REAL].dfd, channel, gain, tmp->law);
15099
ast_cli(a->fd, "Unable to set the software gain for channel %d\n", channel);
15100
ast_mutex_unlock(lock);
15101
return CLI_FAILURE;
15104
ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n",
15105
tx ? "tx" : "rx", gain, channel);
15108
ast_mutex_unlock(lock);
15111
return CLI_SUCCESS;
15113
ast_cli(a->fd, "Unable to find given channel %d\n", channel);
15114
return CLI_FAILURE;
15118
static char *dahdi_set_dnd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15122
struct dahdi_pvt *dahdi_chan = NULL;
15126
e->command = "dahdi set dnd";
15128
"Usage: dahdi set dnd <chan#> <on|off>\n"
15129
" Sets/resets DND (Do Not Disturb) mode on a channel.\n"
15130
" Changes take effect immediately.\n"
15131
" <chan num> is the channel number\n"
15132
" <on|off> Enable or disable DND mode?\n"
15140
return CLI_SHOWUSAGE;
15142
if ((channel = atoi(a->argv[3])) <= 0) {
15143
ast_cli(a->fd, "Expected channel number, got '%s'\n", a->argv[3]);
15144
return CLI_SHOWUSAGE;
15147
if (ast_true(a->argv[4]))
15149
else if (ast_false(a->argv[4]))
15152
ast_cli(a->fd, "Expected 'on' or 'off', got '%s'\n", a->argv[4]);
15153
return CLI_SHOWUSAGE;
15156
ast_mutex_lock(&iflock);
15157
for (dahdi_chan = iflist; dahdi_chan; dahdi_chan = dahdi_chan->next) {
15158
if (dahdi_chan->channel != channel)
15161
/* Found the channel. Actually set it */
15162
dahdi_dnd(dahdi_chan, on);
15165
ast_mutex_unlock(&iflock);
15168
ast_cli(a->fd, "Unable to find given channel %d\n", channel);
15169
return CLI_FAILURE;
15172
return CLI_SUCCESS;
15175
static struct ast_cli_entry dahdi_cli[] = {
15176
AST_CLI_DEFINE(handle_dahdi_show_cadences, "List cadences"),
15177
AST_CLI_DEFINE(dahdi_show_channels, "Show active DAHDI channels"),
15178
AST_CLI_DEFINE(dahdi_show_channel, "Show information on a channel"),
15179
AST_CLI_DEFINE(dahdi_destroy_channel, "Destroy a channel"),
15180
AST_CLI_DEFINE(dahdi_restart_cmd, "Fully restart DAHDI channels"),
15181
AST_CLI_DEFINE(dahdi_show_status, "Show all DAHDI cards status"),
15182
AST_CLI_DEFINE(dahdi_show_version, "Show the DAHDI version in use"),
15183
AST_CLI_DEFINE(dahdi_set_hwgain, "Set hardware gain on a channel"),
15184
AST_CLI_DEFINE(dahdi_set_swgain, "Set software gain on a channel"),
15185
AST_CLI_DEFINE(dahdi_set_dnd, "Sets/resets DND (Do Not Disturb) mode on a channel"),
15191
static int dahdi_fake_event(struct dahdi_pvt *p, int mode)
15196
p->fake_event = DAHDI_EVENT_WINKFLASH;
15199
p->fake_event = DAHDI_EVENT_ONHOOK;
15202
ast_log(LOG_WARNING, "I don't know how to handle transfer event with this: %d on channel %s\n",mode, p->owner->name);
15207
static struct dahdi_pvt *find_channel(int channel)
15209
struct dahdi_pvt *p = iflist;
15211
if (p->channel == channel) {
15219
static int action_dahdidndon(struct mansession *s, const struct message *m)
15221
struct dahdi_pvt *p = NULL;
15222
const char *channel = astman_get_header(m, "DAHDIChannel");
15224
if (ast_strlen_zero(channel)) {
15225
astman_send_error(s, m, "No channel specified");
15228
p = find_channel(atoi(channel));
15230
astman_send_error(s, m, "No such channel");
15234
astman_send_ack(s, m, "DND Enabled");
15238
static int action_dahdidndoff(struct mansession *s, const struct message *m)
15240
struct dahdi_pvt *p = NULL;
15241
const char *channel = astman_get_header(m, "DAHDIChannel");
15243
if (ast_strlen_zero(channel)) {
15244
astman_send_error(s, m, "No channel specified");
15247
p = find_channel(atoi(channel));
15249
astman_send_error(s, m, "No such channel");
15253
astman_send_ack(s, m, "DND Disabled");
15257
static int action_transfer(struct mansession *s, const struct message *m)
15259
struct dahdi_pvt *p = NULL;
15260
const char *channel = astman_get_header(m, "DAHDIChannel");
15262
if (ast_strlen_zero(channel)) {
15263
astman_send_error(s, m, "No channel specified");
15266
p = find_channel(atoi(channel));
15268
astman_send_error(s, m, "No such channel");
15271
dahdi_fake_event(p,TRANSFER);
15272
astman_send_ack(s, m, "DAHDITransfer");
15276
static int action_transferhangup(struct mansession *s, const struct message *m)
15278
struct dahdi_pvt *p = NULL;
15279
const char *channel = astman_get_header(m, "DAHDIChannel");
15281
if (ast_strlen_zero(channel)) {
15282
astman_send_error(s, m, "No channel specified");
15285
p = find_channel(atoi(channel));
15287
astman_send_error(s, m, "No such channel");
15290
dahdi_fake_event(p,HANGUP);
15291
astman_send_ack(s, m, "DAHDIHangup");
15295
static int action_dahdidialoffhook(struct mansession *s, const struct message *m)
15297
struct dahdi_pvt *p = NULL;
15298
const char *channel = astman_get_header(m, "DAHDIChannel");
15299
const char *number = astman_get_header(m, "Number");
15302
if (ast_strlen_zero(channel)) {
15303
astman_send_error(s, m, "No channel specified");
15306
if (ast_strlen_zero(number)) {
15307
astman_send_error(s, m, "No number specified");
15310
p = find_channel(atoi(channel));
15312
astman_send_error(s, m, "No such channel");
15316
astman_send_error(s, m, "Channel does not have it's owner");
15319
for (i = 0; i < strlen(number); i++) {
15320
struct ast_frame f = { AST_FRAME_DTMF, number[i] };
15321
dahdi_queue_frame(p, &f, NULL);
15323
astman_send_ack(s, m, "DAHDIDialOffhook");
15327
static int action_dahdishowchannels(struct mansession *s, const struct message *m)
15329
struct dahdi_pvt *tmp = NULL;
15330
const char *id = astman_get_header(m, "ActionID");
15331
const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
15332
char idText[256] = "";
15334
int dahdichanquery = -1;
15335
if (!ast_strlen_zero(dahdichannel)) {
15336
dahdichanquery = atoi(dahdichannel);
15339
astman_send_ack(s, m, "DAHDI channel status will follow");
15340
if (!ast_strlen_zero(id))
15341
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
15343
ast_mutex_lock(&iflock);
15347
if (tmp->channel > 0) {
15348
int alm = get_alarms(tmp);
15350
/* If a specific channel is queried for, only deliver status for that channel */
15351
if (dahdichanquery > 0 && tmp->channel != dahdichanquery)
15356
/* Add data if we have a current call */
15358
"Event: DAHDIShowChannels\r\n"
15359
"DAHDIChannel: %d\r\n"
15362
"AccountCode: %s\r\n"
15363
"Signalling: %s\r\n"
15364
"SignallingCode: %d\r\n"
15372
tmp->owner->uniqueid,
15373
tmp->owner->accountcode,
15377
tmp->dnd ? "Enabled" : "Disabled",
15378
alarm2str(alm), idText);
15381
"Event: DAHDIShowChannels\r\n"
15382
"DAHDIChannel: %d\r\n"
15383
"Signalling: %s\r\n"
15384
"SignallingCode: %d\r\n"
15390
tmp->channel, sig2str(tmp->sig), tmp->sig,
15392
tmp->dnd ? "Enabled" : "Disabled",
15393
alarm2str(alm), idText);
15400
ast_mutex_unlock(&iflock);
15403
"Event: DAHDIShowChannelsComplete\r\n"
15412
#if defined(HAVE_SS7)
15413
static int linkset_addsigchan(int sigchan)
15415
struct dahdi_ss7 *link;
15418
struct dahdi_params p;
15419
struct dahdi_bufferinfo bi;
15420
struct dahdi_spaninfo si;
15423
link = ss7_resolve_linkset(cur_linkset);
15425
ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
15429
if (cur_ss7type < 0) {
15430
ast_log(LOG_ERROR, "Unspecified or invalid ss7type\n");
15435
link->ss7 = ss7_new(cur_ss7type);
15438
ast_log(LOG_ERROR, "Can't create new SS7!\n");
15442
link->type = cur_ss7type;
15444
if (cur_pointcode < 0) {
15445
ast_log(LOG_ERROR, "Unspecified pointcode!\n");
15448
ss7_set_pc(link->ss7, cur_pointcode);
15451
ast_log(LOG_ERROR, "Invalid sigchan!\n");
15454
if (link->numsigchans >= NUM_DCHANS) {
15455
ast_log(LOG_ERROR, "Too many sigchans on linkset %d\n", cur_linkset);
15458
curfd = link->numsigchans;
15460
link->fds[curfd] = open("/dev/dahdi/channel", O_RDWR, 0600);
15461
if ((link->fds[curfd] < 0) || (ioctl(link->fds[curfd],DAHDI_SPECIFY,&sigchan) == -1)) {
15462
ast_log(LOG_ERROR, "Unable to open SS7 sigchan %d (%s)\n", sigchan, strerror(errno));
15465
memset(&p, 0, sizeof(p));
15466
res = ioctl(link->fds[curfd], DAHDI_GET_PARAMS, &p);
15468
dahdi_close_ss7_fd(link, curfd);
15469
ast_log(LOG_ERROR, "Unable to get parameters for sigchan %d (%s)\n", sigchan, strerror(errno));
15472
if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC) && (p.sigtype != DAHDI_SIG_MTP2)) {
15473
dahdi_close_ss7_fd(link, curfd);
15474
ast_log(LOG_ERROR, "sigchan %d is not in HDLC/FCS mode.\n", sigchan);
15478
memset(&bi, 0, sizeof(bi));
15479
bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
15480
bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
15484
if (ioctl(link->fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
15485
ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", sigchan, strerror(errno));
15486
dahdi_close_ss7_fd(link, curfd);
15490
if (p.sigtype == DAHDI_SIG_MTP2)
15491
ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIMTP2, link->fds[curfd]);
15493
ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIDCHAN, link->fds[curfd]);
15495
link->numsigchans++;
15497
memset(&si, 0, sizeof(si));
15498
res = ioctl(link->fds[curfd], DAHDI_SPANSTAT, &si);
15500
dahdi_close_ss7_fd(link, curfd);
15501
ast_log(LOG_ERROR, "Unable to get span state for sigchan %d (%s)\n", sigchan, strerror(errno));
15505
link->linkstate[curfd] = LINKSTATE_DOWN;
15506
ss7_link_noalarm(link->ss7, link->fds[curfd]);
15508
link->linkstate[curfd] = LINKSTATE_DOWN | LINKSTATE_INALARM;
15509
ss7_link_alarm(link->ss7, link->fds[curfd]);
15513
if (cur_adjpointcode < 0) {
15514
ast_log(LOG_ERROR, "Unspecified adjpointcode!\n");
15517
ss7_set_adjpc(link->ss7, link->fds[curfd], cur_adjpointcode);
15520
if (cur_defaultdpc < 0) {
15521
ast_log(LOG_ERROR, "Unspecified defaultdpc!\n");
15525
if (cur_networkindicator < 0) {
15526
ast_log(LOG_ERROR, "Invalid networkindicator!\n");
15529
ss7_set_network_ind(link->ss7, cur_networkindicator);
15533
#endif /* defined(HAVE_SS7) */
15535
#if defined(HAVE_SS7)
15536
static char *handle_ss7_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15541
e->command = "ss7 set debug {on|off} linkset";
15543
"Usage: ss7 set debug {on|off} linkset <linkset>\n"
15544
" Enables debugging on a given SS7 linkset\n";
15550
return CLI_SHOWUSAGE;
15551
span = atoi(a->argv[5]);
15552
if ((span < 1) || (span > NUM_SPANS)) {
15553
ast_cli(a->fd, "Invalid linkset %s. Should be a number from %d to %d\n", a->argv[5], 1, NUM_SPANS);
15554
return CLI_SUCCESS;
15556
if (!linksets[span-1].ss7) {
15557
ast_cli(a->fd, "No SS7 running on linkset %d\n", span);
15558
return CLI_SUCCESS;
15560
if (linksets[span-1].ss7) {
15561
if (strcasecmp(a->argv[3], "on")) {
15562
ss7_set_debug(linksets[span-1].ss7, SS7_DEBUG_MTP2 | SS7_DEBUG_MTP3 | SS7_DEBUG_ISUP);
15563
ast_cli(a->fd, "Enabled debugging on linkset %d\n", span);
15565
ss7_set_debug(linksets[span-1].ss7, 0);
15566
ast_cli(a->fd, "Disabled debugging on linkset %d\n", span);
15570
return CLI_SUCCESS;
15572
#endif /* defined(HAVE_SS7) */
15574
#if defined(HAVE_SS7)
15575
static char *handle_ss7_block_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15578
int blocked = -1, i;
15581
e->command = "ss7 block cic";
15583
"Usage: ss7 block cic <linkset> <CIC>\n"
15584
" Sends a remote blocking request for the given CIC on the specified linkset\n";
15590
linkset = atoi(a->argv[3]);
15592
return CLI_SHOWUSAGE;
15594
if ((linkset < 1) || (linkset > NUM_SPANS)) {
15595
ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
15596
return CLI_SUCCESS;
15599
if (!linksets[linkset-1].ss7) {
15600
ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
15601
return CLI_SUCCESS;
15604
cic = atoi(a->argv[4]);
15607
ast_cli(a->fd, "Invalid CIC specified!\n");
15608
return CLI_SUCCESS;
15611
for (i = 0; i < linksets[linkset-1].numchans; i++) {
15612
if (linksets[linkset-1].pvts[i]->cic == cic) {
15613
blocked = linksets[linkset-1].pvts[i]->locallyblocked;
15615
ast_mutex_lock(&linksets[linkset-1].lock);
15616
isup_blo(linksets[linkset-1].ss7, cic, linksets[linkset-1].pvts[i]->dpc);
15617
ast_mutex_unlock(&linksets[linkset-1].lock);
15623
ast_cli(a->fd, "Invalid CIC specified!\n");
15624
return CLI_SUCCESS;
15628
ast_cli(a->fd, "Sent blocking request for linkset %d on CIC %d\n", linkset, cic);
15630
ast_cli(a->fd, "CIC %d already locally blocked\n", cic);
15632
/* Break poll on the linkset so it sends our messages */
15633
pthread_kill(linksets[linkset-1].master, SIGURG);
15635
return CLI_SUCCESS;
15637
#endif /* defined(HAVE_SS7) */
15639
#if defined(HAVE_SS7)
15640
static char *handle_ss7_block_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15646
e->command = "ss7 block linkset";
15648
"Usage: ss7 block linkset <linkset number>\n"
15649
" Sends a remote blocking request for all CICs on the given linkset\n";
15655
linkset = atoi(a->argv[3]);
15657
return CLI_SHOWUSAGE;
15659
if ((linkset < 1) || (linkset > NUM_SPANS)) {
15660
ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
15661
return CLI_SUCCESS;
15664
if (!linksets[linkset-1].ss7) {
15665
ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
15666
return CLI_SUCCESS;
15669
for (i = 0; i < linksets[linkset-1].numchans; i++) {
15670
ast_cli(a->fd, "Sending remote blocking request on CIC %d\n", linksets[linkset-1].pvts[i]->cic);
15671
ast_mutex_lock(&linksets[linkset-1].lock);
15672
isup_blo(linksets[linkset-1].ss7, linksets[linkset-1].pvts[i]->cic, linksets[linkset-1].pvts[i]->dpc);
15673
ast_mutex_unlock(&linksets[linkset-1].lock);
15676
/* Break poll on the linkset so it sends our messages */
15677
pthread_kill(linksets[linkset-1].master, SIGURG);
15679
return CLI_SUCCESS;
15681
#endif /* defined(HAVE_SS7) */
15683
#if defined(HAVE_SS7)
15684
static char *handle_ss7_unblock_cic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15687
int i, blocked = -1;
15690
e->command = "ss7 unblock cic";
15692
"Usage: ss7 unblock cic <linkset> <CIC>\n"
15693
" Sends a remote unblocking request for the given CIC on the specified linkset\n";
15700
linkset = atoi(a->argv[3]);
15702
return CLI_SHOWUSAGE;
15704
if ((linkset < 1) || (linkset > NUM_SPANS)) {
15705
ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
15706
return CLI_SUCCESS;
15709
if (!linksets[linkset-1].ss7) {
15710
ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
15711
return CLI_SUCCESS;
15714
cic = atoi(a->argv[4]);
15717
ast_cli(a->fd, "Invalid CIC specified!\n");
15718
return CLI_SUCCESS;
15721
for (i = 0; i < linksets[linkset-1].numchans; i++) {
15722
if (linksets[linkset-1].pvts[i]->cic == cic) {
15723
blocked = linksets[linkset-1].pvts[i]->locallyblocked;
15725
ast_mutex_lock(&linksets[linkset-1].lock);
15726
isup_ubl(linksets[linkset-1].ss7, cic, linksets[linkset-1].pvts[i]->dpc);
15727
ast_mutex_unlock(&linksets[linkset-1].lock);
15733
ast_cli(a->fd, "Sent unblocking request for linkset %d on CIC %d\n", linkset, cic);
15735
/* Break poll on the linkset so it sends our messages */
15736
pthread_kill(linksets[linkset-1].master, SIGURG);
15738
return CLI_SUCCESS;
15740
#endif /* defined(HAVE_SS7) */
15742
#if defined(HAVE_SS7)
15743
static char *handle_ss7_unblock_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15749
e->command = "ss7 unblock linkset";
15751
"Usage: ss7 unblock linkset <linkset number>\n"
15752
" Sends a remote unblocking request for all CICs on the specified linkset\n";
15759
linkset = atoi(a->argv[3]);
15761
return CLI_SHOWUSAGE;
15763
if ((linkset < 1) || (linkset > NUM_SPANS)) {
15764
ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
15765
return CLI_SUCCESS;
15768
if (!linksets[linkset-1].ss7) {
15769
ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
15770
return CLI_SUCCESS;
15773
for (i = 0; i < linksets[linkset-1].numchans; i++) {
15774
ast_cli(a->fd, "Sending remote unblock request on CIC %d\n", linksets[linkset-1].pvts[i]->cic);
15775
ast_mutex_lock(&linksets[linkset-1].lock);
15776
isup_ubl(linksets[linkset-1].ss7, linksets[linkset-1].pvts[i]->cic, linksets[linkset-1].pvts[i]->dpc);
15777
ast_mutex_unlock(&linksets[linkset-1].lock);
15780
/* Break poll on the linkset so it sends our messages */
15781
pthread_kill(linksets[linkset-1].master, SIGURG);
15783
return CLI_SUCCESS;
15785
#endif /* defined(HAVE_SS7) */
15787
#if defined(HAVE_SS7)
15788
static char *handle_ss7_show_linkset(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15791
struct dahdi_ss7 *ss7;
15794
e->command = "ss7 show linkset";
15796
"Usage: ss7 show linkset <span>\n"
15797
" Shows the status of an SS7 linkset.\n";
15804
return CLI_SHOWUSAGE;
15805
linkset = atoi(a->argv[3]);
15806
if ((linkset < 1) || (linkset > NUM_SPANS)) {
15807
ast_cli(a->fd, "Invalid linkset %s. Should be a number %d to %d\n", a->argv[3], 1, NUM_SPANS);
15808
return CLI_SUCCESS;
15810
if (!linksets[linkset-1].ss7) {
15811
ast_cli(a->fd, "No SS7 running on linkset %d\n", linkset);
15812
return CLI_SUCCESS;
15814
if (linksets[linkset-1].ss7)
15815
ss7 = &linksets[linkset-1];
15817
ast_cli(a->fd, "SS7 linkset %d status: %s\n", linkset, (ss7->state == LINKSET_STATE_UP) ? "Up" : "Down");
15819
return CLI_SUCCESS;
15821
#endif /* defined(HAVE_SS7) */
15823
#if defined(HAVE_SS7)
15824
static char *handle_ss7_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
15828
e->command = "ss7 show version";
15830
"Usage: ss7 show version\n"
15831
" Show the libss7 version\n";
15837
ast_cli(a->fd, "libss7 version: %s\n", ss7_get_version());
15839
return CLI_SUCCESS;
15841
#endif /* defined(HAVE_SS7) */
15843
#if defined(HAVE_SS7)
15844
static struct ast_cli_entry dahdi_ss7_cli[] = {
15845
AST_CLI_DEFINE(handle_ss7_debug, "Enables SS7 debugging on a linkset"),
15846
AST_CLI_DEFINE(handle_ss7_block_cic, "Blocks the given CIC"),
15847
AST_CLI_DEFINE(handle_ss7_unblock_cic, "Unblocks the given CIC"),
15848
AST_CLI_DEFINE(handle_ss7_block_linkset, "Blocks all CICs on a linkset"),
15849
AST_CLI_DEFINE(handle_ss7_unblock_linkset, "Unblocks all CICs on a linkset"),
15850
AST_CLI_DEFINE(handle_ss7_show_linkset, "Shows the status of a linkset"),
15851
AST_CLI_DEFINE(handle_ss7_version, "Displays libss7 version"),
15853
#endif /* defined(HAVE_SS7) */
15855
static int __unload_module(void)
15857
struct dahdi_pvt *p;
15858
#if defined(HAVE_PRI) || defined(HAVE_SS7)
15863
for (i = 0; i < NUM_SPANS; i++) {
15864
if (pris[i].master != AST_PTHREADT_NULL)
15865
pthread_cancel(pris[i].master);
15867
ast_cli_unregister_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
15868
ast_unregister_application(dahdi_send_keypad_facility_app);
15869
#ifdef HAVE_PRI_PROG_W_CAUSE
15870
ast_unregister_application(dahdi_send_callrerouting_facility_app);
15873
#if defined(HAVE_SS7)
15874
for (i = 0; i < NUM_SPANS; i++) {
15875
if (linksets[i].master != AST_PTHREADT_NULL)
15876
pthread_cancel(linksets[i].master);
15878
ast_cli_unregister_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
15880
#if defined(HAVE_OPENR2)
15881
dahdi_r2_destroy_links();
15882
ast_cli_unregister_multiple(dahdi_mfcr2_cli, ARRAY_LEN(dahdi_mfcr2_cli));
15883
ast_unregister_application(dahdi_accept_r2_call_app);
15886
ast_cli_unregister_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));
15887
ast_manager_unregister( "DAHDIDialOffhook" );
15888
ast_manager_unregister( "DAHDIHangup" );
15889
ast_manager_unregister( "DAHDITransfer" );
15890
ast_manager_unregister( "DAHDIDNDoff" );
15891
ast_manager_unregister( "DAHDIDNDon" );
15892
ast_manager_unregister("DAHDIShowChannels");
15893
ast_manager_unregister("DAHDIRestart");
15894
ast_channel_unregister(&dahdi_tech);
15895
ast_mutex_lock(&iflock);
15896
/* Hangup all interfaces if they have an owner */
15900
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
15903
ast_mutex_unlock(&iflock);
15904
ast_mutex_lock(&monlock);
15905
if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
15906
pthread_cancel(monitor_thread);
15907
pthread_kill(monitor_thread, SIGURG);
15908
pthread_join(monitor_thread, NULL);
15910
monitor_thread = AST_PTHREADT_STOP;
15911
ast_mutex_unlock(&monlock);
15913
destroy_all_channels();
15915
#if defined(HAVE_PRI)
15916
for (i = 0; i < NUM_SPANS; i++) {
15917
if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL))
15918
pthread_join(pris[i].master, NULL);
15919
for (j = 0; j < NUM_DCHANS; j++) {
15920
dahdi_close_pri_fd(&(pris[i]), j);
15925
#if defined(HAVE_SS7)
15926
for (i = 0; i < NUM_SPANS; i++) {
15927
if (linksets[i].master && (linksets[i].master != AST_PTHREADT_NULL))
15928
pthread_join(linksets[i].master, NULL);
15929
for (j = 0; j < NUM_DCHANS; j++) {
15930
dahdi_close_ss7_fd(&(linksets[i]), j);
15934
ast_cond_destroy(&ss_thread_complete);
15938
static int unload_module(void)
15940
#if defined(HAVE_PRI) || defined(HAVE_SS7)
15944
for (y = 0; y < NUM_SPANS; y++)
15945
ast_mutex_destroy(&pris[y].lock);
15948
for (y = 0; y < NUM_SPANS; y++)
15949
ast_mutex_destroy(&linksets[y].lock);
15950
#endif /* HAVE_SS7 */
15951
return __unload_module();
15954
static int build_channels(struct dahdi_chan_conf *conf, int iscrv, const char *value, int reload, int lineno, int *found_pseudo)
15957
int x, start, finish;
15958
struct dahdi_pvt *tmp;
15960
struct dahdi_pri *pri;
15964
if ((reload == 0) && (conf->chan.sig < 0) && !conf->is_sig_auto) {
15965
ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
15969
c = ast_strdupa(value);
15974
if (sscanf(c, "%30d:%n", &trunkgroup, &y) != 1) {
15975
ast_log(LOG_WARNING, "CRV must begin with trunkgroup followed by a colon at line %d.\n", lineno);
15978
if (trunkgroup < 1) {
15979
ast_log(LOG_WARNING, "CRV trunk group must be a positive number at line %d.\n", lineno);
15983
for (y = 0; y < NUM_SPANS; y++) {
15984
if (pris[y].trunkgroup == trunkgroup) {
15990
ast_log(LOG_WARNING, "No such trunk group %d at CRV declaration at line %d.\n", trunkgroup, lineno);
15996
while ((chan = strsep(&c, ","))) {
15997
if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
15999
} else if (sscanf(chan, "%30d", &start)) {
16002
} else if (!strcasecmp(chan, "pseudo")) {
16003
finish = start = CHAN_PSEUDO;
16007
ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", value, chan);
16010
if (finish < start) {
16011
ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
16017
for (x = start; x <= finish; x++) {
16019
tmp = mkintf(x, conf, pri, reload);
16021
tmp = mkintf(x, conf, NULL, reload);
16027
ast_verb(3, "%s CRV %d:%d, %s signalling\n", reload ? "Reconfigured" : "Registered", trunkgroup, x, sig2str(tmp->sig));
16030
ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
16032
ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
16033
(reload == 1) ? "reconfigure" : "register", value);
16042
/** The length of the parameters list of 'dahdichan'.
16043
* \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
16044
#define MAX_CHANLIST_LEN 80
16046
static void process_echocancel(struct dahdi_chan_conf *confp, const char *data, unsigned int line)
16048
char *parse = ast_strdupa(data);
16049
char *params[DAHDI_MAX_ECHOCANPARAMS + 1];
16050
unsigned int param_count;
16053
if (!(param_count = ast_app_separate_args(parse, ',', params, ARRAY_LEN(params))))
16056
memset(&confp->chan.echocancel, 0, sizeof(confp->chan.echocancel));
16058
/* first parameter is tap length, process it here */
16060
x = ast_strlen_zero(params[0]) ? 0 : atoi(params[0]);
16062
if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
16063
confp->chan.echocancel.head.tap_length = x;
16064
else if ((confp->chan.echocancel.head.tap_length = ast_true(params[0])))
16065
confp->chan.echocancel.head.tap_length = 128;
16067
/* now process any remaining parameters */
16069
for (x = 1; x < param_count; x++) {
16075
if (ast_app_separate_args(params[x], '=', (char **) ¶m, 2) < 1) {
16076
ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, params[x]);
16080
if (ast_strlen_zero(param.name) || (strlen(param.name) > sizeof(confp->chan.echocancel.params[0].name)-1)) {
16081
ast_log(LOG_WARNING, "Invalid echocancel parameter supplied at line %d: '%s'\n", line, param.name);
16085
strcpy(confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].name, param.name);
16088
if (sscanf(param.value, "%30d", &confp->chan.echocancel.params[confp->chan.echocancel.head.param_count].value) != 1) {
16089
ast_log(LOG_WARNING, "Invalid echocancel parameter value supplied at line %d: '%s'\n", line, param.value);
16093
confp->chan.echocancel.head.param_count++;
16097
/*! process_dahdi() - ignore keyword 'channel' and similar */
16098
#define PROC_DAHDI_OPT_NOCHAN (1 << 0)
16099
/*! process_dahdi() - No warnings on non-existing cofiguration keywords */
16100
#define PROC_DAHDI_OPT_NOWARN (1 << 1)
16102
static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct ast_variable *v, int reload, int options)
16104
struct dahdi_pvt *tmp;
16106
int found_pseudo = 0;
16107
char dahdichan[MAX_CHANLIST_LEN] = {};
16109
for (; v; v = v->next) {
16110
if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
16113
/* must have parkinglot in confp before build_channels is called */
16114
if (!strcasecmp(v->name, "parkinglot")) {
16115
ast_copy_string(confp->chan.parkinglot, v->value, sizeof(confp->chan.parkinglot));
16118
/* Create the interface list */
16119
if (!strcasecmp(v->name, "channel")
16121
|| !strcasecmp(v->name, "crv")
16125
if (options & PROC_DAHDI_OPT_NOCHAN) {
16126
ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value);
16129
iscrv = !strcasecmp(v->name, "crv");
16130
if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo))
16132
ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value);
16133
} else if (!strcasecmp(v->name, "buffers")) {
16135
char policy[21] = "";
16137
res = sscanf(v->value, "%30d,%20s", &confp->chan.buf_no, policy);
16139
ast_log(LOG_WARNING, "Parsing buffers option data failed, using defaults.\n");
16140
confp->chan.buf_no = numbufs;
16143
if (confp->chan.buf_no < 0)
16144
confp->chan.buf_no = numbufs;
16145
if (!strcasecmp(policy, "full")) {
16146
confp->chan.buf_policy = DAHDI_POLICY_WHEN_FULL;
16147
} else if (!strcasecmp(policy, "immediate")) {
16148
confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
16149
#ifdef HAVE_DAHDI_HALF_FULL
16150
} else if (!strcasecmp(policy, "half_full")) {
16151
confp->chan.buf_policy = DAHDI_POLICY_HALF_FULL;
16154
ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16156
} else if (!strcasecmp(v->name, "faxbuffers")) {
16158
char policy[21] = "";
16160
res = sscanf(v->value, "%30d,%20s", &confp->chan.faxbuf_no, policy);
16162
ast_log(LOG_WARNING, "Parsing faxbuffers option data failed, using defaults.\n");
16163
confp->chan.faxbuf_no = numbufs;
16166
confp->chan.usefaxbuffers = 1;
16167
if (confp->chan.faxbuf_no < 0)
16168
confp->chan.faxbuf_no = numbufs;
16169
if (!strcasecmp(policy, "full")) {
16170
confp->chan.faxbuf_policy = DAHDI_POLICY_WHEN_FULL;
16171
} else if (!strcasecmp(policy, "immediate")) {
16172
confp->chan.faxbuf_policy = DAHDI_POLICY_IMMEDIATE;
16174
ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16175
confp->chan.usefaxbuffers = 0;
16177
} else if (!strcasecmp(v->name, "dahdichan")) {
16178
ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
16179
} else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
16180
usedistinctiveringdetection = ast_true(v->value);
16181
} else if (!strcasecmp(v->name, "distinctiveringaftercid")) {
16182
distinctiveringaftercid = ast_true(v->value);
16183
} else if (!strcasecmp(v->name, "dring1context")) {
16184
ast_copy_string(confp->chan.drings.ringContext[0].contextData,v->value,sizeof(confp->chan.drings.ringContext[0].contextData));
16185
} else if (!strcasecmp(v->name, "dring2context")) {
16186
ast_copy_string(confp->chan.drings.ringContext[1].contextData,v->value,sizeof(confp->chan.drings.ringContext[1].contextData));
16187
} else if (!strcasecmp(v->name, "dring3context")) {
16188
ast_copy_string(confp->chan.drings.ringContext[2].contextData,v->value,sizeof(confp->chan.drings.ringContext[2].contextData));
16189
} else if (!strcasecmp(v->name, "dring1range")) {
16190
confp->chan.drings.ringnum[0].range = atoi(v->value);
16191
} else if (!strcasecmp(v->name, "dring2range")) {
16192
confp->chan.drings.ringnum[1].range = atoi(v->value);
16193
} else if (!strcasecmp(v->name, "dring3range")) {
16194
confp->chan.drings.ringnum[2].range = atoi(v->value);
16195
} else if (!strcasecmp(v->name, "dring1")) {
16196
sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[0].ring[0], &confp->chan.drings.ringnum[0].ring[1], &confp->chan.drings.ringnum[0].ring[2]);
16197
} else if (!strcasecmp(v->name, "dring2")) {
16198
sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[1].ring[0], &confp->chan.drings.ringnum[1].ring[1], &confp->chan.drings.ringnum[1].ring[2]);
16199
} else if (!strcasecmp(v->name, "dring3")) {
16200
sscanf(v->value, "%30d,%30d,%30d", &confp->chan.drings.ringnum[2].ring[0], &confp->chan.drings.ringnum[2].ring[1], &confp->chan.drings.ringnum[2].ring[2]);
16201
} else if (!strcasecmp(v->name, "usecallerid")) {
16202
confp->chan.use_callerid = ast_true(v->value);
16203
} else if (!strcasecmp(v->name, "cidsignalling")) {
16204
if (!strcasecmp(v->value, "bell"))
16205
confp->chan.cid_signalling = CID_SIG_BELL;
16206
else if (!strcasecmp(v->value, "v23"))
16207
confp->chan.cid_signalling = CID_SIG_V23;
16208
else if (!strcasecmp(v->value, "dtmf"))
16209
confp->chan.cid_signalling = CID_SIG_DTMF;
16210
else if (!strcasecmp(v->value, "smdi"))
16211
confp->chan.cid_signalling = CID_SIG_SMDI;
16212
else if (!strcasecmp(v->value, "v23_jp"))
16213
confp->chan.cid_signalling = CID_SIG_V23_JP;
16214
else if (ast_true(v->value))
16215
confp->chan.cid_signalling = CID_SIG_BELL;
16216
} else if (!strcasecmp(v->name, "cidstart")) {
16217
if (!strcasecmp(v->value, "ring"))
16218
confp->chan.cid_start = CID_START_RING;
16219
else if (!strcasecmp(v->value, "polarity_in"))
16220
confp->chan.cid_start = CID_START_POLARITY_IN;
16221
else if (!strcasecmp(v->value, "polarity"))
16222
confp->chan.cid_start = CID_START_POLARITY;
16223
else if (ast_true(v->value))
16224
confp->chan.cid_start = CID_START_RING;
16225
} else if (!strcasecmp(v->name, "threewaycalling")) {
16226
confp->chan.threewaycalling = ast_true(v->value);
16227
} else if (!strcasecmp(v->name, "cancallforward")) {
16228
confp->chan.cancallforward = ast_true(v->value);
16229
} else if (!strcasecmp(v->name, "relaxdtmf")) {
16230
if (ast_true(v->value))
16231
confp->chan.dtmfrelax = DSP_DIGITMODE_RELAXDTMF;
16233
confp->chan.dtmfrelax = 0;
16234
} else if (!strcasecmp(v->name, "mailbox")) {
16235
ast_copy_string(confp->chan.mailbox, v->value, sizeof(confp->chan.mailbox));
16236
} else if (!strcasecmp(v->name, "hasvoicemail")) {
16237
if (ast_true(v->value) && ast_strlen_zero(confp->chan.mailbox)) {
16238
ast_copy_string(confp->chan.mailbox, cat, sizeof(confp->chan.mailbox));
16240
} else if (!strcasecmp(v->name, "adsi")) {
16241
confp->chan.adsi = ast_true(v->value);
16242
} else if (!strcasecmp(v->name, "usesmdi")) {
16243
confp->chan.use_smdi = ast_true(v->value);
16244
} else if (!strcasecmp(v->name, "smdiport")) {
16245
ast_copy_string(confp->smdi_port, v->value, sizeof(confp->smdi_port));
16246
} else if (!strcasecmp(v->name, "transfer")) {
16247
confp->chan.transfer = ast_true(v->value);
16248
} else if (!strcasecmp(v->name, "canpark")) {
16249
confp->chan.canpark = ast_true(v->value);
16250
} else if (!strcasecmp(v->name, "echocancelwhenbridged")) {
16251
confp->chan.echocanbridged = ast_true(v->value);
16252
} else if (!strcasecmp(v->name, "busydetect")) {
16253
confp->chan.busydetect = ast_true(v->value);
16254
} else if (!strcasecmp(v->name, "busycount")) {
16255
confp->chan.busycount = atoi(v->value);
16256
} else if (!strcasecmp(v->name, "busypattern")) {
16257
if (sscanf(v->value, "%30d,%30d", &confp->chan.busy_tonelength, &confp->chan.busy_quietlength) != 2) {
16258
ast_log(LOG_ERROR, "busypattern= expects busypattern=tonelength,quietlength at line %d.\n", v->lineno);
16260
} else if (!strcasecmp(v->name, "callprogress")) {
16261
confp->chan.callprogress &= ~CALLPROGRESS_PROGRESS;
16262
if (ast_true(v->value))
16263
confp->chan.callprogress |= CALLPROGRESS_PROGRESS;
16264
} else if (!strcasecmp(v->name, "waitfordialtone")) {
16265
confp->chan.waitfordialtone = atoi(v->value);
16266
} else if (!strcasecmp(v->name, "faxdetect")) {
16267
confp->chan.callprogress &= ~CALLPROGRESS_FAX;
16268
if (!strcasecmp(v->value, "incoming")) {
16269
confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING;
16270
} else if (!strcasecmp(v->value, "outgoing")) {
16271
confp->chan.callprogress |= CALLPROGRESS_FAX_OUTGOING;
16272
} else if (!strcasecmp(v->value, "both") || ast_true(v->value))
16273
confp->chan.callprogress |= CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING;
16274
} else if (!strcasecmp(v->name, "echocancel")) {
16275
process_echocancel(confp, v->value, v->lineno);
16276
} else if (!strcasecmp(v->name, "echotraining")) {
16277
if (sscanf(v->value, "%30d", &y) == 1) {
16278
if ((y < 10) || (y > 4000)) {
16279
ast_log(LOG_WARNING, "Echo training time must be within the range of 10 to 4000 ms at line %d.\n", v->lineno);
16281
confp->chan.echotraining = y;
16283
} else if (ast_true(v->value)) {
16284
confp->chan.echotraining = 400;
16286
confp->chan.echotraining = 0;
16287
} else if (!strcasecmp(v->name, "hidecallerid")) {
16288
confp->chan.hidecallerid = ast_true(v->value);
16289
} else if (!strcasecmp(v->name, "hidecalleridname")) {
16290
confp->chan.hidecalleridname = ast_true(v->value);
16291
} else if (!strcasecmp(v->name, "pulsedial")) {
16292
confp->chan.pulse = ast_true(v->value);
16293
} else if (!strcasecmp(v->name, "callreturn")) {
16294
confp->chan.callreturn = ast_true(v->value);
16295
} else if (!strcasecmp(v->name, "callwaiting")) {
16296
confp->chan.callwaiting = ast_true(v->value);
16297
} else if (!strcasecmp(v->name, "callwaitingcallerid")) {
16298
confp->chan.callwaitingcallerid = ast_true(v->value);
16299
} else if (!strcasecmp(v->name, "context")) {
16300
ast_copy_string(confp->chan.context, v->value, sizeof(confp->chan.context));
16301
} else if (!strcasecmp(v->name, "language")) {
16302
ast_copy_string(confp->chan.language, v->value, sizeof(confp->chan.language));
16303
} else if (!strcasecmp(v->name, "progzone")) {
16304
ast_copy_string(progzone, v->value, sizeof(progzone));
16305
} else if (!strcasecmp(v->name, "mohinterpret")
16306
||!strcasecmp(v->name, "musiconhold") || !strcasecmp(v->name, "musicclass")) {
16307
ast_copy_string(confp->chan.mohinterpret, v->value, sizeof(confp->chan.mohinterpret));
16308
} else if (!strcasecmp(v->name, "mohsuggest")) {
16309
ast_copy_string(confp->chan.mohsuggest, v->value, sizeof(confp->chan.mohsuggest));
16310
} else if (!strcasecmp(v->name, "parkinglot")) {
16311
ast_copy_string(parkinglot, v->value, sizeof(parkinglot));
16312
} else if (!strcasecmp(v->name, "stripmsd")) {
16313
ast_log(LOG_NOTICE, "Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->name);
16314
confp->chan.stripmsd = atoi(v->value);
16315
} else if (!strcasecmp(v->name, "jitterbuffers")) {
16316
numbufs = atoi(v->value);
16317
} else if (!strcasecmp(v->name, "group")) {
16318
confp->chan.group = ast_get_group(v->value);
16319
} else if (!strcasecmp(v->name, "callgroup")) {
16320
if (!strcasecmp(v->value, "none"))
16321
confp->chan.callgroup = 0;
16323
confp->chan.callgroup = ast_get_group(v->value);
16324
} else if (!strcasecmp(v->name, "pickupgroup")) {
16325
if (!strcasecmp(v->value, "none"))
16326
confp->chan.pickupgroup = 0;
16328
confp->chan.pickupgroup = ast_get_group(v->value);
16329
} else if (!strcasecmp(v->name, "setvar")) {
16330
char *varname = ast_strdupa(v->value), *varval = NULL;
16331
struct ast_variable *tmpvar;
16332
if (varname && (varval = strchr(varname, '='))) {
16334
if ((tmpvar = ast_variable_new(varname, varval, ""))) {
16335
tmpvar->next = confp->chan.vars;
16336
confp->chan.vars = tmpvar;
16339
} else if (!strcasecmp(v->name, "immediate")) {
16340
confp->chan.immediate = ast_true(v->value);
16341
} else if (!strcasecmp(v->name, "transfertobusy")) {
16342
confp->chan.transfertobusy = ast_true(v->value);
16343
} else if (!strcasecmp(v->name, "mwimonitor")) {
16344
confp->chan.mwimonitor_neon = 0;
16345
confp->chan.mwimonitor_fsk = 0;
16346
confp->chan.mwimonitor_rpas = 0;
16347
if (strcasestr(v->value, "fsk")) {
16348
confp->chan.mwimonitor_fsk = 1;
16350
if (strcasestr(v->value, "rpas")) {
16351
confp->chan.mwimonitor_rpas = 1;
16353
if (strcasestr(v->value, "neon")) {
16354
confp->chan.mwimonitor_neon = 1;
16356
/* If set to true or yes, assume that simple fsk is desired */
16357
if (ast_true(v->value)) {
16358
confp->chan.mwimonitor_fsk = 1;
16360
} else if (!strcasecmp(v->name, "cid_rxgain")) {
16361
if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) {
16362
ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno);
16364
} else if (!strcasecmp(v->name, "rxgain")) {
16365
if (sscanf(v->value, "%30f", &confp->chan.rxgain) != 1) {
16366
ast_log(LOG_WARNING, "Invalid rxgain: %s at line %d.\n", v->value, v->lineno);
16368
} else if (!strcasecmp(v->name, "txgain")) {
16369
if (sscanf(v->value, "%30f", &confp->chan.txgain) != 1) {
16370
ast_log(LOG_WARNING, "Invalid txgain: %s at line %d.\n", v->value, v->lineno);
16372
} else if (!strcasecmp(v->name, "tonezone")) {
16373
if (sscanf(v->value, "%30d", &confp->chan.tonezone) != 1) {
16374
ast_log(LOG_WARNING, "Invalid tonezone: %s at line %d.\n", v->value, v->lineno);
16376
} else if (!strcasecmp(v->name, "callerid")) {
16377
if (!strcasecmp(v->value, "asreceived")) {
16378
confp->chan.cid_num[0] = '\0';
16379
confp->chan.cid_name[0] = '\0';
16381
ast_callerid_split(v->value, confp->chan.cid_name, sizeof(confp->chan.cid_name), confp->chan.cid_num, sizeof(confp->chan.cid_num));
16383
} else if (!strcasecmp(v->name, "fullname")) {
16384
ast_copy_string(confp->chan.cid_name, v->value, sizeof(confp->chan.cid_name));
16385
} else if (!strcasecmp(v->name, "cid_number")) {
16386
ast_copy_string(confp->chan.cid_num, v->value, sizeof(confp->chan.cid_num));
16387
} else if (!strcasecmp(v->name, "useincomingcalleridondahditransfer")) {
16388
confp->chan.dahditrcallerid = ast_true(v->value);
16389
} else if (!strcasecmp(v->name, "restrictcid")) {
16390
confp->chan.restrictcid = ast_true(v->value);
16391
} else if (!strcasecmp(v->name, "usecallingpres")) {
16392
confp->chan.use_callingpres = ast_true(v->value);
16393
} else if (!strcasecmp(v->name, "accountcode")) {
16394
ast_copy_string(confp->chan.accountcode, v->value, sizeof(confp->chan.accountcode));
16395
} else if (!strcasecmp(v->name, "amaflags")) {
16396
y = ast_cdr_amaflags2int(v->value);
16398
ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d.\n", v->value, v->lineno);
16400
confp->chan.amaflags = y;
16401
} else if (!strcasecmp(v->name, "polarityonanswerdelay")) {
16402
confp->chan.polarityonanswerdelay = atoi(v->value);
16403
} else if (!strcasecmp(v->name, "answeronpolarityswitch")) {
16404
confp->chan.answeronpolarityswitch = ast_true(v->value);
16405
} else if (!strcasecmp(v->name, "hanguponpolarityswitch")) {
16406
confp->chan.hanguponpolarityswitch = ast_true(v->value);
16407
} else if (!strcasecmp(v->name, "sendcalleridafter")) {
16408
confp->chan.sendcalleridafter = atoi(v->value);
16409
} else if (!strcasecmp(v->name, "mwimonitornotify")) {
16410
ast_copy_string(mwimonitornotify, v->value, sizeof(mwimonitornotify));
16411
} else if (!strcasecmp(v->name, "mwisendtype")) {
16412
#ifndef HAVE_DAHDI_LINEREVERSE_VMWI /* backward compatibility for older dahdi VMWI implementation */
16413
if (!strcasecmp(v->value, "rpas")) { /* Ring Pulse Alert Signal */
16419
/* Default is fsk, to turn it off you must specify nofsk */
16420
memset(&confp->chan.mwisend_setting, 0, sizeof(confp->chan.mwisend_setting));
16421
if (strcasestr(v->value, "nofsk")) { /* NoFSK */
16422
confp->chan.mwisend_fsk = 0;
16423
} else { /* Default FSK */
16424
confp->chan.mwisend_fsk = 1;
16426
if (strcasestr(v->value, "rpas")) { /* Ring Pulse Alert Signal, normally followed by FSK */
16427
confp->chan.mwisend_rpas = 1;
16429
confp->chan.mwisend_rpas = 0;
16431
if (strcasestr(v->value, "lrev")) { /* Line Reversal */
16432
confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
16434
if (strcasestr(v->value, "hvdc")) { /* HV 90VDC */
16435
confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
16437
if ( (strcasestr(v->value, "neon")) || (strcasestr(v->value, "hvac")) ){ /* 90V DC pulses */
16438
confp->chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
16441
} else if (reload != 1) {
16442
if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
16443
int orig_radio = confp->chan.radio;
16444
int orig_outsigmod = confp->chan.outsigmod;
16445
int orig_auto = confp->is_sig_auto;
16447
confp->chan.radio = 0;
16448
confp->chan.outsigmod = -1;
16449
confp->is_sig_auto = 0;
16450
if (!strcasecmp(v->value, "em")) {
16451
confp->chan.sig = SIG_EM;
16452
} else if (!strcasecmp(v->value, "em_e1")) {
16453
confp->chan.sig = SIG_EM_E1;
16454
} else if (!strcasecmp(v->value, "em_w")) {
16455
confp->chan.sig = SIG_EMWINK;
16456
} else if (!strcasecmp(v->value, "fxs_ls")) {
16457
confp->chan.sig = SIG_FXSLS;
16458
} else if (!strcasecmp(v->value, "fxs_gs")) {
16459
confp->chan.sig = SIG_FXSGS;
16460
} else if (!strcasecmp(v->value, "fxs_ks")) {
16461
confp->chan.sig = SIG_FXSKS;
16462
} else if (!strcasecmp(v->value, "fxo_ls")) {
16463
confp->chan.sig = SIG_FXOLS;
16464
} else if (!strcasecmp(v->value, "fxo_gs")) {
16465
confp->chan.sig = SIG_FXOGS;
16466
} else if (!strcasecmp(v->value, "fxo_ks")) {
16467
confp->chan.sig = SIG_FXOKS;
16468
} else if (!strcasecmp(v->value, "fxs_rx")) {
16469
confp->chan.sig = SIG_FXSKS;
16470
confp->chan.radio = 1;
16471
} else if (!strcasecmp(v->value, "fxo_rx")) {
16472
confp->chan.sig = SIG_FXOLS;
16473
confp->chan.radio = 1;
16474
} else if (!strcasecmp(v->value, "fxs_tx")) {
16475
confp->chan.sig = SIG_FXSLS;
16476
confp->chan.radio = 1;
16477
} else if (!strcasecmp(v->value, "fxo_tx")) {
16478
confp->chan.sig = SIG_FXOGS;
16479
confp->chan.radio = 1;
16480
} else if (!strcasecmp(v->value, "em_rx")) {
16481
confp->chan.sig = SIG_EM;
16482
confp->chan.radio = 1;
16483
} else if (!strcasecmp(v->value, "em_tx")) {
16484
confp->chan.sig = SIG_EM;
16485
confp->chan.radio = 1;
16486
} else if (!strcasecmp(v->value, "em_rxtx")) {
16487
confp->chan.sig = SIG_EM;
16488
confp->chan.radio = 2;
16489
} else if (!strcasecmp(v->value, "em_txrx")) {
16490
confp->chan.sig = SIG_EM;
16491
confp->chan.radio = 2;
16492
} else if (!strcasecmp(v->value, "sf")) {
16493
confp->chan.sig = SIG_SF;
16494
} else if (!strcasecmp(v->value, "sf_w")) {
16495
confp->chan.sig = SIG_SFWINK;
16496
} else if (!strcasecmp(v->value, "sf_featd")) {
16497
confp->chan.sig = SIG_FEATD;
16498
} else if (!strcasecmp(v->value, "sf_featdmf")) {
16499
confp->chan.sig = SIG_FEATDMF;
16500
} else if (!strcasecmp(v->value, "sf_featb")) {
16501
confp->chan.sig = SIG_SF_FEATB;
16502
} else if (!strcasecmp(v->value, "sf")) {
16503
confp->chan.sig = SIG_SF;
16504
} else if (!strcasecmp(v->value, "sf_rx")) {
16505
confp->chan.sig = SIG_SF;
16506
confp->chan.radio = 1;
16507
} else if (!strcasecmp(v->value, "sf_tx")) {
16508
confp->chan.sig = SIG_SF;
16509
confp->chan.radio = 1;
16510
} else if (!strcasecmp(v->value, "sf_rxtx")) {
16511
confp->chan.sig = SIG_SF;
16512
confp->chan.radio = 2;
16513
} else if (!strcasecmp(v->value, "sf_txrx")) {
16514
confp->chan.sig = SIG_SF;
16515
confp->chan.radio = 2;
16516
} else if (!strcasecmp(v->value, "featd")) {
16517
confp->chan.sig = SIG_FEATD;
16518
} else if (!strcasecmp(v->value, "featdmf")) {
16519
confp->chan.sig = SIG_FEATDMF;
16520
} else if (!strcasecmp(v->value, "featdmf_ta")) {
16521
confp->chan.sig = SIG_FEATDMF_TA;
16522
} else if (!strcasecmp(v->value, "e911")) {
16523
confp->chan.sig = SIG_E911;
16524
} else if (!strcasecmp(v->value, "fgccama")) {
16525
confp->chan.sig = SIG_FGC_CAMA;
16526
} else if (!strcasecmp(v->value, "fgccamamf")) {
16527
confp->chan.sig = SIG_FGC_CAMAMF;
16528
} else if (!strcasecmp(v->value, "featb")) {
16529
confp->chan.sig = SIG_FEATB;
16531
} else if (!strcasecmp(v->value, "pri_net")) {
16532
confp->chan.sig = SIG_PRI;
16533
confp->pri.nodetype = PRI_NETWORK;
16534
} else if (!strcasecmp(v->value, "pri_cpe")) {
16535
confp->chan.sig = SIG_PRI;
16536
confp->pri.nodetype = PRI_CPE;
16537
} else if (!strcasecmp(v->value, "bri_cpe")) {
16538
confp->chan.sig = SIG_BRI;
16539
confp->pri.nodetype = PRI_CPE;
16540
} else if (!strcasecmp(v->value, "bri_net")) {
16541
confp->chan.sig = SIG_BRI;
16542
confp->pri.nodetype = PRI_NETWORK;
16543
} else if (!strcasecmp(v->value, "bri_cpe_ptmp")) {
16544
confp->chan.sig = SIG_BRI_PTMP;
16545
confp->pri.nodetype = PRI_CPE;
16546
} else if (!strcasecmp(v->value, "bri_net_ptmp")) {
16547
confp->chan.sig = SIG_BRI_PTMP;
16548
confp->pri.nodetype = PRI_NETWORK;
16549
} else if (!strcasecmp(v->value, "gr303fxoks_net")) {
16550
confp->chan.sig = SIG_GR303FXOKS;
16551
confp->pri.nodetype = PRI_NETWORK;
16552
} else if (!strcasecmp(v->value, "gr303fxsks_cpe")) {
16553
confp->chan.sig = SIG_GR303FXSKS;
16554
confp->pri.nodetype = PRI_CPE;
16557
} else if (!strcasecmp(v->value, "ss7")) {
16558
confp->chan.sig = SIG_SS7;
16561
} else if (!strcasecmp(v->value, "mfcr2")) {
16562
confp->chan.sig = SIG_MFCR2;
16564
} else if (!strcasecmp(v->value, "auto")) {
16565
confp->is_sig_auto = 1;
16567
confp->chan.outsigmod = orig_outsigmod;
16568
confp->chan.radio = orig_radio;
16569
confp->is_sig_auto = orig_auto;
16570
ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
16572
} else if (!strcasecmp(v->name, "outsignalling") || !strcasecmp(v->name, "outsignaling")) {
16573
if (!strcasecmp(v->value, "em")) {
16574
confp->chan.outsigmod = SIG_EM;
16575
} else if (!strcasecmp(v->value, "em_e1")) {
16576
confp->chan.outsigmod = SIG_EM_E1;
16577
} else if (!strcasecmp(v->value, "em_w")) {
16578
confp->chan.outsigmod = SIG_EMWINK;
16579
} else if (!strcasecmp(v->value, "sf")) {
16580
confp->chan.outsigmod = SIG_SF;
16581
} else if (!strcasecmp(v->value, "sf_w")) {
16582
confp->chan.outsigmod = SIG_SFWINK;
16583
} else if (!strcasecmp(v->value, "sf_featd")) {
16584
confp->chan.outsigmod = SIG_FEATD;
16585
} else if (!strcasecmp(v->value, "sf_featdmf")) {
16586
confp->chan.outsigmod = SIG_FEATDMF;
16587
} else if (!strcasecmp(v->value, "sf_featb")) {
16588
confp->chan.outsigmod = SIG_SF_FEATB;
16589
} else if (!strcasecmp(v->value, "sf")) {
16590
confp->chan.outsigmod = SIG_SF;
16591
} else if (!strcasecmp(v->value, "featd")) {
16592
confp->chan.outsigmod = SIG_FEATD;
16593
} else if (!strcasecmp(v->value, "featdmf")) {
16594
confp->chan.outsigmod = SIG_FEATDMF;
16595
} else if (!strcasecmp(v->value, "featdmf_ta")) {
16596
confp->chan.outsigmod = SIG_FEATDMF_TA;
16597
} else if (!strcasecmp(v->value, "e911")) {
16598
confp->chan.outsigmod = SIG_E911;
16599
} else if (!strcasecmp(v->value, "fgccama")) {
16600
confp->chan.outsigmod = SIG_FGC_CAMA;
16601
} else if (!strcasecmp(v->value, "fgccamamf")) {
16602
confp->chan.outsigmod = SIG_FGC_CAMAMF;
16603
} else if (!strcasecmp(v->value, "featb")) {
16604
confp->chan.outsigmod = SIG_FEATB;
16606
ast_log(LOG_ERROR, "Unknown signalling method '%s' at line %d.\n", v->value, v->lineno);
16609
} else if (!strcasecmp(v->name, "pridialplan")) {
16610
if (!strcasecmp(v->value, "national")) {
16611
confp->pri.dialplan = PRI_NATIONAL_ISDN + 1;
16612
} else if (!strcasecmp(v->value, "unknown")) {
16613
confp->pri.dialplan = PRI_UNKNOWN + 1;
16614
} else if (!strcasecmp(v->value, "private")) {
16615
confp->pri.dialplan = PRI_PRIVATE + 1;
16616
} else if (!strcasecmp(v->value, "international")) {
16617
confp->pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
16618
} else if (!strcasecmp(v->value, "local")) {
16619
confp->pri.dialplan = PRI_LOCAL_ISDN + 1;
16620
} else if (!strcasecmp(v->value, "dynamic")) {
16621
confp->pri.dialplan = -1;
16622
} else if (!strcasecmp(v->value, "redundant")) {
16623
confp->pri.dialplan = -2;
16625
ast_log(LOG_WARNING, "Unknown PRI dialplan '%s' at line %d.\n", v->value, v->lineno);
16627
} else if (!strcasecmp(v->name, "prilocaldialplan")) {
16628
if (!strcasecmp(v->value, "national")) {
16629
confp->pri.localdialplan = PRI_NATIONAL_ISDN + 1;
16630
} else if (!strcasecmp(v->value, "unknown")) {
16631
confp->pri.localdialplan = PRI_UNKNOWN + 1;
16632
} else if (!strcasecmp(v->value, "private")) {
16633
confp->pri.localdialplan = PRI_PRIVATE + 1;
16634
} else if (!strcasecmp(v->value, "international")) {
16635
confp->pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
16636
} else if (!strcasecmp(v->value, "local")) {
16637
confp->pri.localdialplan = PRI_LOCAL_ISDN + 1;
16638
} else if (!strcasecmp(v->value, "dynamic")) {
16639
confp->pri.localdialplan = -1;
16640
} else if (!strcasecmp(v->value, "redundant")) {
16641
confp->pri.localdialplan = -2;
16643
ast_log(LOG_WARNING, "Unknown PRI localdialplan '%s' at line %d.\n", v->value, v->lineno);
16645
} else if (!strcasecmp(v->name, "switchtype")) {
16646
if (!strcasecmp(v->value, "national"))
16647
confp->pri.switchtype = PRI_SWITCH_NI2;
16648
else if (!strcasecmp(v->value, "ni1"))
16649
confp->pri.switchtype = PRI_SWITCH_NI1;
16650
else if (!strcasecmp(v->value, "dms100"))
16651
confp->pri.switchtype = PRI_SWITCH_DMS100;
16652
else if (!strcasecmp(v->value, "4ess"))
16653
confp->pri.switchtype = PRI_SWITCH_ATT4ESS;
16654
else if (!strcasecmp(v->value, "5ess"))
16655
confp->pri.switchtype = PRI_SWITCH_LUCENT5E;
16656
else if (!strcasecmp(v->value, "euroisdn"))
16657
confp->pri.switchtype = PRI_SWITCH_EUROISDN_E1;
16658
else if (!strcasecmp(v->value, "qsig"))
16659
confp->pri.switchtype = PRI_SWITCH_QSIG;
16661
ast_log(LOG_ERROR, "Unknown switchtype '%s' at line %d.\n", v->value, v->lineno);
16664
} else if (!strcasecmp(v->name, "nsf")) {
16665
if (!strcasecmp(v->value, "sdn"))
16666
confp->pri.nsf = PRI_NSF_SDN;
16667
else if (!strcasecmp(v->value, "megacom"))
16668
confp->pri.nsf = PRI_NSF_MEGACOM;
16669
else if (!strcasecmp(v->value, "tollfreemegacom"))
16670
confp->pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
16671
else if (!strcasecmp(v->value, "accunet"))
16672
confp->pri.nsf = PRI_NSF_ACCUNET;
16673
else if (!strcasecmp(v->value, "none"))
16674
confp->pri.nsf = PRI_NSF_NONE;
16676
ast_log(LOG_WARNING, "Unknown network-specific facility '%s' at line %d.\n", v->value, v->lineno);
16677
confp->pri.nsf = PRI_NSF_NONE;
16679
} else if (!strcasecmp(v->name, "priindication")) {
16680
if (!strcasecmp(v->value, "outofband"))
16681
confp->chan.priindication_oob = 1;
16682
else if (!strcasecmp(v->value, "inband"))
16683
confp->chan.priindication_oob = 0;
16685
ast_log(LOG_WARNING, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
16686
v->value, v->lineno);
16687
} else if (!strcasecmp(v->name, "priexclusive")) {
16688
confp->chan.priexclusive = ast_true(v->value);
16689
} else if (!strcasecmp(v->name, "internationalprefix")) {
16690
ast_copy_string(confp->pri.internationalprefix, v->value, sizeof(confp->pri.internationalprefix));
16691
} else if (!strcasecmp(v->name, "nationalprefix")) {
16692
ast_copy_string(confp->pri.nationalprefix, v->value, sizeof(confp->pri.nationalprefix));
16693
} else if (!strcasecmp(v->name, "localprefix")) {
16694
ast_copy_string(confp->pri.localprefix, v->value, sizeof(confp->pri.localprefix));
16695
} else if (!strcasecmp(v->name, "privateprefix")) {
16696
ast_copy_string(confp->pri.privateprefix, v->value, sizeof(confp->pri.privateprefix));
16697
} else if (!strcasecmp(v->name, "unknownprefix")) {
16698
ast_copy_string(confp->pri.unknownprefix, v->value, sizeof(confp->pri.unknownprefix));
16699
} else if (!strcasecmp(v->name, "resetinterval")) {
16700
if (!strcasecmp(v->value, "never"))
16701
confp->pri.resetinterval = -1;
16702
else if (atoi(v->value) >= 60)
16703
confp->pri.resetinterval = atoi(v->value);
16705
ast_log(LOG_WARNING, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
16706
v->value, v->lineno);
16707
} else if (!strcasecmp(v->name, "minunused")) {
16708
confp->pri.minunused = atoi(v->value);
16709
} else if (!strcasecmp(v->name, "minidle")) {
16710
confp->pri.minidle = atoi(v->value);
16711
} else if (!strcasecmp(v->name, "idleext")) {
16712
ast_copy_string(confp->pri.idleext, v->value, sizeof(confp->pri.idleext));
16713
} else if (!strcasecmp(v->name, "idledial")) {
16714
ast_copy_string(confp->pri.idledial, v->value, sizeof(confp->pri.idledial));
16715
} else if (!strcasecmp(v->name, "overlapdial")) {
16716
if (ast_true(v->value)) {
16717
confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
16718
} else if (!strcasecmp(v->value, "incoming")) {
16719
confp->pri.overlapdial = DAHDI_OVERLAPDIAL_INCOMING;
16720
} else if (!strcasecmp(v->value, "outgoing")) {
16721
confp->pri.overlapdial = DAHDI_OVERLAPDIAL_OUTGOING;
16722
} else if (!strcasecmp(v->value, "both") || ast_true(v->value)) {
16723
confp->pri.overlapdial = DAHDI_OVERLAPDIAL_BOTH;
16725
confp->pri.overlapdial = DAHDI_OVERLAPDIAL_NONE;
16727
#ifdef HAVE_PRI_PROG_W_CAUSE
16728
} else if (!strcasecmp(v->name, "qsigchannelmapping")) {
16729
if (!strcasecmp(v->value, "logical")) {
16730
confp->pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_LOGICAL;
16731
} else if (!strcasecmp(v->value, "physical")) {
16732
confp->pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
16734
confp->pri.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL;
16737
} else if (!strcasecmp(v->name, "discardremoteholdretrieval")) {
16738
confp->pri.discardremoteholdretrieval = ast_true(v->value);
16739
#ifdef HAVE_PRI_INBANDDISCONNECT
16740
} else if (!strcasecmp(v->name, "inbanddisconnect")) {
16741
confp->pri.inbanddisconnect = ast_true(v->value);
16743
} else if (!strcasecmp(v->name, "pritimer")) {
16744
#ifdef PRI_GETSET_TIMERS
16751
ast_copy_string(tmp, v->value, sizeof(tmp));
16753
timerc = strsep(&c, ",");
16754
if (!ast_strlen_zero(timerc) && !ast_strlen_zero(c)) {
16755
timeridx = pri_timer2idx(timerc);
16757
if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
16758
ast_log(LOG_WARNING,
16759
"'%s' is not a valid ISDN timer at line %d.\n", timerc,
16761
} else if (!timer) {
16762
ast_log(LOG_WARNING,
16763
"'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
16764
c, timerc, v->lineno);
16766
pritimers[timeridx] = timer;
16769
ast_log(LOG_WARNING,
16770
"'%s' is not a valid ISDN timer configuration string at line %d.\n",
16771
v->value, v->lineno);
16774
} else if (!strcasecmp(v->name, "facilityenable")) {
16775
confp->pri.facilityenable = ast_true(v->value);
16776
#endif /* PRI_GETSET_TIMERS */
16777
#endif /* HAVE_PRI */
16779
} else if (!strcasecmp(v->name, "ss7type")) {
16780
if (!strcasecmp(v->value, "itu")) {
16781
cur_ss7type = SS7_ITU;
16782
} else if (!strcasecmp(v->value, "ansi")) {
16783
cur_ss7type = SS7_ANSI;
16785
ast_log(LOG_WARNING, "'%s' is an unknown ss7 switch type at line %d.!\n", v->value, v->lineno);
16786
} else if (!strcasecmp(v->name, "linkset")) {
16787
cur_linkset = atoi(v->value);
16788
} else if (!strcasecmp(v->name, "pointcode")) {
16789
cur_pointcode = parse_pointcode(v->value);
16790
} else if (!strcasecmp(v->name, "adjpointcode")) {
16791
cur_adjpointcode = parse_pointcode(v->value);
16792
} else if (!strcasecmp(v->name, "defaultdpc")) {
16793
cur_defaultdpc = parse_pointcode(v->value);
16794
} else if (!strcasecmp(v->name, "cicbeginswith")) {
16795
cur_cicbeginswith = atoi(v->value);
16796
} else if (!strcasecmp(v->name, "networkindicator")) {
16797
if (!strcasecmp(v->value, "national"))
16798
cur_networkindicator = SS7_NI_NAT;
16799
else if (!strcasecmp(v->value, "national_spare"))
16800
cur_networkindicator = SS7_NI_NAT_SPARE;
16801
else if (!strcasecmp(v->value, "international"))
16802
cur_networkindicator = SS7_NI_INT;
16803
else if (!strcasecmp(v->value, "international_spare"))
16804
cur_networkindicator = SS7_NI_INT_SPARE;
16806
cur_networkindicator = -1;
16807
} else if (!strcasecmp(v->name, "ss7_internationalprefix")) {
16808
ast_copy_string(confp->ss7.internationalprefix, v->value, sizeof(confp->ss7.internationalprefix));
16809
} else if (!strcasecmp(v->name, "ss7_nationalprefix")) {
16810
ast_copy_string(confp->ss7.nationalprefix, v->value, sizeof(confp->ss7.nationalprefix));
16811
} else if (!strcasecmp(v->name, "ss7_subscriberprefix")) {
16812
ast_copy_string(confp->ss7.subscriberprefix, v->value, sizeof(confp->ss7.subscriberprefix));
16813
} else if (!strcasecmp(v->name, "ss7_unknownprefix")) {
16814
ast_copy_string(confp->ss7.unknownprefix, v->value, sizeof(confp->ss7.unknownprefix));
16815
} else if (!strcasecmp(v->name, "ss7_called_nai")) {
16816
if (!strcasecmp(v->value, "national")) {
16817
confp->ss7.called_nai = SS7_NAI_NATIONAL;
16818
} else if (!strcasecmp(v->value, "international")) {
16819
confp->ss7.called_nai = SS7_NAI_INTERNATIONAL;
16820
} else if (!strcasecmp(v->value, "subscriber")) {
16821
confp->ss7.called_nai = SS7_NAI_SUBSCRIBER;
16822
} else if (!strcasecmp(v->value, "dynamic")) {
16823
confp->ss7.called_nai = SS7_NAI_DYNAMIC;
16825
ast_log(LOG_WARNING, "Unknown SS7 called_nai '%s' at line %d.\n", v->value, v->lineno);
16827
} else if (!strcasecmp(v->name, "ss7_calling_nai")) {
16828
if (!strcasecmp(v->value, "national")) {
16829
confp->ss7.calling_nai = SS7_NAI_NATIONAL;
16830
} else if (!strcasecmp(v->value, "international")) {
16831
confp->ss7.calling_nai = SS7_NAI_INTERNATIONAL;
16832
} else if (!strcasecmp(v->value, "subscriber")) {
16833
confp->ss7.calling_nai = SS7_NAI_SUBSCRIBER;
16834
} else if (!strcasecmp(v->value, "dynamic")) {
16835
confp->ss7.calling_nai = SS7_NAI_DYNAMIC;
16837
ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
16839
} else if (!strcasecmp(v->name, "sigchan")) {
16841
sigchan = atoi(v->value);
16842
res = linkset_addsigchan(sigchan);
16846
} else if (!strcasecmp(v->name, "ss7_explicitacm")) {
16847
struct dahdi_ss7 *link;
16848
link = ss7_resolve_linkset(cur_linkset);
16850
ast_log(LOG_ERROR, "Invalid linkset number. Must be between 1 and %d\n", NUM_SPANS + 1);
16853
if (ast_true(v->value))
16854
link->flags |= LINKSET_FLAG_EXPLICITACM;
16855
#endif /* HAVE_SS7 */
16857
} else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
16858
ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file));
16859
ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", confp->mfcr2.r2proto_file);
16860
} else if (!strcasecmp(v->name, "mfcr2_logdir")) {
16861
ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir));
16862
} else if (!strcasecmp(v->name, "mfcr2_variant")) {
16863
confp->mfcr2.variant = openr2_proto_get_variant(v->value);
16864
if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
16865
ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno);
16866
confp->mfcr2.variant = OR2_VAR_ITU;
16868
} else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
16869
confp->mfcr2.mfback_timeout = atoi(v->value);
16870
if (!confp->mfcr2.mfback_timeout) {
16871
ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
16872
confp->mfcr2.mfback_timeout = -1;
16873
} else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
16874
ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
16876
} else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
16877
confp->mfcr2.metering_pulse_timeout = atoi(v->value);
16878
if (confp->mfcr2.metering_pulse_timeout > 500) {
16879
ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
16881
} else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
16882
confp->mfcr2.get_ani_first = ast_true(v->value) ? 1 : 0;
16883
} else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
16884
confp->mfcr2.double_answer = ast_true(v->value) ? 1 : 0;
16885
} else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
16886
confp->mfcr2.charge_calls = ast_true(v->value) ? 1 : 0;
16887
} else if (!strcasecmp(v->name, "mfcr2_accept_on_offer")) {
16888
confp->mfcr2.accept_on_offer = ast_true(v->value) ? 1 : 0;
16889
} else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
16890
confp->mfcr2.allow_collect_calls = ast_true(v->value) ? 1 : 0;
16891
} else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
16892
confp->mfcr2.forced_release = ast_true(v->value) ? 1 : 0;
16893
} else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
16894
confp->mfcr2.immediate_accept = ast_true(v->value) ? 1 : 0;
16895
} else if (!strcasecmp(v->name, "mfcr2_skip_category")) {
16896
confp->mfcr2.skip_category_request = ast_true(v->value) ? 1 : 0;
16897
} else if (!strcasecmp(v->name, "mfcr2_call_files")) {
16898
confp->mfcr2.call_files = ast_true(v->value) ? 1 : 0;
16899
} else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
16900
confp->mfcr2.max_ani = atoi(v->value);
16901
if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){
16902
confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1;
16904
} else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
16905
confp->mfcr2.max_dnis = atoi(v->value);
16906
if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){
16907
confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1;
16909
} else if (!strcasecmp(v->name, "mfcr2_category")) {
16910
confp->mfcr2.category = openr2_proto_get_category(v->value);
16911
if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
16912
confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
16913
ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
16914
v->value, v->lineno);
16916
} else if (!strcasecmp(v->name, "mfcr2_logging")) {
16917
openr2_log_level_t tmplevel;
16919
char *logval = ast_strdupa(v->value);
16921
clevel = strsep(&logval,",");
16922
if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
16923
ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", clevel, v->lineno);
16926
confp->mfcr2.loglevel |= tmplevel;
16928
#endif /* HAVE_OPENR2 */
16929
} else if (!strcasecmp(v->name, "cadence")) {
16930
/* setup to scan our argument */
16931
int element_count, c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
16933
struct dahdi_ring_cadence new_cadence;
16934
int cid_location = -1;
16935
int firstcadencepos = 0;
16936
char original_args[80];
16937
int cadence_is_ok = 1;
16939
ast_copy_string(original_args, v->value, sizeof(original_args));
16940
/* 16 cadences allowed (8 pairs) */
16941
element_count = sscanf(v->value, "%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d,%30d", &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12], &c[13], &c[14], &c[15]);
16943
/* Cadence must be even (on/off) */
16944
if (element_count % 2 == 1) {
16945
ast_log(LOG_ERROR, "Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->lineno);
16949
/* Ring cadences cannot be negative */
16950
for (i = 0; i < element_count; i++) {
16952
ast_log(LOG_ERROR, "Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->lineno);
16955
} else if (c[i] < 0) {
16957
/* Silence duration, negative possibly okay */
16958
if (cid_location == -1) {
16962
ast_log(LOG_ERROR, "CID location specified twice: %s at line %d.\n", original_args, v->lineno);
16967
if (firstcadencepos == 0) {
16968
firstcadencepos = i; /* only recorded to avoid duplicate specification */
16969
/* duration will be passed negative to the DAHDI driver */
16971
ast_log(LOG_ERROR, "First cadence position specified twice: %s at line %d.\n", original_args, v->lineno);
16979
/* Substitute our scanned cadence */
16980
for (i = 0; i < 16; i++) {
16981
new_cadence.ringcadence[i] = c[i];
16984
if (cadence_is_ok) {
16985
/* ---we scanned it without getting annoyed; now some sanity checks--- */
16986
if (element_count < 2) {
16987
ast_log(LOG_ERROR, "Minimum cadence is ring,pause: %s at line %d.\n", original_args, v->lineno);
16989
if (cid_location == -1) {
16990
/* user didn't say; default to first pause */
16993
/* convert element_index to cidrings value */
16994
cid_location = (cid_location + 1) / 2;
16996
/* ---we like their cadence; try to install it--- */
16997
if (!user_has_defined_cadences++)
16998
/* this is the first user-defined cadence; clear the default user cadences */
17000
if ((num_cadence+1) >= NUM_CADENCE_MAX)
17001
ast_log(LOG_ERROR, "Already %d cadences; can't add another: %s at line %d.\n", NUM_CADENCE_MAX, original_args, v->lineno);
17003
cadences[num_cadence] = new_cadence;
17004
cidrings[num_cadence++] = cid_location;
17005
ast_verb(3, "cadence 'r%d' added: %s\n",num_cadence,original_args);
17009
} else if (!strcasecmp(v->name, "ringtimeout")) {
17010
ringt_base = (atoi(v->value) * 8) / READ_SIZE;
17011
} else if (!strcasecmp(v->name, "prewink")) {
17012
confp->timing.prewinktime = atoi(v->value);
17013
} else if (!strcasecmp(v->name, "preflash")) {
17014
confp->timing.preflashtime = atoi(v->value);
17015
} else if (!strcasecmp(v->name, "wink")) {
17016
confp->timing.winktime = atoi(v->value);
17017
} else if (!strcasecmp(v->name, "flash")) {
17018
confp->timing.flashtime = atoi(v->value);
17019
} else if (!strcasecmp(v->name, "start")) {
17020
confp->timing.starttime = atoi(v->value);
17021
} else if (!strcasecmp(v->name, "rxwink")) {
17022
confp->timing.rxwinktime = atoi(v->value);
17023
} else if (!strcasecmp(v->name, "rxflash")) {
17024
confp->timing.rxflashtime = atoi(v->value);
17025
} else if (!strcasecmp(v->name, "debounce")) {
17026
confp->timing.debouncetime = atoi(v->value);
17027
} else if (!strcasecmp(v->name, "toneduration")) {
17031
struct dahdi_dialparams dps;
17033
ctlfd = open("/dev/dahdi/ctl", O_RDWR);
17035
ast_log(LOG_ERROR, "Unable to open /dev/dahdi/ctl to set toneduration at line %d.\n", v->lineno);
17039
toneduration = atoi(v->value);
17040
if (toneduration > -1) {
17041
memset(&dps, 0, sizeof(dps));
17043
dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
17044
res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
17046
ast_log(LOG_ERROR, "Invalid tone duration: %d ms at line %d: %s\n", toneduration, v->lineno, strerror(errno));
17051
} else if (!strcasecmp(v->name, "defaultcic")) {
17052
ast_copy_string(defaultcic, v->value, sizeof(defaultcic));
17053
} else if (!strcasecmp(v->name, "defaultozz")) {
17054
ast_copy_string(defaultozz, v->value, sizeof(defaultozz));
17055
} else if (!strcasecmp(v->name, "mwilevel")) {
17056
mwilevel = atoi(v->value);
17058
} else if (!(options & PROC_DAHDI_OPT_NOWARN) )
17059
ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);
17061
if (dahdichan[0]) {
17062
/* The user has set 'dahdichan' */
17063
/*< \todo pass proper line number instead of 0 */
17064
if (build_channels(confp, 0, dahdichan, reload, 0, &found_pseudo)) {
17068
/*< \todo why check for the pseudo in the per-channel section.
17069
* Any actual use for manual setup of the pseudo channel? */
17070
if (!found_pseudo && reload != 1) {
17071
/* use the default configuration for a channel, so
17072
that any settings from real configured channels
17073
don't "leak" into the pseudo channel config
17075
struct dahdi_chan_conf conf = dahdi_chan_conf_default();
17077
tmp = mkintf(CHAN_PSEUDO, &conf, NULL, reload);
17080
ast_verb(3, "Automatically generated pseudo channel\n");
17082
ast_log(LOG_WARNING, "Unable to register pseudo channel!\n");
17088
static int setup_dahdi(int reload)
17090
struct ast_config *cfg, *ucfg;
17091
struct ast_variable *v;
17092
struct dahdi_chan_conf base_conf = dahdi_chan_conf_default();
17093
struct dahdi_chan_conf conf;
17094
struct ast_flags config_flags = { reload == 1 ? CONFIG_FLAG_FILEUNCHANGED : 0 };
17104
int dchannels[NUM_DCHANS];
17107
cfg = ast_config_load(config, config_flags);
17109
/* Error if we have no config file */
17111
ast_log(LOG_ERROR, "Unable to load config %s\n", config);
17113
} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
17114
ucfg = ast_config_load("users.conf", config_flags);
17115
if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
17117
} else if (ucfg == CONFIG_STATUS_FILEINVALID) {
17118
ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
17121
ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
17122
if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
17123
ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
17124
ast_config_destroy(ucfg);
17127
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
17128
ast_log(LOG_ERROR, "File %s cannot be parsed. Aborting.\n", config);
17131
ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
17132
if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
17133
ast_log(LOG_ERROR, "File users.conf cannot be parsed. Aborting.\n");
17134
ast_config_destroy(cfg);
17139
/* It's a little silly to lock it, but we mind as well just to be sure */
17140
ast_mutex_lock(&iflock);
17143
/* Process trunkgroups first */
17144
v = ast_variable_browse(cfg, "trunkgroups");
17146
if (!strcasecmp(v->name, "trunkgroup")) {
17147
trunkgroup = atoi(v->value);
17148
if (trunkgroup > 0) {
17149
if ((c = strchr(v->value, ','))) {
17151
memset(dchannels, 0, sizeof(dchannels));
17152
while (c && (i < NUM_DCHANS)) {
17153
dchannels[i] = atoi(c + 1);
17154
if (dchannels[i] < 0) {
17155
ast_log(LOG_WARNING, "D-channel for trunk group %d must be a postiive number at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
17158
c = strchr(c + 1, ',');
17161
if (pri_create_trunkgroup(trunkgroup, dchannels)) {
17162
ast_log(LOG_WARNING, "Unable to create trunk group %d with Primary D-channel %d at line %d of chan_dahdi.conf\n", trunkgroup, dchannels[0], v->lineno);
17164
ast_verb(2, "Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup, dchannels[0], i - 1, (i == 1) ? "" : "s");
17166
ast_log(LOG_WARNING, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
17168
ast_log(LOG_WARNING, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->lineno);
17170
ast_log(LOG_WARNING, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->lineno);
17171
} else if (!strcasecmp(v->name, "spanmap")) {
17172
spanno = atoi(v->value);
17174
if ((c = strchr(v->value, ','))) {
17175
trunkgroup = atoi(c + 1);
17176
if (trunkgroup > 0) {
17177
if ((c = strchr(c + 1, ',')))
17178
logicalspan = atoi(c + 1);
17181
if (logicalspan >= 0) {
17182
if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
17183
ast_log(LOG_WARNING, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
17185
ast_verb(2, "Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
17187
ast_log(LOG_WARNING, "Logical span must be a postive number, or '0' (for unspecified) at line %d of chan_dahdi.conf\n", v->lineno);
17189
ast_log(LOG_WARNING, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v->lineno);
17191
ast_log(LOG_WARNING, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v->lineno);
17193
ast_log(LOG_WARNING, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v->lineno);
17195
ast_log(LOG_NOTICE, "Ignoring unknown keyword '%s' in trunkgroups\n", v->name);
17202
/* Copy the default jb config over global_jbconf */
17203
memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
17205
mwimonitornotify[0] = '\0';
17207
v = ast_variable_browse(cfg, "channels");
17208
if ((res = process_dahdi(&base_conf, "", v, reload, 0))) {
17209
ast_mutex_unlock(&iflock);
17210
ast_config_destroy(cfg);
17212
ast_config_destroy(ucfg);
17217
/* Now get configuration from all normal sections in chan_dahdi.conf: */
17218
for (cat = ast_category_browse(cfg, NULL); cat ; cat = ast_category_browse(cfg, cat)) {
17219
/* [channels] and [trunkgroups] are used. Let's also reserve
17220
* [globals] and [general] for future use
17222
if (!strcasecmp(cat, "general") ||
17223
!strcasecmp(cat, "trunkgroups") ||
17224
!strcasecmp(cat, "globals") ||
17225
!strcasecmp(cat, "channels")) {
17229
memcpy(&conf, &base_conf, sizeof(conf));
17231
if ((res = process_dahdi(&conf, cat, ast_variable_browse(cfg, cat), reload, PROC_DAHDI_OPT_NOCHAN))) {
17232
ast_mutex_unlock(&iflock);
17233
ast_config_destroy(cfg);
17235
ast_config_destroy(cfg);
17241
ast_config_destroy(cfg);
17246
process_dahdi(&base_conf, "", ast_variable_browse(ucfg, "general"), 1, 0);
17248
for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
17249
if (!strcasecmp(cat, "general")) {
17253
chans = ast_variable_retrieve(ucfg, cat, "dahdichan");
17255
if (ast_strlen_zero(chans)) {
17259
memcpy(&conf, &base_conf, sizeof(conf));
17261
if ((res = process_dahdi(&conf, cat, ast_variable_browse(ucfg, cat), reload, PROC_DAHDI_OPT_NOCHAN | PROC_DAHDI_OPT_NOWARN))) {
17262
ast_config_destroy(ucfg);
17263
ast_mutex_unlock(&iflock);
17267
ast_config_destroy(ucfg);
17269
ast_mutex_unlock(&iflock);
17274
for (x = 0; x < NUM_SPANS; x++) {
17275
if (pris[x].pvts[0]) {
17276
if (start_pri(pris + x)) {
17277
ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
17280
ast_verb(2, "Starting D-Channel on span %d\n", x + 1);
17288
for (x = 0; x < NUM_SPANS; x++) {
17289
if (linksets[x].ss7) {
17290
if (ast_pthread_create(&linksets[x].master, NULL, ss7_linkset, &linksets[x])) {
17291
ast_log(LOG_ERROR, "Unable to start SS7 linkset on span %d\n", x + 1);
17294
ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1);
17302
for (x = 0; x < r2links_count; x++) {
17303
if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) {
17304
ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
17307
ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
17312
/* And start the monitor for the first time */
17317
static int load_module(void)
17320
#if defined(HAVE_PRI) || defined(HAVE_SS7)
17325
memset(pris, 0, sizeof(pris));
17326
for (y = 0; y < NUM_SPANS; y++) {
17327
ast_mutex_init(&pris[y].lock);
17328
pris[y].offset = -1;
17329
pris[y].master = AST_PTHREADT_NULL;
17330
for (i = 0; i < NUM_DCHANS; i++)
17331
pris[y].fds[i] = -1;
17333
pri_set_error(dahdi_pri_error);
17334
pri_set_message(dahdi_pri_message);
17335
ast_register_application_xml(dahdi_send_keypad_facility_app, dahdi_send_keypad_facility_exec);
17336
#ifdef HAVE_PRI_PROG_W_CAUSE
17337
ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec);
17341
memset(linksets, 0, sizeof(linksets));
17342
for (y = 0; y < NUM_SPANS; y++) {
17343
ast_mutex_init(&linksets[y].lock);
17344
linksets[y].master = AST_PTHREADT_NULL;
17345
for (i = 0; i < NUM_DCHANS; i++)
17346
linksets[y].fds[i] = -1;
17348
ss7_set_error(dahdi_ss7_error);
17349
ss7_set_message(dahdi_ss7_message);
17350
#endif /* HAVE_SS7 */
17351
res = setup_dahdi(0);
17352
/* Make sure we can register our DAHDI channel type */
17354
return AST_MODULE_LOAD_DECLINE;
17355
if (ast_channel_register(&dahdi_tech)) {
17356
ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
17358
return AST_MODULE_LOAD_FAILURE;
17361
ast_string_field_init(&inuse, 16);
17362
ast_string_field_set(&inuse, name, "GR-303InUse");
17363
ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
17366
ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
17369
ast_cli_register_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli)/sizeof(dahdi_mfcr2_cli[0]));
17370
ast_register_application_xml(dahdi_accept_r2_call_app, dahdi_accept_r2_call_exec);
17373
ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));
17375
memset(round_robin, 0, sizeof(round_robin));
17376
ast_manager_register( "DAHDITransfer", 0, action_transfer, "Transfer DAHDI Channel" );
17377
ast_manager_register( "DAHDIHangup", 0, action_transferhangup, "Hangup DAHDI Channel" );
17378
ast_manager_register( "DAHDIDialOffhook", 0, action_dahdidialoffhook, "Dial over DAHDI channel while offhook" );
17379
ast_manager_register( "DAHDIDNDon", 0, action_dahdidndon, "Toggle DAHDI channel Do Not Disturb status ON" );
17380
ast_manager_register( "DAHDIDNDoff", 0, action_dahdidndoff, "Toggle DAHDI channel Do Not Disturb status OFF" );
17381
ast_manager_register("DAHDIShowChannels", 0, action_dahdishowchannels, "Show status DAHDI channels");
17382
ast_manager_register("DAHDIRestart", 0, action_dahdirestart, "Fully Restart DAHDI channels (terminates calls)");
17384
ast_cond_init(&ss_thread_complete, NULL);
17389
static int dahdi_sendtext(struct ast_channel *c, const char *text)
17391
#define END_SILENCE_LEN 400
17392
#define HEADER_MS 50
17393
#define TRAILER_MS 5
17394
#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
17395
#define ASCII_BYTES_PER_CHAR 80
17397
unsigned char *buf,*mybuf;
17398
struct dahdi_pvt *p = c->tech_pvt;
17399
struct pollfd fds[1];
17400
int size,res,fd,len,x;
17402
/* Initial carrier (imaginary) */
17408
idx = dahdi_get_index(c, p, 0);
17410
ast_log(LOG_WARNING, "Huh? I don't exist?\n");
17413
if (!text[0]) return(0); /* if nothing to send, dont */
17414
if ((!p->tdd) && (!p->mate)) return(0); /* if not in TDD mode, just return */
17416
buf = ast_malloc(((strlen(text) + 1) * ASCII_BYTES_PER_CHAR) + END_SILENCE_LEN + HEADER_LEN);
17418
buf = ast_malloc(((strlen(text) + 1) * TDD_BYTES_PER_CHAR) + END_SILENCE_LEN);
17423
int codec = AST_LAW(p);
17424
for (x = 0; x < HEADER_MS; x++) { /* 50 ms of Mark */
17427
/* Put actual message */
17428
for (x = 0; text[x]; x++) {
17431
for (x = 0; x < TRAILER_MS; x++) { /* 5 ms of Mark */
17437
len = tdd_generate(p->tdd, buf, text);
17439
ast_log(LOG_ERROR, "TDD generate (len %d) failed!!\n", (int)strlen(text));
17444
memset(buf + len, 0x7f, END_SILENCE_LEN);
17445
len += END_SILENCE_LEN;
17446
fd = p->subs[idx].dfd;
17448
if (ast_check_hangup(c)) {
17453
if (size > READ_SIZE)
17456
fds[0].events = POLLOUT | POLLPRI;
17457
fds[0].revents = 0;
17458
res = poll(fds, 1, -1);
17460
ast_debug(1, "poll (for write) ret. 0 on channel %d\n", p->channel);
17463
/* if got exception */
17464
if (fds[0].revents & POLLPRI) {
17468
if (!(fds[0].revents & POLLOUT)) {
17469
ast_debug(1, "write fd not ready on channel %d\n", p->channel);
17472
res = write(fd, buf, size);
17478
ast_debug(1, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
17489
static int reload(void)
17493
res = setup_dahdi(1);
17495
ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");
17501
/* This is a workaround so that menuselect displays a proper description
17502
* AST_MODULE_INFO(, , "DAHDI Telephony"
17505
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,
17506
.load = load_module,
17507
.unload = unload_module,