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 Pseudo TDM interface
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>
44 <depend>res_features</depend>
50 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
58 #include <sys/signal.h>
62 #if !defined(SOLARIS) && !defined(__FreeBSD__)
66 #include <sys/ioctl.h>
74 #include "asterisk/lock.h"
75 #include "asterisk/channel.h"
76 #include "asterisk/config.h"
77 #include "asterisk/logger.h"
78 #include "asterisk/module.h"
79 #include "asterisk/pbx.h"
80 #include "asterisk/options.h"
81 #include "asterisk/file.h"
82 #include "asterisk/ulaw.h"
83 #include "asterisk/alaw.h"
84 #include "asterisk/callerid.h"
85 #include "asterisk/adsi.h"
86 #include "asterisk/cli.h"
87 #include "asterisk/cdr.h"
88 #include "asterisk/features.h"
89 #include "asterisk/musiconhold.h"
90 #include "asterisk/say.h"
91 #include "asterisk/tdd.h"
92 #include "asterisk/app.h"
93 #include "asterisk/dsp.h"
94 #include "asterisk/astdb.h"
95 #include "asterisk/manager.h"
96 #include "asterisk/causes.h"
97 #include "asterisk/term.h"
98 #include "asterisk/utils.h"
99 #include "asterisk/transcap.h"
100 #include "asterisk/stringfields.h"
101 #include "asterisk/abstract_jb.h"
102 #include "asterisk/smdi.h"
103 #include "asterisk/astobj.h"
104 #define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
106 #include "asterisk/dahdi_compat.h"
107 #include "asterisk/tonezone_compat.h"
109 /*! Global jitterbuffer configuration - by default, jb is disabled */
110 static struct ast_jb_conf default_jbconf
=
114 .resync_threshold
= -1,
117 static struct ast_jb_conf global_jbconf
;
119 #ifndef DAHDI_TONEDETECT
120 /* Work around older code with no tone detect */
121 #define DAHDI_EVENT_DTMFDOWN 0
122 #define DAHDI_EVENT_DTMFUP 0
125 /* define this to send PRI user-user information elements */
126 #undef SUPPORT_USERUSER
129 * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
130 * the user hangs up to reset the state machine so ring works properly.
131 * This is used to be able to support kewlstart by putting the zhone in
132 * groundstart mode since their forward disconnect supervision is entirely
133 * broken even though their documentation says it isn't and their support
134 * is entirely unwilling to provide any assistance with their channel banks
135 * even though their web site says they support their products for life.
137 /* #define ZHONE_HACK */
140 * Define if you want to check the hook state for an FXO (FXS signalled) interface
141 * before dialing on it. Certain FXO interfaces always think they're out of
142 * service with this method however.
144 /* #define DAHDI_CHECK_HOOKSTATE */
146 /*! \brief Typically, how many rings before we should send Caller*ID */
147 #define DEFAULT_CIDRINGS 1
149 #define CHANNEL_PSEUDO -12
151 #define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
153 /*! \brief Signaling types that need to use MF detection should be placed in this macro */
154 #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))
156 static const char tdesc
[] = "DAHDI Telephony Driver"
162 #define SIG_EM DAHDI_SIG_EM
163 #define SIG_EMWINK (0x0100000 | DAHDI_SIG_EM)
164 #define SIG_FEATD (0x0200000 | DAHDI_SIG_EM)
165 #define SIG_FEATDMF (0x0400000 | DAHDI_SIG_EM)
166 #define SIG_FEATB (0x0800000 | DAHDI_SIG_EM)
167 #define SIG_E911 (0x1000000 | DAHDI_SIG_EM)
168 #define SIG_FEATDMF_TA (0x2000000 | DAHDI_SIG_EM)
169 #define SIG_FGC_CAMA (0x4000000 | DAHDI_SIG_EM)
170 #define SIG_FGC_CAMAMF (0x8000000 | DAHDI_SIG_EM)
171 #define SIG_FXSLS DAHDI_SIG_FXSLS
172 #define SIG_FXSGS DAHDI_SIG_FXSGS
173 #define SIG_FXSKS DAHDI_SIG_FXSKS
174 #define SIG_FXOLS DAHDI_SIG_FXOLS
175 #define SIG_FXOGS DAHDI_SIG_FXOGS
176 #define SIG_FXOKS DAHDI_SIG_FXOKS
177 #define SIG_PRI DAHDI_SIG_CLEAR
178 #define SIG_SF DAHDI_SIG_SF
179 #define SIG_SFWINK (0x0100000 | DAHDI_SIG_SF)
180 #define SIG_SF_FEATD (0x0200000 | DAHDI_SIG_SF)
181 #define SIG_SF_FEATDMF (0x0400000 | DAHDI_SIG_SF)
182 #define SIG_SF_FEATB (0x0800000 | DAHDI_SIG_SF)
183 #define SIG_EM_E1 DAHDI_SIG_EM_E1
184 #define SIG_GR303FXOKS (0x0100000 | DAHDI_SIG_FXOKS)
185 #define SIG_GR303FXSKS (0x0100000 | DAHDI_SIG_FXSKS)
188 #define NUM_DCHANS 4 /*!< No more than 4 d-channels */
189 #define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
191 #define CHAN_PSEUDO -2
193 #define DCHAN_PROVISIONED (1 << 0)
194 #define DCHAN_NOTINALARM (1 << 1)
195 #define DCHAN_UP (1 << 2)
197 #define DCHAN_AVAILABLE (DCHAN_PROVISIONED | DCHAN_NOTINALARM | DCHAN_UP)
199 static char defaultcic
[64] = "";
200 static char defaultozz
[64] = "";
202 static char progzone
[10] = "";
204 static int distinctiveringaftercid
= 0;
206 static int numbufs
= 4;
209 static struct ast_channel inuse
;
210 #ifdef PRI_GETSET_TIMERS
211 static int pritimers
[PRI_MAX_TIMERS
];
213 static int pridebugfd
= -1;
214 static char pridebugfilename
[1024] = "";
217 /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
218 static int firstdigittimeout
= 16000;
220 /*! \brief How long to wait for following digits (FXO logic) */
221 static int gendigittimeout
= 8000;
223 /*! \brief How long to wait for an extra digit, if there is an ambiguous match */
224 static int matchdigittimeout
= 3000;
226 /*! \brief Protect the interface list (of dahdi_pvt's) */
227 AST_MUTEX_DEFINE_STATIC(iflock
);
230 static int ifcount
= 0;
233 AST_MUTEX_DEFINE_STATIC(pridebugfdlock
);
236 /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
237 when it's doing something critical. */
238 AST_MUTEX_DEFINE_STATIC(monlock
);
240 /*! \brief This is the thread for the monitor which checks for input on the channels
241 which are not currently in use. */
242 static pthread_t monitor_thread
= AST_PTHREADT_NULL
;
243 static ast_cond_t ss_thread_complete
= PTHREAD_COND_INITIALIZER
;
244 AST_MUTEX_DEFINE_STATIC(ss_thread_lock
);
245 AST_MUTEX_DEFINE_STATIC(restart_lock
);
246 static int ss_thread_count
= 0;
247 static int num_restart_pending
= 0;
249 static int restart_monitor(void);
251 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
);
253 static int dahdi_sendtext(struct ast_channel
*c
, const char *text
);
255 /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
256 static inline int dahdi_get_event(int fd
)
259 if (ioctl(fd
, DAHDI_GETEVENT
, &j
) == -1)
264 /*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
265 static inline int dahdi_wait_event(int fd
)
268 i
= DAHDI_IOMUX_SIGEVENT
;
269 if (ioctl(fd
, DAHDI_IOMUX
, &i
) == -1)
271 if (ioctl(fd
, DAHDI_GETEVENT
, &j
) == -1)
276 /*! Chunk size to read -- we use 20ms chunks to make things happy. */
277 #define READ_SIZE 160
279 #define MASK_AVAIL (1 << 0) /*!< Channel available for PRI use */
280 #define MASK_INUSE (1 << 1) /*!< Channel currently in use */
282 #define CALLWAITING_SILENT_SAMPLES ( (300 * 8) / READ_SIZE) /*!< 300 ms */
283 #define CALLWAITING_REPEAT_SAMPLES ( (10000 * 8) / READ_SIZE) /*!< 10,000 ms */
284 #define CIDCW_EXPIRE_SAMPLES ( (500 * 8) / READ_SIZE) /*!< 500 ms */
285 #define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
286 #define DEFAULT_RINGT ( (8000 * 8) / READ_SIZE) /*!< 8,000 ms */
290 static int ringt_base
= DEFAULT_RINGT
;
294 #define PVT_TO_CHANNEL(p) (((p)->prioffset) | ((p)->logicalspan << 8) | (p->pri->mastertrunkgroup ? 0x10000 : 0))
295 #define PRI_CHANNEL(p) ((p) & 0xff)
296 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
297 #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
300 pthread_t master
; /*!< Thread of master */
301 ast_mutex_t lock
; /*!< Mutex */
302 char idleext
[AST_MAX_EXTENSION
]; /*!< Where to idle extra calls */
303 char idlecontext
[AST_MAX_CONTEXT
]; /*!< What context to use for idle */
304 char idledial
[AST_MAX_EXTENSION
]; /*!< What to dial before dumping */
305 int minunused
; /*!< Min # of channels to keep empty */
306 int minidle
; /*!< Min # of "idling" calls to keep active */
307 int nodetype
; /*!< Node type */
308 int switchtype
; /*!< Type of switch to emulate */
309 int nsf
; /*!< Network-Specific Facilities */
310 int dialplan
; /*!< Dialing plan */
311 int localdialplan
; /*!< Local dialing plan */
312 char internationalprefix
[10]; /*!< country access code ('00' for european dialplans) */
313 char nationalprefix
[10]; /*!< area access code ('0' for european dialplans) */
314 char localprefix
[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
315 char privateprefix
[20]; /*!< for private dialplans */
316 char unknownprefix
[20]; /*!< for unknown dialplans */
317 int dchannels
[NUM_DCHANS
]; /*!< What channel are the dchannels on */
318 int trunkgroup
; /*!< What our trunkgroup is */
319 int mastertrunkgroup
; /*!< What trunk group is our master */
320 int prilogicalspan
; /*!< Logical span number within trunk group */
321 int numchans
; /*!< Num of channels we represent */
322 int overlapdial
; /*!< In overlap dialing mode */
323 int facilityenable
; /*!< Enable facility IEs */
324 struct pri
*dchans
[NUM_DCHANS
]; /*!< Actual d-channels */
325 int dchanavail
[NUM_DCHANS
]; /*!< Whether each channel is available */
326 struct pri
*pri
; /*!< Currently active D-channel */
328 int fds
[NUM_DCHANS
]; /*!< FD's for d-channels */
333 #ifdef HAVE_PRI_INBANDDISCONNECT
334 unsigned int inbanddisconnect
:1; /*!< Should we support inband audio after receiving DISCONNECT? */
336 time_t lastreset
; /*!< time when unused channels were last reset */
337 long resetinterval
; /*!< Interval (in seconds) for resetting unused channels */
338 struct dahdi_pvt
*pvts
[MAX_CHANNELS
]; /*!< Member channel pvt structs */
339 struct dahdi_pvt
*crvs
; /*!< Member CRV structs */
340 struct dahdi_pvt
*crvend
; /*!< Pointer to end of CRV structs */
344 static struct dahdi_pri pris
[NUM_SPANS
];
347 #define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW | PRI_DEBUG_Q921_STATE)
349 #define DEFAULT_PRI_DEBUG 0
352 static inline void pri_rel(struct dahdi_pri
*pri
)
354 ast_mutex_unlock(&pri
->lock
);
358 /*! Shut up the compiler */
362 #define SUB_REAL 0 /*!< Active call */
363 #define SUB_CALLWAIT 1 /*!< Call-Waiting call on hold */
364 #define SUB_THREEWAY 2 /*!< Three-way call */
366 /* Polarity states */
367 #define POLARITY_IDLE 0
368 #define POLARITY_REV 1
371 static struct dahdi_distRings drings
;
373 struct distRingData
{
376 struct ringContextData
{
377 char contextData
[AST_MAX_CONTEXT
];
379 struct dahdi_distRings
{
380 struct distRingData ringnum
[3];
381 struct ringContextData ringContext
[3];
384 static char *subnames
[] = {
390 struct dahdi_subchannel
{
392 struct ast_channel
*owner
;
394 short buffer
[AST_FRIENDLY_OFFSET
/2 + READ_SIZE
];
395 struct ast_frame f
; /*!< One frame for each channel. How did this ever work before? */
396 unsigned int needringing
:1;
397 unsigned int needbusy
:1;
398 unsigned int needcongestion
:1;
399 unsigned int needcallerid
:1;
400 unsigned int needanswer
:1;
401 unsigned int needflash
:1;
402 unsigned int needhold
:1;
403 unsigned int needunhold
:1;
404 unsigned int linear
:1;
405 unsigned int inthreeway
:1;
406 struct dahdi_confinfo curconf
;
409 #define CONF_USER_REAL (1 << 0)
410 #define CONF_USER_THIRDCALL (1 << 1)
414 static struct dahdi_pvt
{
416 struct ast_channel
*owner
; /*!< Our current active owner (if applicable) */
417 /*!< Up to three channels can be associated with this call */
419 struct dahdi_subchannel sub_unused
; /*!< Just a safety precaution */
420 struct dahdi_subchannel subs
[3]; /*!< Sub-channels */
421 struct dahdi_confinfo saveconf
; /*!< Saved conference info */
423 struct dahdi_pvt
*slaves
[MAX_SLAVES
]; /*!< Slave to us (follows our conferencing) */
424 struct dahdi_pvt
*master
; /*!< Master to us (we follow their conferencing) */
425 int inconference
; /*!< If our real should be in the conference */
427 int sig
; /*!< Signalling style */
428 int radio
; /*!< radio type */
429 int outsigmod
; /*!< Outbound Signalling style (modifier) */
430 int oprmode
; /*!< "Operator Services" mode */
431 struct dahdi_pvt
*oprpeer
; /*!< "Operator Services" peer tech_pvt ptr */
434 int tonezone
; /*!< tone zone for this chan, or -1 for default */
435 struct dahdi_pvt
*next
; /*!< Next channel in list */
436 struct dahdi_pvt
*prev
; /*!< Prev channel in list */
440 unsigned int answeronpolarityswitch
:1;
441 unsigned int busydetect
:1;
442 unsigned int callreturn
:1;
443 unsigned int callwaiting
:1;
444 unsigned int callwaitingcallerid
:1;
445 unsigned int cancallforward
:1;
446 unsigned int canpark
:1;
447 unsigned int confirmanswer
:1; /*!< Wait for '#' to confirm answer */
448 unsigned int destroy
:1;
449 unsigned int didtdd
:1; /*!< flag to say its done it once */
450 unsigned int dialednone
:1;
451 unsigned int dialing
:1;
452 unsigned int digital
:1;
454 unsigned int echobreak
:1;
455 unsigned int echocanbridged
:1;
456 unsigned int echocanon
:1;
457 unsigned int faxhandled
:1; /*!< Has a fax tone already been handled? */
458 unsigned int firstradio
:1;
459 unsigned int hanguponpolarityswitch
:1;
460 unsigned int hardwaredtmf
:1;
461 unsigned int hidecallerid
:1;
462 unsigned int hidecalleridname
:1; /*!< Hide just the name not the number for legacy PBX use */
463 unsigned int ignoredtmf
:1;
464 unsigned int immediate
:1; /*!< Answer before getting digits? */
465 unsigned int inalarm
:1;
466 unsigned int unknown_alarm
:1;
467 unsigned int mate
:1; /*!< flag to say its in MATE mode */
468 unsigned int outgoing
:1;
469 unsigned int overlapdial
:1;
470 unsigned int permcallwaiting
:1;
471 unsigned int permhidecallerid
:1; /*!< Whether to hide our outgoing caller ID or not */
472 unsigned int priindication_oob
:1;
473 unsigned int priexclusive
:1;
474 unsigned int pulse
:1;
475 unsigned int pulsedial
:1; /*!< whether a pulse dial phone is detected */
476 unsigned int restartpending
:1; /*!< flag to ensure counted only once for restart */
477 unsigned int restrictcid
:1; /*!< Whether restrict the callerid -> only send ANI */
478 unsigned int threewaycalling
:1;
479 unsigned int transfer
:1;
480 unsigned int use_callerid
:1; /*!< Whether or not to use caller id on this channel */
481 unsigned int use_callingpres
:1; /*!< Whether to use the callingpres the calling switch sends */
482 unsigned int usedistinctiveringdetection
:1;
483 unsigned int dahditrcallerid
:1; /*!< should we use the callerid from incoming call on dahdi transfer or not */
484 unsigned int transfertobusy
:1; /*!< allow flash-transfers to busy channels */
485 #if defined(HAVE_PRI)
486 unsigned int alerting
:1;
487 unsigned int alreadyhungup
:1;
488 unsigned int isidlecall
:1;
489 unsigned int proceeding
:1;
490 unsigned int progress
:1;
491 unsigned int resetting
:1;
492 unsigned int setup_ack
:1;
494 unsigned int use_smdi
:1; /* Whether to use SMDI on this channel */
495 struct ast_smdi_interface
*smdi_iface
; /* The serial port to listen for SMDI data on */
497 struct dahdi_distRings drings
;
499 char context
[AST_MAX_CONTEXT
];
500 char defcontext
[AST_MAX_CONTEXT
];
501 char exten
[AST_MAX_EXTENSION
];
502 char language
[MAX_LANGUAGE
];
503 char mohinterpret
[MAX_MUSICCLASS
];
504 char mohsuggest
[MAX_MUSICCLASS
];
506 char cid_ani
[AST_MAX_EXTENSION
];
508 char cid_num
[AST_MAX_EXTENSION
];
509 int cid_ton
; /*!< Type Of Number (TON) */
510 char cid_name
[AST_MAX_EXTENSION
];
511 char lastcid_num
[AST_MAX_EXTENSION
];
512 char lastcid_name
[AST_MAX_EXTENSION
];
513 char *origcid_num
; /*!< malloced original callerid */
514 char *origcid_name
; /*!< malloced original callerid */
515 char callwait_num
[AST_MAX_EXTENSION
];
516 char callwait_name
[AST_MAX_EXTENSION
];
517 char rdnis
[AST_MAX_EXTENSION
];
518 char dnid
[AST_MAX_EXTENSION
];
521 int confno
; /*!< Our conference */
522 int confusers
; /*!< Who is using our conference */
523 int propconfno
; /*!< Propagated conference number */
524 ast_group_t callgroup
;
525 ast_group_t pickupgroup
;
526 int channel
; /*!< Channel Number or CRV */
527 int span
; /*!< Span number */
528 time_t guardtime
; /*!< Must wait this much time before using for new call */
529 int cid_signalling
; /*!< CID signalling type bell202 or v23 */
530 int cid_start
; /*!< CID start indicator, polarity or ring */
531 int callingpres
; /*!< The value of callling presentation that we're going to use when placing a PRI call */
532 int callwaitingrepeat
; /*!< How many samples to wait before repeating call waiting */
533 int cidcwexpire
; /*!< When to expire our muting for CID/CW */
534 unsigned char *cidspill
;
547 int busy_quietlength
;
549 struct timeval flashtime
; /*!< Last flash-hook time */
551 int cref
; /*!< Call reference number */
552 struct dahdi_dialoperation dop
;
553 int whichwink
; /*!< SIG_FEATDMF_TA Which wink are we on? */
555 char accountcode
[AST_MAX_ACCOUNT_CODE
]; /*!< Account code */
556 int amaflags
; /*!< AMA Flags */
557 struct tdd_state
*tdd
; /*!< TDD flag */
558 char call_forward
[AST_MAX_EXTENSION
];
559 char mailbox
[AST_MAX_EXTENSION
];
563 int distinctivering
; /*!< Which distinctivering to use */
564 int cidrings
; /*!< Which ring to deliver CID on */
565 int dtmfrelax
; /*!< whether to run in relaxed DTMF mode */
567 int polarityonanswerdelay
;
568 struct timeval polaritydelaytv
;
569 int sendcalleridafter
;
571 struct dahdi_pri
*pri
;
572 struct dahdi_pvt
*bearer
;
573 struct dahdi_pvt
*realcall
;
581 } *iflist
= NULL
, *ifend
= NULL
;
583 /*! \brief Channel configuration from chan_dahdi.conf .
584 * This struct is used for parsing the [channels] section of chan_dahdi.conf.
585 * Generally there is a field here for every possible configuration item.
587 * The state of fields is saved along the parsing and whenever a 'channel'
588 * statement is reached, the current dahdi_chan_conf is used to configure the
589 * channel (struct dahdi_pvt)
591 * @seealso dahdi_chan_init for the default values.
593 struct dahdi_chan_conf
{
594 struct dahdi_pvt chan
;
596 struct dahdi_pri pri
;
598 struct dahdi_params timing
;
600 char smdi_port
[SMDI_MAX_FILENAME_LEN
];
603 /** returns a new dahdi_chan_conf with default values (by-value) */
604 static struct dahdi_chan_conf
dahdi_chan_conf_default(void) {
605 /* recall that if a field is not included here it is initialized
608 struct dahdi_chan_conf conf
= {
612 .switchtype
= PRI_SWITCH_NI2
,
613 .dialplan
= PRI_NATIONAL_ISDN
+ 1,
614 .localdialplan
= PRI_NATIONAL_ISDN
+ 1,
620 .internationalprefix
= "",
621 .nationalprefix
= "",
626 .resetinterval
= 3600
630 .context
= "default",
633 .mohinterpret
= "default",
637 .cid_signalling
= CID_SIG_BELL
,
638 .cid_start
= CID_START_RING
,
639 .dahditrcallerid
= 0,
655 .polarityonanswerdelay
= 600,
657 .sendcalleridafter
= DEFAULT_CIDRINGS
669 .smdi_port
= "/dev/ttyS0",
676 static struct ast_channel
*dahdi_request(const char *type
, int format
, void *data
, int *cause
);
677 static int dahdi_digit_begin(struct ast_channel
*ast
, char digit
);
678 static int dahdi_digit_end(struct ast_channel
*ast
, char digit
, unsigned int duration
);
679 static int dahdi_sendtext(struct ast_channel
*c
, const char *text
);
680 static int dahdi_call(struct ast_channel
*ast
, char *rdest
, int timeout
);
681 static int dahdi_hangup(struct ast_channel
*ast
);
682 static int dahdi_answer(struct ast_channel
*ast
);
683 static struct ast_frame
*dahdi_read(struct ast_channel
*ast
);
684 static int dahdi_write(struct ast_channel
*ast
, struct ast_frame
*frame
);
685 static struct ast_frame
*dahdi_exception(struct ast_channel
*ast
);
686 static int dahdi_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
);
687 static int dahdi_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
);
688 static int dahdi_setoption(struct ast_channel
*chan
, int option
, void *data
, int datalen
);
689 static int dahdi_func_read(struct ast_channel
*chan
, char *function
, char *data
, char *buf
, size_t len
);
691 static const struct ast_channel_tech dahdi_tech
= {
693 .description
= tdesc
,
694 .capabilities
= AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
| AST_FORMAT_ALAW
,
695 .requester
= dahdi_request
,
696 .send_digit_begin
= dahdi_digit_begin
,
697 .send_digit_end
= dahdi_digit_end
,
698 .send_text
= dahdi_sendtext
,
700 .hangup
= dahdi_hangup
,
701 .answer
= dahdi_answer
,
703 .write
= dahdi_write
,
704 .bridge
= dahdi_bridge
,
705 .exception
= dahdi_exception
,
706 .indicate
= dahdi_indicate
,
707 .fixup
= dahdi_fixup
,
708 .setoption
= dahdi_setoption
,
709 .func_channel_read
= dahdi_func_read
,
712 static const struct ast_channel_tech zap_tech
= {
714 .description
= tdesc
,
715 .capabilities
= AST_FORMAT_SLINEAR
| AST_FORMAT_ULAW
| AST_FORMAT_ALAW
,
716 .requester
= dahdi_request
,
717 .send_digit_begin
= dahdi_digit_begin
,
718 .send_digit_end
= dahdi_digit_end
,
719 .send_text
= dahdi_sendtext
,
721 .hangup
= dahdi_hangup
,
722 .answer
= dahdi_answer
,
724 .write
= dahdi_write
,
725 .bridge
= dahdi_bridge
,
726 .exception
= dahdi_exception
,
727 .indicate
= dahdi_indicate
,
728 .fixup
= dahdi_fixup
,
729 .setoption
= dahdi_setoption
,
730 .func_channel_read
= dahdi_func_read
,
733 static const struct ast_channel_tech
*chan_tech
;
736 #define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
738 #define GET_CHANNEL(p) ((p)->channel)
741 struct dahdi_pvt
*round_robin
[32];
744 static inline int pri_grab(struct dahdi_pvt
*pvt
, struct dahdi_pri
*pri
)
747 /* Grab the lock first */
749 res
= ast_mutex_trylock(&pri
->lock
);
751 DEADLOCK_AVOIDANCE(&pvt
->lock
);
754 /* Then break the poll */
755 if (pri
->master
!= AST_PTHREADT_NULL
)
756 pthread_kill(pri
->master
, SIGURG
);
761 #define NUM_CADENCE_MAX 25
762 static int num_cadence
= 4;
763 static int user_has_defined_cadences
= 0;
765 static struct dahdi_ring_cadence cadences
[NUM_CADENCE_MAX
] = {
766 { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
767 { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
768 { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
769 { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
772 /*! \brief cidrings says in which pause to transmit the cid information, where the first pause
773 * is 1, the second pause is 2 and so on.
776 static int cidrings
[NUM_CADENCE_MAX
] = {
777 2, /*!< Right after first long ring */
778 4, /*!< Right after long part */
779 3, /*!< After third chirp */
780 2, /*!< Second spell */
783 #define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
784 (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
786 #define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
787 #define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
789 static int dahdi_get_index(struct ast_channel
*ast
, struct dahdi_pvt
*p
, int nullok
)
792 if (p
->subs
[SUB_REAL
].owner
== ast
)
794 else if (p
->subs
[SUB_CALLWAIT
].owner
== ast
)
796 else if (p
->subs
[SUB_THREEWAY
].owner
== ast
)
801 ast_log(LOG_WARNING
, "Unable to get index, and nullok is not asserted\n");
807 static void wakeup_sub(struct dahdi_pvt
*p
, int a
, struct dahdi_pri
*pri
)
809 static void wakeup_sub(struct dahdi_pvt
*p
, int a
, void *pri
)
814 ast_mutex_unlock(&pri
->lock
);
817 if (p
->subs
[a
].owner
) {
818 if (ast_mutex_trylock(&p
->subs
[a
].owner
->lock
)) {
819 DEADLOCK_AVOIDANCE(&p
->lock
);
821 ast_queue_frame(p
->subs
[a
].owner
, &ast_null_frame
);
822 ast_mutex_unlock(&p
->subs
[a
].owner
->lock
);
830 ast_mutex_lock(&pri
->lock
);
835 static void dahdi_queue_frame(struct dahdi_pvt
*p
, struct ast_frame
*f
, struct dahdi_pri
*pri
)
837 static void dahdi_queue_frame(struct dahdi_pvt
*p
, struct ast_frame
*f
, void *pri
)
840 /* We must unlock the PRI to avoid the possibility of a deadlock */
843 ast_mutex_unlock(&pri
->lock
);
847 if (ast_mutex_trylock(&p
->owner
->lock
)) {
848 DEADLOCK_AVOIDANCE(&p
->lock
);
850 ast_queue_frame(p
->owner
, f
);
851 ast_mutex_unlock(&p
->owner
->lock
);
859 ast_mutex_lock(&pri
->lock
);
863 static int restore_gains(struct dahdi_pvt
*p
);
865 static void swap_subs(struct dahdi_pvt
*p
, int a
, int b
)
869 struct ast_channel
*towner
;
871 ast_log(LOG_DEBUG
, "Swapping %d and %d\n", a
, b
);
873 tchan
= p
->subs
[a
].chan
;
874 towner
= p
->subs
[a
].owner
;
875 tinthreeway
= p
->subs
[a
].inthreeway
;
877 p
->subs
[a
].chan
= p
->subs
[b
].chan
;
878 p
->subs
[a
].owner
= p
->subs
[b
].owner
;
879 p
->subs
[a
].inthreeway
= p
->subs
[b
].inthreeway
;
881 p
->subs
[b
].chan
= tchan
;
882 p
->subs
[b
].owner
= towner
;
883 p
->subs
[b
].inthreeway
= tinthreeway
;
885 if (p
->subs
[a
].owner
)
886 p
->subs
[a
].owner
->fds
[0] = p
->subs
[a
].dfd
;
887 if (p
->subs
[b
].owner
)
888 p
->subs
[b
].owner
->fds
[0] = p
->subs
[b
].dfd
;
889 wakeup_sub(p
, a
, NULL
);
890 wakeup_sub(p
, b
, NULL
);
893 static int dahdi_open(char *fn
)
901 for (x
= 0; x
< strlen(fn
); x
++) {
902 if (!isdigit(fn
[x
])) {
910 ast_log(LOG_WARNING
, "Invalid channel number '%s'\n", fn
);
914 fn
= "/dev/zap/channel";
916 fn
= "/dev/dahdi/channel";
919 fd
= open(fn
, O_RDWR
| O_NONBLOCK
);
921 ast_log(LOG_WARNING
, "Unable to open '%s': %s\n", fn
, strerror(errno
));
925 if (ioctl(fd
, DAHDI_SPECIFY
, &chan
)) {
929 ast_log(LOG_WARNING
, "Unable to specify channel %d: %s\n", chan
, strerror(errno
));
934 if (ioctl(fd
, DAHDI_SET_BLOCKSIZE
, &bs
) == -1) {
935 ast_log(LOG_WARNING
, "Unable to set blocksize '%d': %s\n", bs
, strerror(errno
));
944 static void dahdi_close(int fd
)
950 static int dahdi_setlinear(int dfd
, int linear
)
953 res
= ioctl(dfd
, DAHDI_SETLINEAR
, &linear
);
960 static int alloc_sub(struct dahdi_pvt
*p
, int x
)
962 struct dahdi_bufferinfo bi
;
964 if (p
->subs
[x
].dfd
< 0) {
966 p
->subs
[x
].dfd
= dahdi_open("/dev/zap/pseudo");
968 p
->subs
[x
].dfd
= dahdi_open("/dev/dahdi/pseudo");
970 if (p
->subs
[x
].dfd
> -1) {
971 res
= ioctl(p
->subs
[x
].dfd
, DAHDI_GET_BUFINFO
, &bi
);
973 bi
.txbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
974 bi
.rxbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
975 bi
.numbufs
= numbufs
;
976 res
= ioctl(p
->subs
[x
].dfd
, DAHDI_SET_BUFINFO
, &bi
);
978 ast_log(LOG_WARNING
, "Unable to set buffer policy on channel %d: %s\n", x
, strerror(errno
));
981 ast_log(LOG_WARNING
, "Unable to check buffer policy on channel %d: %s\n", x
, strerror(errno
));
982 if (ioctl(p
->subs
[x
].dfd
, DAHDI_CHANNO
, &p
->subs
[x
].chan
) == 1) {
983 ast_log(LOG_WARNING
, "Unable to get channel number for pseudo channel on FD %d: %s\n", p
->subs
[x
].dfd
, strerror(errno
));
984 dahdi_close(p
->subs
[x
].dfd
);
989 ast_log(LOG_DEBUG
, "Allocated %s subchannel on FD %d channel %d\n", subnames
[x
], p
->subs
[x
].dfd
, p
->subs
[x
].chan
);
992 ast_log(LOG_WARNING
, "Unable to open pseudo channel: %s\n", strerror(errno
));
995 ast_log(LOG_WARNING
, "%s subchannel of %d already in use\n", subnames
[x
], p
->channel
);
999 static int unalloc_sub(struct dahdi_pvt
*p
, int x
)
1002 ast_log(LOG_WARNING
, "Trying to unalloc the real channel %d?!?\n", p
->channel
);
1005 ast_log(LOG_DEBUG
, "Released sub %d of channel %d\n", x
, p
->channel
);
1006 if (p
->subs
[x
].dfd
> -1) {
1007 dahdi_close(p
->subs
[x
].dfd
);
1009 p
->subs
[x
].dfd
= -1;
1010 p
->subs
[x
].linear
= 0;
1011 p
->subs
[x
].chan
= 0;
1012 p
->subs
[x
].owner
= NULL
;
1013 p
->subs
[x
].inthreeway
= 0;
1014 p
->polarity
= POLARITY_IDLE
;
1015 memset(&p
->subs
[x
].curconf
, 0, sizeof(p
->subs
[x
].curconf
));
1019 static int digit_to_dtmfindex(char digit
)
1022 return DAHDI_TONE_DTMF_BASE
+ (digit
- '0');
1023 else if (digit
>= 'A' && digit
<= 'D')
1024 return DAHDI_TONE_DTMF_A
+ (digit
- 'A');
1025 else if (digit
>= 'a' && digit
<= 'd')
1026 return DAHDI_TONE_DTMF_A
+ (digit
- 'a');
1027 else if (digit
== '*')
1028 return DAHDI_TONE_DTMF_s
;
1029 else if (digit
== '#')
1030 return DAHDI_TONE_DTMF_p
;
1035 static int dahdi_digit_begin(struct ast_channel
*chan
, char digit
)
1037 struct dahdi_pvt
*pvt
;
1041 pvt
= chan
->tech_pvt
;
1043 ast_mutex_lock(&pvt
->lock
);
1045 index
= dahdi_get_index(chan
, pvt
, 0);
1047 if ((index
!= SUB_REAL
) || !pvt
->owner
)
1051 if ((pvt
->sig
== SIG_PRI
) && (chan
->_state
== AST_STATE_DIALING
) && !pvt
->proceeding
) {
1052 if (pvt
->setup_ack
) {
1053 if (!pri_grab(pvt
, pvt
->pri
)) {
1054 pri_information(pvt
->pri
->pri
, pvt
->call
, digit
);
1057 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", pvt
->span
);
1058 } else if (strlen(pvt
->dialdest
) < sizeof(pvt
->dialdest
) - 1) {
1060 ast_log(LOG_DEBUG
, "Queueing digit '%c' since setup_ack not yet received\n", digit
);
1061 res
= strlen(pvt
->dialdest
);
1062 pvt
->dialdest
[res
++] = digit
;
1063 pvt
->dialdest
[res
] = '\0';
1068 if ((dtmf
= digit_to_dtmfindex(digit
)) == -1)
1071 if (pvt
->pulse
|| ioctl(pvt
->subs
[SUB_REAL
].dfd
, DAHDI_SENDTONE
, &dtmf
)) {
1073 struct dahdi_dialoperation zo
= {
1074 .op
= DAHDI_DIAL_OP_APPEND
,
1076 .dialstr
[1] = digit
,
1079 if ((res
= ioctl(pvt
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &zo
)))
1080 ast_log(LOG_WARNING
, "Couldn't dial digit %c: %s\n", digit
, strerror(errno
));
1084 ast_log(LOG_DEBUG
, "Started VLDTMF digit '%c'\n", digit
);
1086 pvt
->begindigit
= digit
;
1090 ast_mutex_unlock(&pvt
->lock
);
1095 static int dahdi_digit_end(struct ast_channel
*chan
, char digit
, unsigned int duration
)
1097 struct dahdi_pvt
*pvt
;
1102 pvt
= chan
->tech_pvt
;
1104 ast_mutex_lock(&pvt
->lock
);
1106 index
= dahdi_get_index(chan
, pvt
, 0);
1108 if ((index
!= SUB_REAL
) || !pvt
->owner
|| pvt
->pulse
)
1112 /* This means that the digit was already sent via PRI signalling */
1113 if (pvt
->sig
== SIG_PRI
&& !pvt
->begindigit
)
1117 if (pvt
->begindigit
) {
1119 ast_log(LOG_DEBUG
, "Ending VLDTMF digit '%c'\n", digit
);
1120 res
= ioctl(pvt
->subs
[SUB_REAL
].dfd
, DAHDI_SENDTONE
, &x
);
1122 pvt
->begindigit
= 0;
1126 ast_mutex_unlock(&pvt
->lock
);
1131 static char *events
[] = {
1144 "Hook Transition Complete",
1149 "Polarity Reversal",
1157 { DAHDI_ALARM_RED
, "Red Alarm" },
1158 { DAHDI_ALARM_YELLOW
, "Yellow Alarm" },
1159 { DAHDI_ALARM_BLUE
, "Blue Alarm" },
1160 { DAHDI_ALARM_RECOVER
, "Recovering" },
1161 { DAHDI_ALARM_LOOPBACK
, "Loopback" },
1162 { DAHDI_ALARM_NOTOPEN
, "Not Open" },
1163 { DAHDI_ALARM_NONE
, "None" },
1166 static char *alarm2str(int alarm
)
1169 for (x
= 0; x
< sizeof(alarms
) / sizeof(alarms
[0]); x
++) {
1170 if (alarms
[x
].alarm
& alarm
)
1171 return alarms
[x
].name
;
1173 return alarm
? "Unknown Alarm" : "No Alarm";
1176 static char *event2str(int event
)
1178 static char buf
[256];
1179 if ((event
< (sizeof(events
) / sizeof(events
[0]))) && (event
> -1))
1180 return events
[event
];
1181 sprintf(buf
, "Event %d", event
); /* safe */
1186 static char *dialplan2str(int dialplan
)
1188 if (dialplan
== -1) {
1189 return("Dynamically set dialplan in ISDN");
1191 return (pri_plan2str(dialplan
));
1195 static char *dahdi_sig2str(int sig
)
1197 static char buf
[256];
1200 return "E & M Immediate";
1202 return "E & M Wink";
1206 return "Feature Group D (DTMF)";
1208 return "Feature Group D (MF)";
1209 case SIG_FEATDMF_TA
:
1210 return "Feature Groud D (MF) Tandem Access";
1212 return "Feature Group B (MF)";
1216 return "FGC/CAMA (Dialpulse)";
1217 case SIG_FGC_CAMAMF
:
1218 return "FGC/CAMA (MF)";
1220 return "FXS Loopstart";
1222 return "FXS Groundstart";
1224 return "FXS Kewlstart";
1226 return "FXO Loopstart";
1228 return "FXO Groundstart";
1230 return "FXO Kewlstart";
1234 return "SF (Tone) Immediate";
1236 return "SF (Tone) Wink";
1238 return "SF (Tone) with Feature Group D (DTMF)";
1239 case SIG_SF_FEATDMF
:
1240 return "SF (Tone) with Feature Group D (MF)";
1242 return "SF (Tone) with Feature Group B (MF)";
1243 case SIG_GR303FXOKS
:
1244 return "GR-303 with FXOKS";
1245 case SIG_GR303FXSKS
:
1246 return "GR-303 with FXSKS";
1250 snprintf(buf
, sizeof(buf
), "Unknown signalling %d", sig
);
1255 #define sig2str dahdi_sig2str
1257 static int conf_add(struct dahdi_pvt
*p
, struct dahdi_subchannel
*c
, int index
, int slavechannel
)
1259 /* If the conference already exists, and we're already in it
1260 don't bother doing anything */
1261 struct dahdi_confinfo zi
;
1263 memset(&zi
, 0, sizeof(zi
));
1266 if (slavechannel
> 0) {
1267 /* If we have only one slave, do a digital mon */
1268 zi
.confmode
= DAHDI_CONF_DIGITALMON
;
1269 zi
.confno
= slavechannel
;
1272 /* Real-side and pseudo-side both participate in conference */
1273 zi
.confmode
= DAHDI_CONF_REALANDPSEUDO
| DAHDI_CONF_TALKER
| DAHDI_CONF_LISTENER
|
1274 DAHDI_CONF_PSEUDO_TALKER
| DAHDI_CONF_PSEUDO_LISTENER
;
1276 zi
.confmode
= DAHDI_CONF_CONF
| DAHDI_CONF_TALKER
| DAHDI_CONF_LISTENER
;
1277 zi
.confno
= p
->confno
;
1279 if ((zi
.confno
== c
->curconf
.confno
) && (zi
.confmode
== c
->curconf
.confmode
))
1283 if (ioctl(c
->dfd
, DAHDI_SETCONF
, &zi
)) {
1284 ast_log(LOG_WARNING
, "Failed to add %d to conference %d/%d: %s\n", c
->dfd
, zi
.confmode
, zi
.confno
, strerror(errno
));
1287 if (slavechannel
< 1) {
1288 p
->confno
= zi
.confno
;
1290 memcpy(&c
->curconf
, &zi
, sizeof(c
->curconf
));
1291 ast_log(LOG_DEBUG
, "Added %d to conference %d/%d\n", c
->dfd
, c
->curconf
.confmode
, c
->curconf
.confno
);
1295 static int isourconf(struct dahdi_pvt
*p
, struct dahdi_subchannel
*c
)
1297 /* If they're listening to our channel, they're ours */
1298 if ((p
->channel
== c
->curconf
.confno
) && (c
->curconf
.confmode
== DAHDI_CONF_DIGITALMON
))
1300 /* If they're a talker on our (allocated) conference, they're ours */
1301 if ((p
->confno
> 0) && (p
->confno
== c
->curconf
.confno
) && (c
->curconf
.confmode
& DAHDI_CONF_TALKER
))
1306 static int conf_del(struct dahdi_pvt
*p
, struct dahdi_subchannel
*c
, int index
)
1308 struct dahdi_confinfo zi
;
1309 if (/* Can't delete if there's no dfd */
1311 /* Don't delete from the conference if it's not our conference */
1313 /* Don't delete if we don't think it's conferenced at all (implied) */
1315 memset(&zi
, 0, sizeof(zi
));
1319 if (ioctl(c
->dfd
, DAHDI_SETCONF
, &zi
)) {
1320 ast_log(LOG_WARNING
, "Failed to drop %d from conference %d/%d: %s\n", c
->dfd
, c
->curconf
.confmode
, c
->curconf
.confno
, strerror(errno
));
1323 ast_log(LOG_DEBUG
, "Removed %d from conference %d/%d\n", c
->dfd
, c
->curconf
.confmode
, c
->curconf
.confno
);
1324 memcpy(&c
->curconf
, &zi
, sizeof(c
->curconf
));
1328 static int isslavenative(struct dahdi_pvt
*p
, struct dahdi_pvt
**out
)
1332 struct dahdi_pvt
*slave
= NULL
;
1333 /* Start out optimistic */
1335 /* Update conference state in a stateless fashion */
1336 for (x
= 0; x
< 3; x
++) {
1337 /* Any three-way calling makes slave native mode *definitely* out
1339 if ((p
->subs
[x
].dfd
> -1) && p
->subs
[x
].inthreeway
)
1342 /* If we don't have any 3-way calls, check to see if we have
1343 precisely one slave */
1344 if (useslavenative
) {
1345 for (x
= 0; x
< MAX_SLAVES
; x
++) {
1348 /* Whoops already have a slave! No
1349 slave native and stop right away */
1354 /* We have one slave so far */
1355 slave
= p
->slaves
[x
];
1360 /* If no slave, slave native definitely out */
1363 else if (slave
->law
!= p
->law
) {
1369 return useslavenative
;
1372 static int reset_conf(struct dahdi_pvt
*p
)
1374 struct dahdi_confinfo zi
;
1375 memset(&zi
, 0, sizeof(zi
));
1377 memset(&p
->subs
[SUB_REAL
].curconf
, 0, sizeof(p
->subs
[SUB_REAL
].curconf
));
1378 if (p
->subs
[SUB_REAL
].dfd
> -1) {
1379 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETCONF
, &zi
))
1380 ast_log(LOG_WARNING
, "Failed to reset conferencing on channel %d: %s\n", p
->channel
, strerror(errno
));
1385 static int update_conf(struct dahdi_pvt
*p
)
1390 struct dahdi_pvt
*slave
= NULL
;
1392 useslavenative
= isslavenative(p
, &slave
);
1393 /* Start with the obvious, general stuff */
1394 for (x
= 0; x
< 3; x
++) {
1395 /* Look for three way calls */
1396 if ((p
->subs
[x
].dfd
> -1) && p
->subs
[x
].inthreeway
) {
1397 conf_add(p
, &p
->subs
[x
], x
, 0);
1400 conf_del(p
, &p
->subs
[x
], x
);
1403 /* If we have a slave, add him to our conference now. or DAX
1404 if this is slave native */
1405 for (x
= 0; x
< MAX_SLAVES
; x
++) {
1408 conf_add(p
, &p
->slaves
[x
]->subs
[SUB_REAL
], SUB_REAL
, GET_CHANNEL(p
));
1410 conf_add(p
, &p
->slaves
[x
]->subs
[SUB_REAL
], SUB_REAL
, 0);
1415 /* If we're supposed to be in there, do so now */
1416 if (p
->inconference
&& !p
->subs
[SUB_REAL
].inthreeway
) {
1418 conf_add(p
, &p
->subs
[SUB_REAL
], SUB_REAL
, GET_CHANNEL(slave
));
1420 conf_add(p
, &p
->subs
[SUB_REAL
], SUB_REAL
, 0);
1424 /* If we have a master, add ourselves to his conference */
1426 if (isslavenative(p
->master
, NULL
)) {
1427 conf_add(p
->master
, &p
->subs
[SUB_REAL
], SUB_REAL
, GET_CHANNEL(p
->master
));
1429 conf_add(p
->master
, &p
->subs
[SUB_REAL
], SUB_REAL
, 0);
1433 /* Nobody is left (or should be left) in our conference.
1438 ast_log(LOG_DEBUG
, "Updated conferencing on %d, with %d conference users\n", p
->channel
, needconf
);
1442 static void dahdi_enable_ec(struct dahdi_pvt
*p
)
1449 ast_log(LOG_DEBUG
, "Echo cancellation already on\n");
1453 ast_log(LOG_DEBUG
, "Echo cancellation isn't required on digital connection\n");
1456 if (p
->echocancel
) {
1457 if (p
->sig
== SIG_PRI
) {
1459 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_AUDIOMODE
, &x
);
1461 ast_log(LOG_WARNING
, "Unable to enable audio mode on channel %d (%s)\n", p
->channel
, strerror(errno
));
1464 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_ECHOCANCEL
, &x
);
1466 ast_log(LOG_WARNING
, "Unable to enable echo cancellation on channel %d (%s)\n", p
->channel
, strerror(errno
));
1470 ast_log(LOG_DEBUG
, "Enabled echo cancellation on channel %d\n", p
->channel
);
1472 } else if (option_debug
)
1473 ast_log(LOG_DEBUG
, "No echo cancellation requested\n");
1476 static void dahdi_train_ec(struct dahdi_pvt
*p
)
1480 if (p
&& p
->echocancel
&& p
->echotraining
) {
1481 x
= p
->echotraining
;
1482 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_ECHOTRAIN
, &x
);
1484 ast_log(LOG_WARNING
, "Unable to request echo training on channel %d: %s\n", p
->channel
, strerror(errno
));
1486 ast_log(LOG_DEBUG
, "Engaged echo training on channel %d\n", p
->channel
);
1489 ast_log(LOG_DEBUG
, "No echo training requested\n");
1492 static void dahdi_disable_ec(struct dahdi_pvt
*p
)
1496 if (p
->echocancel
) {
1498 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_ECHOCANCEL
, &x
);
1500 ast_log(LOG_WARNING
, "Unable to disable echo cancellation on channel %d: %s\n", p
->channel
, strerror(errno
));
1501 else if (option_debug
)
1502 ast_log(LOG_DEBUG
, "disabled echo cancellation on channel %d\n", p
->channel
);
1507 static void fill_txgain(struct dahdi_gains
*g
, float gain
, int law
)
1511 float linear_gain
= pow(10.0, gain
/ 20.0);
1514 case DAHDI_LAW_ALAW
:
1515 for (j
= 0; j
< (sizeof(g
->txgain
) / sizeof(g
->txgain
[0])); j
++) {
1517 k
= (int) (((float) AST_ALAW(j
)) * linear_gain
);
1518 if (k
> 32767) k
= 32767;
1519 if (k
< -32767) k
= -32767;
1520 g
->txgain
[j
] = AST_LIN2A(k
);
1526 case DAHDI_LAW_MULAW
:
1527 for (j
= 0; j
< (sizeof(g
->txgain
) / sizeof(g
->txgain
[0])); j
++) {
1529 k
= (int) (((float) AST_MULAW(j
)) * linear_gain
);
1530 if (k
> 32767) k
= 32767;
1531 if (k
< -32767) k
= -32767;
1532 g
->txgain
[j
] = AST_LIN2MU(k
);
1541 static void fill_rxgain(struct dahdi_gains
*g
, float gain
, int law
)
1545 float linear_gain
= pow(10.0, gain
/ 20.0);
1548 case DAHDI_LAW_ALAW
:
1549 for (j
= 0; j
< (sizeof(g
->rxgain
) / sizeof(g
->rxgain
[0])); j
++) {
1551 k
= (int) (((float) AST_ALAW(j
)) * linear_gain
);
1552 if (k
> 32767) k
= 32767;
1553 if (k
< -32767) k
= -32767;
1554 g
->rxgain
[j
] = AST_LIN2A(k
);
1560 case DAHDI_LAW_MULAW
:
1561 for (j
= 0; j
< (sizeof(g
->rxgain
) / sizeof(g
->rxgain
[0])); j
++) {
1563 k
= (int) (((float) AST_MULAW(j
)) * linear_gain
);
1564 if (k
> 32767) k
= 32767;
1565 if (k
< -32767) k
= -32767;
1566 g
->rxgain
[j
] = AST_LIN2MU(k
);
1575 static int set_actual_txgain(int fd
, int chan
, float gain
, int law
)
1577 struct dahdi_gains g
;
1580 memset(&g
, 0, sizeof(g
));
1582 res
= ioctl(fd
, DAHDI_GETGAINS
, &g
);
1585 ast_log(LOG_DEBUG
, "Failed to read gains: %s\n", strerror(errno
));
1589 fill_txgain(&g
, gain
, law
);
1591 return ioctl(fd
, DAHDI_SETGAINS
, &g
);
1594 static int set_actual_rxgain(int fd
, int chan
, float gain
, int law
)
1596 struct dahdi_gains g
;
1599 memset(&g
, 0, sizeof(g
));
1601 res
= ioctl(fd
, DAHDI_GETGAINS
, &g
);
1603 ast_log(LOG_DEBUG
, "Failed to read gains: %s\n", strerror(errno
));
1607 fill_rxgain(&g
, gain
, law
);
1609 return ioctl(fd
, DAHDI_SETGAINS
, &g
);
1612 static int set_actual_gain(int fd
, int chan
, float rxgain
, float txgain
, int law
)
1614 return set_actual_txgain(fd
, chan
, txgain
, law
) | set_actual_rxgain(fd
, chan
, rxgain
, law
);
1617 static int bump_gains(struct dahdi_pvt
*p
)
1621 /* Bump receive gain by 5.0db */
1622 res
= set_actual_gain(p
->subs
[SUB_REAL
].dfd
, 0, p
->rxgain
+ 5.0, p
->txgain
, p
->law
);
1624 ast_log(LOG_WARNING
, "Unable to bump gain: %s\n", strerror(errno
));
1631 static int restore_gains(struct dahdi_pvt
*p
)
1635 res
= set_actual_gain(p
->subs
[SUB_REAL
].dfd
, 0, p
->rxgain
, p
->txgain
, p
->law
);
1637 ast_log(LOG_WARNING
, "Unable to restore gains: %s\n", strerror(errno
));
1644 static inline int dahdi_set_hook(int fd
, int hs
)
1649 res
= ioctl(fd
, DAHDI_HOOK
, &x
);
1652 if (errno
== EINPROGRESS
)
1654 ast_log(LOG_WARNING
, "DAHDI hook failed returned %d (trying %d): %s\n", res
, hs
, strerror(errno
));
1655 /* will expectedly fail if phone is off hook during operation, such as during a restart */
1661 static inline int dahdi_confmute(struct dahdi_pvt
*p
, int muted
)
1665 if (p
->sig
== SIG_PRI
) {
1667 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_AUDIOMODE
, &y
);
1669 ast_log(LOG_WARNING
, "Unable to set audio mode on %d: %s\n", p
->channel
, strerror(errno
));
1671 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_CONFMUTE
, &x
);
1673 ast_log(LOG_WARNING
, "dahdi confmute(%d) failed on channel %d: %s\n", muted
, p
->channel
, strerror(errno
));
1677 static int save_conference(struct dahdi_pvt
*p
)
1679 struct dahdi_confinfo c
;
1681 if (p
->saveconf
.confmode
) {
1682 ast_log(LOG_WARNING
, "Can't save conference -- already in use\n");
1685 p
->saveconf
.chan
= 0;
1686 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GETCONF
, &p
->saveconf
);
1688 ast_log(LOG_WARNING
, "Unable to get conference info: %s\n", strerror(errno
));
1689 p
->saveconf
.confmode
= 0;
1694 c
.confmode
= DAHDI_CONF_NORMAL
;
1695 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETCONF
, &c
);
1697 ast_log(LOG_WARNING
, "Unable to set conference info: %s\n", strerror(errno
));
1701 ast_log(LOG_DEBUG
, "Disabled conferencing\n");
1705 static int restore_conference(struct dahdi_pvt
*p
)
1708 if (p
->saveconf
.confmode
) {
1709 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETCONF
, &p
->saveconf
);
1710 p
->saveconf
.confmode
= 0;
1712 ast_log(LOG_WARNING
, "Unable to restore conference info: %s\n", strerror(errno
));
1717 ast_log(LOG_DEBUG
, "Restored conferencing\n");
1721 static int send_callerid(struct dahdi_pvt
*p
);
1723 static int send_cwcidspill(struct dahdi_pvt
*p
)
1727 if (!(p
->cidspill
= ast_malloc(MAX_CALLERID_SIZE
)))
1729 p
->cidlen
= ast_callerid_callwaiting_generate(p
->cidspill
, p
->callwait_name
, p
->callwait_num
, AST_LAW(p
));
1730 /* Make sure we account for the end */
1731 p
->cidlen
+= READ_SIZE
* 4;
1734 if (option_verbose
> 2)
1735 ast_verbose(VERBOSE_PREFIX_3
"CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n", p
->callwait_name
, p
->callwait_num
);
1739 static int has_voicemail(struct dahdi_pvt
*p
)
1742 return ast_app_has_voicemail(p
->mailbox
, NULL
);
1745 static int send_callerid(struct dahdi_pvt
*p
)
1747 /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
1749 /* Take out of linear mode if necessary */
1750 if (p
->subs
[SUB_REAL
].linear
) {
1751 p
->subs
[SUB_REAL
].linear
= 0;
1752 dahdi_setlinear(p
->subs
[SUB_REAL
].dfd
, 0);
1754 while (p
->cidpos
< p
->cidlen
) {
1755 res
= write(p
->subs
[SUB_REAL
].dfd
, p
->cidspill
+ p
->cidpos
, p
->cidlen
- p
->cidpos
);
1757 if (errno
== EAGAIN
)
1760 ast_log(LOG_WARNING
, "write failed: %s\n", strerror(errno
));
1770 if (p
->callwaitcas
) {
1771 /* Wait for CID/CW to expire */
1772 p
->cidcwexpire
= CIDCW_EXPIRE_SAMPLES
;
1774 restore_conference(p
);
1778 static int dahdi_callwait(struct ast_channel
*ast
)
1780 struct dahdi_pvt
*p
= ast
->tech_pvt
;
1781 p
->callwaitingrepeat
= CALLWAITING_REPEAT_SAMPLES
;
1783 ast_log(LOG_WARNING
, "Spill already exists?!?\n");
1786 if (!(p
->cidspill
= ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE
* 4)))
1790 memset(p
->cidspill
, 0x7f, 2400 + 600 + READ_SIZE
* 4);
1791 if (!p
->callwaitrings
&& p
->callwaitingcallerid
) {
1792 ast_gen_cas(p
->cidspill
, 1, 2400 + 680, AST_LAW(p
));
1794 p
->cidlen
= 2400 + 680 + READ_SIZE
* 4;
1796 ast_gen_cas(p
->cidspill
, 1, 2400, AST_LAW(p
));
1798 p
->cidlen
= 2400 + READ_SIZE
* 4;
1806 static int dahdi_call(struct ast_channel
*ast
, char *rdest
, int timeout
)
1808 struct dahdi_pvt
*p
= ast
->tech_pvt
;
1809 int x
, res
, index
,mysig
;
1814 char dest
[256]; /* must be same length as p->dialdest */
1815 ast_mutex_lock(&p
->lock
);
1816 ast_copy_string(dest
, rdest
, sizeof(dest
));
1817 ast_copy_string(p
->dialdest
, rdest
, sizeof(p
->dialdest
));
1818 if ((ast
->_state
== AST_STATE_BUSY
)) {
1819 p
->subs
[SUB_REAL
].needbusy
= 1;
1820 ast_mutex_unlock(&p
->lock
);
1823 if ((ast
->_state
!= AST_STATE_DOWN
) && (ast
->_state
!= AST_STATE_RESERVED
)) {
1824 ast_log(LOG_WARNING
, "dahdi_call called on %s, neither down nor reserved\n", ast
->name
);
1825 ast_mutex_unlock(&p
->lock
);
1829 if ((p
->radio
|| (p
->oprmode
< 0))) /* if a radio channel, up immediately */
1831 /* Special pseudo -- automatically up */
1832 ast_setstate(ast
, AST_STATE_UP
);
1833 ast_mutex_unlock(&p
->lock
);
1836 x
= DAHDI_FLUSH_READ
| DAHDI_FLUSH_WRITE
;
1837 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_FLUSH
, &x
);
1839 ast_log(LOG_WARNING
, "Unable to flush input on channel %d: %s\n", p
->channel
, strerror(errno
));
1842 set_actual_gain(p
->subs
[SUB_REAL
].dfd
, 0, p
->rxgain
, p
->txgain
, p
->law
);
1845 if (p
->outsigmod
> -1)
1846 mysig
= p
->outsigmod
;
1852 if (p
->owner
== ast
) {
1853 /* Normal ring, on hook */
1855 /* Don't send audio while on hook, until the call is answered */
1857 if (p
->use_callerid
) {
1858 /* Generate the Caller-ID spill if desired */
1860 ast_log(LOG_WARNING
, "cidspill already exists??\n");
1864 if ((p
->cidspill
= ast_malloc(MAX_CALLERID_SIZE
))) {
1865 p
->cidlen
= ast_callerid_generate(p
->cidspill
, ast
->cid
.cid_name
, ast
->cid
.cid_num
, AST_LAW(p
));
1870 /* Choose proper cadence */
1871 if ((p
->distinctivering
> 0) && (p
->distinctivering
<= num_cadence
)) {
1872 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETCADENCE
, &cadences
[p
->distinctivering
- 1]))
1873 ast_log(LOG_WARNING
, "Unable to set distinctive ring cadence %d on '%s': %s\n", p
->distinctivering
, ast
->name
, strerror(errno
));
1874 p
->cidrings
= cidrings
[p
->distinctivering
- 1];
1876 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETCADENCE
, NULL
))
1877 ast_log(LOG_WARNING
, "Unable to reset default ring on '%s': %s\n", ast
->name
, strerror(errno
));
1878 p
->cidrings
= p
->sendcalleridafter
;
1881 /* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */
1882 c
= strchr(dest
, '/');
1885 if (c
&& (strlen(c
) < p
->stripmsd
)) {
1886 ast_log(LOG_WARNING
, "Number '%s' is shorter than stripmsd (%d)\n", c
, p
->stripmsd
);
1890 p
->dop
.op
= DAHDI_DIAL_OP_REPLACE
;
1891 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "Tw%s", c
);
1892 ast_log(LOG_DEBUG
, "FXO: setup deferred dialstring: %s\n", c
);
1894 p
->dop
.dialstr
[0] = '\0';
1897 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
) && (errno
!= EINPROGRESS
)) {
1898 ast_log(LOG_WARNING
, "Unable to ring phone: %s\n", strerror(errno
));
1899 ast_mutex_unlock(&p
->lock
);
1904 /* Call waiting call */
1905 p
->callwaitrings
= 0;
1906 if (ast
->cid
.cid_num
)
1907 ast_copy_string(p
->callwait_num
, ast
->cid
.cid_num
, sizeof(p
->callwait_num
));
1909 p
->callwait_num
[0] = '\0';
1910 if (ast
->cid
.cid_name
)
1911 ast_copy_string(p
->callwait_name
, ast
->cid
.cid_name
, sizeof(p
->callwait_name
));
1913 p
->callwait_name
[0] = '\0';
1914 /* Call waiting tone instead */
1915 if (dahdi_callwait(ast
)) {
1916 ast_mutex_unlock(&p
->lock
);
1919 /* Make ring-back */
1920 if (tone_zone_play_tone(p
->subs
[SUB_CALLWAIT
].dfd
, DAHDI_TONE_RINGTONE
))
1921 ast_log(LOG_WARNING
, "Unable to generate call-wait ring-back on channel %s\n", ast
->name
);
1924 n
= ast
->cid
.cid_name
;
1925 l
= ast
->cid
.cid_num
;
1927 ast_copy_string(p
->lastcid_num
, l
, sizeof(p
->lastcid_num
));
1929 p
->lastcid_num
[0] = '\0';
1931 ast_copy_string(p
->lastcid_name
, n
, sizeof(p
->lastcid_name
));
1933 p
->lastcid_name
[0] = '\0';
1934 ast_setstate(ast
, AST_STATE_RINGING
);
1935 index
= dahdi_get_index(ast
, p
, 0);
1937 p
->subs
[index
].needringing
= 1;
1950 case SIG_FGC_CAMAMF
:
1955 case SIG_SF_FEATDMF
:
1956 case SIG_FEATDMF_TA
:
1958 c
= strchr(dest
, '/');
1963 if (strlen(c
) < p
->stripmsd
) {
1964 ast_log(LOG_WARNING
, "Number '%s' is shorter than stripmsd (%d)\n", c
, p
->stripmsd
);
1965 ast_mutex_unlock(&p
->lock
);
1969 /* Start the trunk, if not GR-303 */
1973 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
1975 if (errno
!= EINPROGRESS
) {
1976 ast_log(LOG_WARNING
, "Unable to start channel: %s\n", strerror(errno
));
1977 ast_mutex_unlock(&p
->lock
);
1984 ast_log(LOG_DEBUG
, "Dialing '%s'\n", c
);
1985 p
->dop
.op
= DAHDI_DIAL_OP_REPLACE
;
1991 l
= ast
->cid
.cid_num
;
1993 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "T*%s*%s*", l
, c
);
1995 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "T**%s*", c
);
1998 l
= ast
->cid
.cid_num
;
2000 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*00%s#*%s#", l
, c
);
2002 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*02#*%s#", c
);
2004 case SIG_FEATDMF_TA
:
2006 const char *cic
, *ozz
;
2008 /* If you have to go through a Tandem Access point you need to use this */
2009 ozz
= pbx_builtin_getvar_helper(p
->owner
, "FEATDMF_OZZ");
2012 cic
= pbx_builtin_getvar_helper(p
->owner
, "FEATDMF_CIC");
2016 ast_log(LOG_WARNING
, "Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set\n");
2017 ast_mutex_unlock(&p
->lock
);
2020 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*%s%s#", ozz
, cic
);
2021 snprintf(p
->finaldial
, sizeof(p
->finaldial
), "M*%s#", c
);
2026 ast_copy_string(p
->dop
.dialstr
, "M*911#", sizeof(p
->dop
.dialstr
));
2029 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "P%s", c
);
2031 case SIG_FGC_CAMAMF
:
2033 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*%s#", c
);
2037 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "P%sw", c
);
2039 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "T%sw", c
);
2043 if (p
->echotraining
&& (strlen(p
->dop
.dialstr
) > 4)) {
2044 memset(p
->echorest
, 'w', sizeof(p
->echorest
) - 1);
2045 strcpy(p
->echorest
+ (p
->echotraining
/ 400) + 1, p
->dop
.dialstr
+ strlen(p
->dop
.dialstr
) - 2);
2046 p
->echorest
[sizeof(p
->echorest
) - 1] = '\0';
2048 p
->dop
.dialstr
[strlen(p
->dop
.dialstr
)-2] = '\0';
2052 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
)) {
2053 int saveerr
= errno
;
2056 ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
2057 ast_log(LOG_WARNING
, "Dialing failed on channel %d: %s\n", p
->channel
, strerror(saveerr
));
2058 ast_mutex_unlock(&p
->lock
);
2062 ast_log(LOG_DEBUG
, "Deferring dialing...\n");
2064 if (ast_strlen_zero(c
))
2066 ast_setstate(ast
, AST_STATE_DIALING
);
2069 /* Special pseudo -- automatically up*/
2070 ast_setstate(ast
, AST_STATE_UP
);
2073 /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
2074 p
->dialdest
[0] = '\0';
2077 ast_log(LOG_DEBUG
, "not yet implemented\n");
2078 ast_mutex_unlock(&p
->lock
);
2084 #ifdef SUPPORT_USERUSER
2085 const char *useruser
;
2089 int prilocaldialplan
;
2093 int redirect_reason
;
2095 c
= strchr(dest
, '/');
2104 if (!p
->hidecallerid
) {
2105 l
= ast
->cid
.cid_num
;
2106 if (!p
->hidecalleridname
) {
2107 n
= ast
->cid
.cid_name
;
2112 if (strlen(c
) < p
->stripmsd
) {
2113 ast_log(LOG_WARNING
, "Number '%s' is shorter than stripmsd (%d)\n", c
, p
->stripmsd
);
2114 ast_mutex_unlock(&p
->lock
);
2117 if (mysig
!= SIG_FXSKS
) {
2118 p
->dop
.op
= DAHDI_DIAL_OP_REPLACE
;
2119 s
= strchr(c
+ p
->stripmsd
, 'w');
2122 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "T%s", s
);
2124 p
->dop
.dialstr
[0] = '\0';
2127 p
->dop
.dialstr
[0] = '\0';
2130 if (pri_grab(p
, p
->pri
)) {
2131 ast_log(LOG_WARNING
, "Failed to grab PRI!\n");
2132 ast_mutex_unlock(&p
->lock
);
2135 if (!(p
->call
= pri_new_call(p
->pri
->pri
))) {
2136 ast_log(LOG_WARNING
, "Unable to create call on channel %d\n", p
->channel
);
2138 ast_mutex_unlock(&p
->lock
);
2141 if (!(sr
= pri_sr_new())) {
2142 ast_log(LOG_WARNING
, "Failed to allocate setup request channel %d\n", p
->channel
);
2143 pri_destroycall(p
->pri
->pri
, p
->call
);
2146 ast_mutex_unlock(&p
->lock
);
2149 if (p
->bearer
|| (mysig
== SIG_FXSKS
)) {
2151 ast_log(LOG_DEBUG
, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p
->bearer
), p
->bearer
->logicalspan
, p
->bearer
->channel
);
2152 p
->bearer
->call
= p
->call
;
2154 ast_log(LOG_DEBUG
, "I'm being setup with no bearer right now...\n");
2155 pri_set_crv(p
->pri
->pri
, p
->call
, p
->channel
, 0);
2157 p
->digital
= IS_DIGITAL(ast
->transfercapability
);
2158 /* Add support for exclusive override */
2159 if (p
->priexclusive
)
2162 /* otherwise, traditional behavior */
2163 if (p
->pri
->nodetype
== PRI_NETWORK
)
2169 pri_sr_set_channel(sr
, p
->bearer
? PVT_TO_CHANNEL(p
->bearer
) : PVT_TO_CHANNEL(p
), exclusive
, 1);
2170 pri_sr_set_bearer(sr
, p
->digital
? PRI_TRANS_CAP_DIGITAL
: ast
->transfercapability
,
2172 ((p
->law
== DAHDI_LAW_ALAW
) ? PRI_LAYER_1_ALAW
: PRI_LAYER_1_ULAW
)));
2173 if (p
->pri
->facilityenable
)
2174 pri_facility_enable(p
->pri
->pri
);
2176 if (option_verbose
> 2)
2177 ast_verbose(VERBOSE_PREFIX_3
"Requested transfer capability: 0x%.2x - %s\n", ast
->transfercapability
, ast_transfercapability2str(ast
->transfercapability
));
2179 pridialplan
= p
->pri
->dialplan
- 1;
2180 if (pridialplan
== -2) { /* compute dynamically */
2181 if (strncmp(c
+ p
->stripmsd
, p
->pri
->internationalprefix
, strlen(p
->pri
->internationalprefix
)) == 0) {
2182 dp_strip
= strlen(p
->pri
->internationalprefix
);
2183 pridialplan
= PRI_INTERNATIONAL_ISDN
;
2184 } else if (strncmp(c
+ p
->stripmsd
, p
->pri
->nationalprefix
, strlen(p
->pri
->nationalprefix
)) == 0) {
2185 dp_strip
= strlen(p
->pri
->nationalprefix
);
2186 pridialplan
= PRI_NATIONAL_ISDN
;
2188 pridialplan
= PRI_LOCAL_ISDN
;
2191 pri_sr_set_called(sr
, c
+ p
->stripmsd
+ dp_strip
, pridialplan
, s
? 1 : 0);
2194 prilocaldialplan
= p
->pri
->localdialplan
- 1;
2195 if ((l
!= NULL
) && (prilocaldialplan
== -2)) { /* compute dynamically */
2196 if (strncmp(l
, p
->pri
->internationalprefix
, strlen(p
->pri
->internationalprefix
)) == 0) {
2197 ldp_strip
= strlen(p
->pri
->internationalprefix
);
2198 prilocaldialplan
= PRI_INTERNATIONAL_ISDN
;
2199 } else if (strncmp(l
, p
->pri
->nationalprefix
, strlen(p
->pri
->nationalprefix
)) == 0) {
2200 ldp_strip
= strlen(p
->pri
->nationalprefix
);
2201 prilocaldialplan
= PRI_NATIONAL_ISDN
;
2203 prilocaldialplan
= PRI_LOCAL_ISDN
;
2206 pri_sr_set_caller(sr
, l
? (l
+ ldp_strip
) : NULL
, n
, prilocaldialplan
,
2207 p
->use_callingpres
? ast
->cid
.cid_pres
: (l
? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
: PRES_NUMBER_NOT_AVAILABLE
));
2208 if ((rr_str
= pbx_builtin_getvar_helper(ast
, "PRIREDIRECTREASON"))) {
2209 if (!strcasecmp(rr_str
, "UNKNOWN"))
2210 redirect_reason
= 0;
2211 else if (!strcasecmp(rr_str
, "BUSY"))
2212 redirect_reason
= 1;
2213 else if (!strcasecmp(rr_str
, "NO_REPLY"))
2214 redirect_reason
= 2;
2215 else if (!strcasecmp(rr_str
, "UNCONDITIONAL"))
2216 redirect_reason
= 15;
2218 redirect_reason
= PRI_REDIR_UNCONDITIONAL
;
2220 redirect_reason
= PRI_REDIR_UNCONDITIONAL
;
2221 pri_sr_set_redirecting(sr
, ast
->cid
.cid_rdnis
, p
->pri
->localdialplan
- 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
, redirect_reason
);
2223 #ifdef SUPPORT_USERUSER
2224 /* User-user info */
2225 useruser
= pbx_builtin_getvar_helper(p
->owner
, "USERUSERINFO");
2228 pri_sr_set_useruser(sr
, useruser
);
2231 if (pri_setup(p
->pri
->pri
, p
->call
, sr
)) {
2232 ast_log(LOG_WARNING
, "Unable to setup call to %s (using %s)\n",
2233 c
+ p
->stripmsd
+ dp_strip
, dialplan2str(p
->pri
->dialplan
));
2235 ast_mutex_unlock(&p
->lock
);
2240 ast_setstate(ast
, AST_STATE_DIALING
);
2244 ast_mutex_unlock(&p
->lock
);
2248 static void destroy_dahdi_pvt(struct dahdi_pvt
**pvt
)
2250 struct dahdi_pvt
*p
= *pvt
;
2251 /* Remove channel from the list */
2253 p
->prev
->next
= p
->next
;
2255 p
->next
->prev
= p
->prev
;
2257 ast_smdi_interface_unref(p
->smdi_iface
);
2258 ast_mutex_destroy(&p
->lock
);
2260 p
->owner
->tech_pvt
= NULL
;
2265 static int destroy_channel(struct dahdi_pvt
*prev
, struct dahdi_pvt
*cur
, int now
)
2275 for (i
= 0; i
< 3; i
++) {
2276 if (cur
->subs
[i
].owner
) {
2282 prev
->next
= cur
->next
;
2284 prev
->next
->prev
= prev
;
2290 iflist
->prev
= NULL
;
2294 if (cur
->subs
[SUB_REAL
].dfd
> -1) {
2295 dahdi_close(cur
->subs
[SUB_REAL
].dfd
);
2297 destroy_dahdi_pvt(&cur
);
2301 prev
->next
= cur
->next
;
2303 prev
->next
->prev
= prev
;
2309 iflist
->prev
= NULL
;
2313 if (cur
->subs
[SUB_REAL
].dfd
> -1) {
2314 dahdi_close(cur
->subs
[SUB_REAL
].dfd
);
2316 destroy_dahdi_pvt(&cur
);
2321 static void destroy_all_channels(void)
2324 struct dahdi_pvt
*p
, *pl
;
2326 while (num_restart_pending
) {
2330 ast_mutex_lock(&iflock
);
2331 /* Destroy all the interfaces and free their memory */
2334 /* Free any callerid */
2336 ast_free(p
->cidspill
);
2337 /* Close the DAHDI thingy */
2338 if (p
->subs
[SUB_REAL
].dfd
> -1)
2339 dahdi_close(p
->subs
[SUB_REAL
].dfd
);
2343 /* Free associated memory */
2345 destroy_dahdi_pvt(&pl
);
2346 if (option_verbose
> 2)
2347 ast_verbose(VERBOSE_PREFIX_2
"Unregistered channel %d\n", x
);
2351 ast_mutex_unlock(&iflock
);
2355 static char *dahdi_send_keypad_facility_app
= "DAHDISendKeypadFacility";
2356 static char *zap_send_keypad_facility_app
= "ZapSendKeypadFacility";
2358 static char *dahdi_send_keypad_facility_synopsis
= "Send digits out of band over a PRI";
2359 static char *zap_send_keypad_facility_synopsis
= "Send digits out of band over a PRI";
2361 static char *dahdi_send_keypad_facility_descrip
=
2362 " DAHDISendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
2363 " IE over the current channel.\n";
2364 static char *zap_send_keypad_facility_descrip
=
2365 " ZapSendKeypadFacility(): This application will send the given string of digits in a Keypad Facility\n"
2366 " IE over the current channel.\n";
2368 static int send_keypad_facility_exec(struct ast_channel
*chan
, void *data
)
2370 /* Data will be our digit string */
2371 struct dahdi_pvt
*p
;
2372 char *digits
= (char *) data
;
2374 if (ast_strlen_zero(digits
)) {
2375 ast_log(LOG_DEBUG
, "No digit string sent to application!\n");
2379 p
= (struct dahdi_pvt
*)chan
->tech_pvt
;
2382 ast_log(LOG_DEBUG
, "Unable to find technology private\n");
2386 ast_mutex_lock(&p
->lock
);
2388 if (!p
->pri
|| !p
->call
) {
2389 ast_log(LOG_DEBUG
, "Unable to find pri or call on channel!\n");
2390 ast_mutex_unlock(&p
->lock
);
2394 if (!pri_grab(p
, p
->pri
)) {
2395 pri_keypad_facility(p
->pri
->pri
, p
->call
, digits
);
2398 ast_log(LOG_DEBUG
, "Unable to grab pri to send keypad facility!\n");
2399 ast_mutex_unlock(&p
->lock
);
2403 ast_mutex_unlock(&p
->lock
);
2408 static int dahdi_send_keypad_facility_exec(struct ast_channel
*chan
, void *data
)
2410 return send_keypad_facility_exec(chan
, data
);
2413 static int zap_send_keypad_facility_exec(struct ast_channel
*chan
, void *data
)
2415 ast_log(LOG_WARNING
, "Use of the command %s is deprecated, please use %s instead.\n", zap_send_keypad_facility_app
, dahdi_send_keypad_facility_app
);
2416 return send_keypad_facility_exec(chan
, data
);
2419 static int pri_is_up(struct dahdi_pri
*pri
)
2422 for (x
= 0; x
< NUM_DCHANS
; x
++) {
2423 if (pri
->dchanavail
[x
] == DCHAN_AVAILABLE
)
2429 static int pri_assign_bearer(struct dahdi_pvt
*crv
, struct dahdi_pri
*pri
, struct dahdi_pvt
*bearer
)
2431 bearer
->owner
= &inuse
;
2432 bearer
->realcall
= crv
;
2433 crv
->subs
[SUB_REAL
].dfd
= bearer
->subs
[SUB_REAL
].dfd
;
2434 if (crv
->subs
[SUB_REAL
].owner
)
2435 crv
->subs
[SUB_REAL
].owner
->fds
[0] = crv
->subs
[SUB_REAL
].dfd
;
2436 crv
->bearer
= bearer
;
2437 crv
->call
= bearer
->call
;
2442 static char *pri_order(int level
)
2452 return "Quaternary";
2458 /* Returns fd of the active dchan */
2459 static int pri_active_dchan_fd(struct dahdi_pri
*pri
)
2463 for (x
= 0; x
< NUM_DCHANS
; x
++) {
2464 if ((pri
->dchans
[x
] == pri
->pri
))
2471 static int pri_find_dchan(struct dahdi_pri
*pri
)
2478 for (x
= 0; x
< NUM_DCHANS
; x
++) {
2479 if ((pri
->dchanavail
[x
] == DCHAN_AVAILABLE
) && (newslot
< 0))
2481 if (pri
->dchans
[x
] == old
) {
2487 ast_log(LOG_WARNING
, "No D-channels available! Using Primary channel %d as D-channel anyway!\n",
2488 pri
->dchannels
[newslot
]);
2490 if (old
&& (oldslot
!= newslot
))
2491 ast_log(LOG_NOTICE
, "Switching from from d-channel %d to channel %d!\n",
2492 pri
->dchannels
[oldslot
], pri
->dchannels
[newslot
]);
2493 pri
->pri
= pri
->dchans
[newslot
];
2498 static int dahdi_hangup(struct ast_channel
*ast
)
2502 /*static int restore_gains(struct dahdi_pvt *p);*/
2503 struct dahdi_pvt
*p
= ast
->tech_pvt
;
2504 struct dahdi_pvt
*tmp
= NULL
;
2505 struct dahdi_pvt
*prev
= NULL
;
2506 struct dahdi_params par
;
2509 ast_log(LOG_DEBUG
, "dahdi_hangup(%s)\n", ast
->name
);
2510 if (!ast
->tech_pvt
) {
2511 ast_log(LOG_WARNING
, "Asked to hangup channel not connected\n");
2515 ast_mutex_lock(&p
->lock
);
2517 index
= dahdi_get_index(ast
, p
, 1);
2519 if (p
->sig
== SIG_PRI
) {
2521 ast_channel_setoption(ast
,AST_OPTION_AUDIO_MODE
,&x
,sizeof(char),0);
2525 dahdi_confmute(p
, 0);
2527 if (p
->origcid_num
) {
2528 ast_copy_string(p
->cid_num
, p
->origcid_num
, sizeof(p
->cid_num
));
2529 free(p
->origcid_num
);
2530 p
->origcid_num
= NULL
;
2532 if (p
->origcid_name
) {
2533 ast_copy_string(p
->cid_name
, p
->origcid_name
, sizeof(p
->cid_name
));
2534 free(p
->origcid_name
);
2535 p
->origcid_name
= NULL
;
2538 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_DTMF
| p
->dtmfrelax
);
2543 ast_log(LOG_DEBUG
, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
2544 p
->channel
, index
, p
->subs
[SUB_REAL
].dfd
, p
->subs
[SUB_CALLWAIT
].dfd
, p
->subs
[SUB_THREEWAY
].dfd
);
2548 /* Real channel, do some fixup */
2549 p
->subs
[index
].owner
= NULL
;
2550 p
->subs
[index
].needanswer
= 0;
2551 p
->subs
[index
].needflash
= 0;
2552 p
->subs
[index
].needringing
= 0;
2553 p
->subs
[index
].needbusy
= 0;
2554 p
->subs
[index
].needcongestion
= 0;
2555 p
->subs
[index
].linear
= 0;
2556 p
->subs
[index
].needcallerid
= 0;
2557 p
->polarity
= POLARITY_IDLE
;
2558 dahdi_setlinear(p
->subs
[index
].dfd
, 0);
2559 if (index
== SUB_REAL
) {
2560 if ((p
->subs
[SUB_CALLWAIT
].dfd
> -1) && (p
->subs
[SUB_THREEWAY
].dfd
> -1)) {
2561 ast_log(LOG_DEBUG
, "Normal call hung up with both three way call and a call waiting call in place?\n");
2562 if (p
->subs
[SUB_CALLWAIT
].inthreeway
) {
2563 /* We had flipped over to answer a callwait and now it's gone */
2564 ast_log(LOG_DEBUG
, "We were flipped over to the callwait, moving back and unowning.\n");
2565 /* Move to the call-wait, but un-own us until they flip back. */
2566 swap_subs(p
, SUB_CALLWAIT
, SUB_REAL
);
2567 unalloc_sub(p
, SUB_CALLWAIT
);
2570 /* The three way hung up, but we still have a call wait */
2571 ast_log(LOG_DEBUG
, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
2572 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
2573 unalloc_sub(p
, SUB_THREEWAY
);
2574 if (p
->subs
[SUB_REAL
].inthreeway
) {
2575 /* This was part of a three way call. Immediately make way for
2577 ast_log(LOG_DEBUG
, "Call was complete, setting owner to former third call\n");
2578 p
->owner
= p
->subs
[SUB_REAL
].owner
;
2580 /* This call hasn't been completed yet... Set owner to NULL */
2581 ast_log(LOG_DEBUG
, "Call was incomplete, setting owner to NULL\n");
2584 p
->subs
[SUB_REAL
].inthreeway
= 0;
2586 } else if (p
->subs
[SUB_CALLWAIT
].dfd
> -1) {
2587 /* Move to the call-wait and switch back to them. */
2588 swap_subs(p
, SUB_CALLWAIT
, SUB_REAL
);
2589 unalloc_sub(p
, SUB_CALLWAIT
);
2590 p
->owner
= p
->subs
[SUB_REAL
].owner
;
2591 if (p
->owner
->_state
!= AST_STATE_UP
)
2592 p
->subs
[SUB_REAL
].needanswer
= 1;
2593 if (ast_bridged_channel(p
->subs
[SUB_REAL
].owner
))
2594 ast_queue_control(p
->subs
[SUB_REAL
].owner
, AST_CONTROL_UNHOLD
);
2595 } else if (p
->subs
[SUB_THREEWAY
].dfd
> -1) {
2596 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
2597 unalloc_sub(p
, SUB_THREEWAY
);
2598 if (p
->subs
[SUB_REAL
].inthreeway
) {
2599 /* This was part of a three way call. Immediately make way for
2601 ast_log(LOG_DEBUG
, "Call was complete, setting owner to former third call\n");
2602 p
->owner
= p
->subs
[SUB_REAL
].owner
;
2604 /* This call hasn't been completed yet... Set owner to NULL */
2605 ast_log(LOG_DEBUG
, "Call was incomplete, setting owner to NULL\n");
2608 p
->subs
[SUB_REAL
].inthreeway
= 0;
2610 } else if (index
== SUB_CALLWAIT
) {
2611 /* Ditch the holding callwait call, and immediately make it availabe */
2612 if (p
->subs
[SUB_CALLWAIT
].inthreeway
) {
2613 /* This is actually part of a three way, placed on hold. Place the third part
2614 on music on hold now */
2615 if (p
->subs
[SUB_THREEWAY
].owner
&& ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
)) {
2616 ast_queue_control_data(p
->subs
[SUB_THREEWAY
].owner
, AST_CONTROL_HOLD
,
2617 S_OR(p
->mohsuggest
, NULL
),
2618 !ast_strlen_zero(p
->mohsuggest
) ? strlen(p
->mohsuggest
) + 1 : 0);
2620 p
->subs
[SUB_THREEWAY
].inthreeway
= 0;
2621 /* Make it the call wait now */
2622 swap_subs(p
, SUB_CALLWAIT
, SUB_THREEWAY
);
2623 unalloc_sub(p
, SUB_THREEWAY
);
2625 unalloc_sub(p
, SUB_CALLWAIT
);
2626 } else if (index
== SUB_THREEWAY
) {
2627 if (p
->subs
[SUB_CALLWAIT
].inthreeway
) {
2628 /* The other party of the three way call is currently in a call-wait state.
2629 Start music on hold for them, and take the main guy out of the third call */
2630 if (p
->subs
[SUB_CALLWAIT
].owner
&& ast_bridged_channel(p
->subs
[SUB_CALLWAIT
].owner
)) {
2631 ast_queue_control_data(p
->subs
[SUB_CALLWAIT
].owner
, AST_CONTROL_HOLD
,
2632 S_OR(p
->mohsuggest
, NULL
),
2633 !ast_strlen_zero(p
->mohsuggest
) ? strlen(p
->mohsuggest
) + 1 : 0);
2635 p
->subs
[SUB_CALLWAIT
].inthreeway
= 0;
2637 p
->subs
[SUB_REAL
].inthreeway
= 0;
2638 /* If this was part of a three way call index, let us make
2639 another three way call */
2640 unalloc_sub(p
, SUB_THREEWAY
);
2642 /* This wasn't any sort of call, but how are we an index? */
2643 ast_log(LOG_WARNING
, "Index found but not any type of call?\n");
2647 if (!p
->subs
[SUB_REAL
].owner
&& !p
->subs
[SUB_CALLWAIT
].owner
&& !p
->subs
[SUB_THREEWAY
].owner
) {
2650 p
->distinctivering
= 0;
2651 p
->confirmanswer
= 0;
2657 p
->onhooktime
= time(NULL
);
2665 ast_dsp_free(p
->dsp
);
2669 law
= DAHDI_LAW_DEFAULT
;
2670 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SETLAW
, &law
);
2672 ast_log(LOG_WARNING
, "Unable to set law on channel %d to default: %s\n", p
->channel
, strerror(errno
));
2673 /* Perform low level hangup if no owner left */
2676 #ifdef SUPPORT_USERUSER
2677 const char *useruser
= pbx_builtin_getvar_helper(ast
,"USERUSERINFO");
2680 /* Make sure we have a call (or REALLY have a call in the case of a PRI) */
2681 if (p
->call
&& (!p
->bearer
|| (p
->bearer
->call
== p
->call
))) {
2682 if (!pri_grab(p
, p
->pri
)) {
2683 if (p
->alreadyhungup
) {
2684 ast_log(LOG_DEBUG
, "Already hungup... Calling hangup once, and clearing call\n");
2686 #ifdef SUPPORT_USERUSER
2687 pri_call_set_useruser(p
->call
, useruser
);
2690 pri_hangup(p
->pri
->pri
, p
->call
, -1);
2693 p
->bearer
->call
= NULL
;
2695 const char *cause
= pbx_builtin_getvar_helper(ast
,"PRI_CAUSE");
2696 int icause
= ast
->hangupcause
? ast
->hangupcause
: -1;
2697 ast_log(LOG_DEBUG
, "Not yet hungup... Calling hangup once with icause, and clearing call\n");
2699 #ifdef SUPPORT_USERUSER
2700 pri_call_set_useruser(p
->call
, useruser
);
2703 p
->alreadyhungup
= 1;
2705 p
->bearer
->alreadyhungup
= 1;
2708 icause
= atoi(cause
);
2710 pri_hangup(p
->pri
->pri
, p
->call
, icause
);
2713 ast_log(LOG_WARNING
, "pri_disconnect failed\n");
2716 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
2721 ast_log(LOG_DEBUG
, "Bearer call is %p, while ours is still %p\n", p
->bearer
->call
, p
->call
);
2727 if (p
->sig
&& (p
->sig
!= SIG_PRI
))
2728 res
= dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOK
);
2730 ast_log(LOG_WARNING
, "Unable to hangup line %s\n", ast
->name
);
2736 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &par
);
2739 ast_log(LOG_DEBUG
, "Hanging up channel %d, offhook = %d\n", p
->channel
, par
.rxisoffhook
);
2741 /* If they're off hook, try playing congestion */
2742 if ((par
.rxisoffhook
) && (!(p
->radio
|| (p
->oprmode
< 0))))
2743 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
2745 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, -1);
2751 /* Make sure we're not made available for at least two seconds assuming
2752 we were actually used for an inbound or outbound call. */
2753 if (ast
->_state
!= AST_STATE_RESERVED
) {
2754 time(&p
->guardtime
);
2759 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, -1);
2764 dahdi_disable_ec(p
);
2766 ast_channel_setoption(ast
,AST_OPTION_TONE_VERIFY
,&x
,sizeof(char),0);
2767 ast_channel_setoption(ast
,AST_OPTION_TDD
,&x
,sizeof(char),0);
2771 p
->callwaiting
= p
->permcallwaiting
;
2772 p
->hidecallerid
= p
->permhidecallerid
;
2777 /* Restore data mode */
2778 if (p
->sig
== SIG_PRI
) {
2780 ast_channel_setoption(ast
,AST_OPTION_AUDIO_MODE
,&x
,sizeof(char),0);
2784 ast_log(LOG_DEBUG
, "Freeing up bearer channel %d\n", p
->bearer
->channel
);
2785 /* Free up the bearer channel as well, and
2786 don't use its file descriptor anymore */
2787 update_conf(p
->bearer
);
2788 reset_conf(p
->bearer
);
2789 p
->bearer
->owner
= NULL
;
2790 p
->bearer
->realcall
= NULL
;
2792 p
->subs
[SUB_REAL
].dfd
= -1;
2796 if (num_restart_pending
== 0)
2800 p
->callwaitingrepeat
= 0;
2803 ast
->tech_pvt
= NULL
;
2804 ast_mutex_unlock(&p
->lock
);
2805 ast_module_unref(ast_module_info
->self
);
2806 if (option_verbose
> 2)
2807 ast_verbose( VERBOSE_PREFIX_3
"Hungup '%s'\n", ast
->name
);
2809 ast_mutex_lock(&iflock
);
2811 if (p
->restartpending
) {
2812 num_restart_pending
--;
2820 destroy_channel(prev
, tmp
, 0);
2828 ast_mutex_unlock(&iflock
);
2832 static int dahdi_answer(struct ast_channel
*ast
)
2834 struct dahdi_pvt
*p
= ast
->tech_pvt
;
2837 int oldstate
= ast
->_state
;
2838 ast_setstate(ast
, AST_STATE_UP
);
2839 ast_mutex_lock(&p
->lock
);
2840 index
= dahdi_get_index(ast
, p
, 0);
2843 /* nothing to do if a radio channel */
2844 if ((p
->radio
|| (p
->oprmode
< 0))) {
2845 ast_mutex_unlock(&p
->lock
);
2859 case SIG_FEATDMF_TA
:
2862 case SIG_FGC_CAMAMF
:
2867 case SIG_SF_FEATDMF
:
2872 /* Pick up the line */
2873 ast_log(LOG_DEBUG
, "Took %s off hook\n", ast
->name
);
2874 if (p
->hanguponpolarityswitch
) {
2875 gettimeofday(&p
->polaritydelaytv
, NULL
);
2877 res
= dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
2878 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
2880 if ((index
== SUB_REAL
) && p
->subs
[SUB_THREEWAY
].inthreeway
) {
2881 if (oldstate
== AST_STATE_RINGING
) {
2882 ast_log(LOG_DEBUG
, "Finally swapping real and threeway\n");
2883 tone_zone_play_tone(p
->subs
[SUB_THREEWAY
].dfd
, -1);
2884 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
2885 p
->owner
= p
->subs
[SUB_REAL
].owner
;
2888 if (p
->sig
& __DAHDI_SIG_FXS
) {
2895 /* Send a pri acknowledge */
2896 if (!pri_grab(p
, p
->pri
)) {
2898 res
= pri_answer(p
->pri
->pri
, p
->call
, 0, !p
->digital
);
2901 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
2907 ast_mutex_unlock(&p
->lock
);
2910 ast_log(LOG_WARNING
, "Don't know how to answer signalling %d (channel %d)\n", p
->sig
, p
->channel
);
2913 ast_mutex_unlock(&p
->lock
);
2917 static int dahdi_setoption(struct ast_channel
*chan
, int option
, void *data
, int datalen
)
2923 struct dahdi_pvt
*p
= chan
->tech_pvt
, *pp
;
2924 struct oprmode
*oprmode
;
2927 /* all supported options require data */
2928 if (!data
|| (datalen
< 1)) {
2934 case AST_OPTION_TXGAIN
:
2935 scp
= (signed char *) data
;
2936 index
= dahdi_get_index(chan
, p
, 0);
2938 ast_log(LOG_WARNING
, "No index in TXGAIN?\n");
2942 ast_log(LOG_DEBUG
, "Setting actual tx gain on %s to %f\n", chan
->name
, p
->txgain
+ (float) *scp
);
2943 return set_actual_txgain(p
->subs
[index
].dfd
, 0, p
->txgain
+ (float) *scp
, p
->law
);
2944 case AST_OPTION_RXGAIN
:
2945 scp
= (signed char *) data
;
2946 index
= dahdi_get_index(chan
, p
, 0);
2948 ast_log(LOG_WARNING
, "No index in RXGAIN?\n");
2952 ast_log(LOG_DEBUG
, "Setting actual rx gain on %s to %f\n", chan
->name
, p
->rxgain
+ (float) *scp
);
2953 return set_actual_rxgain(p
->subs
[index
].dfd
, 0, p
->rxgain
+ (float) *scp
, p
->law
);
2954 case AST_OPTION_TONE_VERIFY
:
2960 ast_log(LOG_DEBUG
, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan
->name
);
2961 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_MUTECONF
| p
->dtmfrelax
); /* set mute mode if desired */
2964 ast_log(LOG_DEBUG
, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan
->name
);
2965 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_MUTECONF
| DSP_DIGITMODE_MUTEMAX
| p
->dtmfrelax
); /* set mute mode if desired */
2968 ast_log(LOG_DEBUG
, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan
->name
);
2969 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_DTMF
| p
->dtmfrelax
); /* set mute mode if desired */
2973 case AST_OPTION_TDD
:
2974 /* turn on or off TDD */
2977 if (!*cp
) { /* turn it off */
2979 ast_log(LOG_DEBUG
, "Set option TDD MODE, value: OFF(0) on %s\n",chan
->name
);
2985 ast_log(LOG_DEBUG
, "Set option TDD MODE, value: %s(%d) on %s\n",
2986 (*cp
== 2) ? "MATE" : "ON", (int) *cp
, chan
->name
);
2987 dahdi_disable_ec(p
);
2988 /* otherwise, turn it on */
2989 if (!p
->didtdd
) { /* if havent done it yet */
2990 unsigned char mybuf
[41000], *buf
;
2991 int size
, res
, fd
, len
;
2992 struct pollfd fds
[1];
2995 memset(buf
, 0x7f, sizeof(mybuf
)); /* set to silence */
2996 ast_tdd_gen_ecdisa(buf
+ 16000, 16000); /* put in tone */
2998 index
= dahdi_get_index(chan
, p
, 0);
3000 ast_log(LOG_WARNING
, "No index in TDD?\n");
3003 fd
= p
->subs
[index
].dfd
;
3005 if (ast_check_hangup(chan
))
3008 if (size
> READ_SIZE
)
3011 fds
[0].events
= POLLPRI
| POLLOUT
;
3013 res
= poll(fds
, 1, -1);
3015 ast_log(LOG_DEBUG
, "poll (for write) ret. 0 on channel %d\n", p
->channel
);
3018 /* if got exception */
3019 if (fds
[0].revents
& POLLPRI
)
3021 if (!(fds
[0].revents
& POLLOUT
)) {
3022 ast_log(LOG_DEBUG
, "write fd not ready on channel %d\n", p
->channel
);
3025 res
= write(fd
, buf
, size
);
3027 if (res
== -1) return -1;
3028 ast_log(LOG_DEBUG
, "Write returned %d (%s) on channel %d\n", res
, strerror(errno
), p
->channel
);
3034 p
->didtdd
= 1; /* set to have done it now */
3036 if (*cp
== 2) { /* Mate mode */
3043 if (!p
->tdd
) { /* if we dont have one yet */
3044 p
->tdd
= tdd_new(); /* allocate one */
3047 case AST_OPTION_RELAXDTMF
: /* Relax DTMF decoding (or not) */
3051 ast_log(LOG_DEBUG
, "Set option RELAX DTMF, value: %s(%d) on %s\n",
3052 *cp
? "ON" : "OFF", (int) *cp
, chan
->name
);
3054 if (*cp
) p
->dtmfrelax
= DSP_DIGITMODE_RELAXDTMF
;
3055 ast_dsp_digitmode(p
->dsp
, DSP_DIGITMODE_DTMF
| p
->dtmfrelax
);
3057 case AST_OPTION_AUDIO_MODE
: /* Set AUDIO mode (or not) */
3060 ast_log(LOG_DEBUG
, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan
->name
);
3062 dahdi_disable_ec(p
);
3064 ast_log(LOG_DEBUG
, "Set option AUDIO MODE, value: ON(1) on %s\n", chan
->name
);
3067 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_AUDIOMODE
, &x
) == -1)
3068 ast_log(LOG_WARNING
, "Unable to set audio mode on channel %d to %d: %s\n", p
->channel
, x
, strerror(errno
));
3070 case AST_OPTION_OPRMODE
: /* Operator services mode */
3071 oprmode
= (struct oprmode
*) data
;
3072 pp
= oprmode
->peer
->tech_pvt
;
3073 p
->oprmode
= pp
->oprmode
= 0;
3077 /* setup modes, if any */
3080 pp
->oprmode
= oprmode
->mode
;
3081 p
->oprmode
= -oprmode
->mode
;
3083 ast_log(LOG_DEBUG
, "Set Operator Services mode, value: %d on %s/%s\n",
3084 oprmode
->mode
, chan
->name
,oprmode
->peer
->name
);;
3086 case AST_OPTION_ECHOCAN
:
3089 ast_log(LOG_DEBUG
, "Enabling echo cancelation on %s\n", chan
->name
);
3092 ast_log(LOG_DEBUG
, "Disabling echo cancelation on %s\n", chan
->name
);
3093 dahdi_disable_ec(p
);
3102 static int dahdi_func_read(struct ast_channel
*chan
, char *function
, char *data
, char *buf
, size_t len
)
3104 struct dahdi_pvt
*p
= chan
->tech_pvt
;
3106 if (!strcasecmp(data
, "rxgain")) {
3107 ast_mutex_lock(&p
->lock
);
3108 snprintf(buf
, len
, "%f", p
->rxgain
);
3109 ast_mutex_unlock(&p
->lock
);
3110 } else if (!strcasecmp(data
, "txgain")) {
3111 ast_mutex_lock(&p
->lock
);
3112 snprintf(buf
, len
, "%f", p
->txgain
);
3113 ast_mutex_unlock(&p
->lock
);
3115 ast_copy_string(buf
, "", len
);
3121 static void dahdi_unlink(struct dahdi_pvt
*slave
, struct dahdi_pvt
*master
, int needlock
)
3123 /* Unlink a specific slave or all slaves/masters from a given master */
3129 ast_mutex_lock(&master
->lock
);
3131 while (ast_mutex_trylock(&slave
->lock
)) {
3132 DEADLOCK_AVOIDANCE(&master
->lock
);
3137 for (x
= 0; x
< MAX_SLAVES
; x
++) {
3138 if (master
->slaves
[x
]) {
3139 if (!slave
|| (master
->slaves
[x
] == slave
)) {
3140 /* Take slave out of the conference */
3141 ast_log(LOG_DEBUG
, "Unlinking slave %d from %d\n", master
->slaves
[x
]->channel
, master
->channel
);
3142 conf_del(master
, &master
->slaves
[x
]->subs
[SUB_REAL
], SUB_REAL
);
3143 conf_del(master
->slaves
[x
], &master
->subs
[SUB_REAL
], SUB_REAL
);
3144 master
->slaves
[x
]->master
= NULL
;
3145 master
->slaves
[x
] = NULL
;
3150 master
->inconference
= 0;
3153 if (master
->master
) {
3154 /* Take master out of the conference */
3155 conf_del(master
->master
, &master
->subs
[SUB_REAL
], SUB_REAL
);
3156 conf_del(master
, &master
->master
->subs
[SUB_REAL
], SUB_REAL
);
3158 for (x
= 0; x
< MAX_SLAVES
; x
++) {
3159 if (master
->master
->slaves
[x
] == master
)
3160 master
->master
->slaves
[x
] = NULL
;
3161 else if (master
->master
->slaves
[x
])
3165 master
->master
->inconference
= 0;
3167 master
->master
= NULL
;
3169 update_conf(master
);
3172 ast_mutex_unlock(&slave
->lock
);
3173 ast_mutex_unlock(&master
->lock
);
3177 static void dahdi_link(struct dahdi_pvt
*slave
, struct dahdi_pvt
*master
) {
3179 if (!slave
|| !master
) {
3180 ast_log(LOG_WARNING
, "Tried to link to/from NULL??\n");
3183 for (x
= 0; x
< MAX_SLAVES
; x
++) {
3184 if (!master
->slaves
[x
]) {
3185 master
->slaves
[x
] = slave
;
3189 if (x
>= MAX_SLAVES
) {
3190 ast_log(LOG_WARNING
, "Replacing slave %d with new slave, %d\n", master
->slaves
[MAX_SLAVES
- 1]->channel
, slave
->channel
);
3191 master
->slaves
[MAX_SLAVES
- 1] = slave
;
3194 ast_log(LOG_WARNING
, "Replacing master %d with new master, %d\n", slave
->master
->channel
, master
->channel
);
3195 slave
->master
= master
;
3197 ast_log(LOG_DEBUG
, "Making %d slave to master %d at %d\n", slave
->channel
, master
->channel
, x
);
3200 static void disable_dtmf_detect(struct dahdi_pvt
*p
)
3202 #ifdef DAHDI_TONEDETECT
3208 #ifdef DAHDI_TONEDETECT
3210 ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONEDETECT
, &val
);
3212 if (!p
->hardwaredtmf
&& p
->dsp
) {
3213 p
->dsp_features
&= ~DSP_FEATURE_DTMF_DETECT
;
3214 ast_dsp_set_features(p
->dsp
, p
->dsp_features
);
3218 static void enable_dtmf_detect(struct dahdi_pvt
*p
)
3220 #ifdef DAHDI_TONEDETECT
3224 if (p
->channel
== CHAN_PSEUDO
)
3229 #ifdef DAHDI_TONEDETECT
3230 val
= DAHDI_TONEDETECT_ON
| DAHDI_TONEDETECT_MUTE
;
3231 ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONEDETECT
, &val
);
3233 if (!p
->hardwaredtmf
&& p
->dsp
) {
3234 p
->dsp_features
|= DSP_FEATURE_DTMF_DETECT
;
3235 ast_dsp_set_features(p
->dsp
, p
->dsp_features
);
3239 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
)
3241 struct ast_channel
*who
;
3242 struct dahdi_pvt
*p0
, *p1
, *op0
, *op1
;
3243 struct dahdi_pvt
*master
= NULL
, *slave
= NULL
;
3244 struct ast_frame
*f
;
3248 int oi0
, oi1
, i0
= -1, i1
= -1, t0
, t1
;
3249 int os0
= -1, os1
= -1;
3251 struct ast_channel
*oc0
, *oc1
;
3252 enum ast_bridge_result res
;
3255 int triedtopribridge
= 0;
3256 q931_call
*q931c0
= NULL
, *q931c1
= NULL
;
3259 /* For now, don't attempt to native bridge if either channel needs DTMF detection.
3260 There is code below to handle it properly until DTMF is actually seen,
3261 but due to currently unresolved issues it's ignored...
3264 if (flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
))
3265 return AST_BRIDGE_FAILED_NOWARN
;
3267 ast_mutex_lock(&c0
->lock
);
3268 while (ast_mutex_trylock(&c1
->lock
)) {
3269 DEADLOCK_AVOIDANCE(&c0
->lock
);
3274 /* cant do pseudo-channels here */
3275 if (!p0
|| (!p0
->sig
) || !p1
|| (!p1
->sig
)) {
3276 ast_mutex_unlock(&c0
->lock
);
3277 ast_mutex_unlock(&c1
->lock
);
3278 return AST_BRIDGE_FAILED_NOWARN
;
3281 oi0
= dahdi_get_index(c0
, p0
, 0);
3282 oi1
= dahdi_get_index(c1
, p1
, 0);
3283 if ((oi0
< 0) || (oi1
< 0)) {
3284 ast_mutex_unlock(&c0
->lock
);
3285 ast_mutex_unlock(&c1
->lock
);
3286 return AST_BRIDGE_FAILED
;
3289 op0
= p0
= c0
->tech_pvt
;
3290 op1
= p1
= c1
->tech_pvt
;
3296 if (ast_mutex_trylock(&p0
->lock
)) {
3297 /* Don't block, due to potential for deadlock */
3298 ast_mutex_unlock(&c0
->lock
);
3299 ast_mutex_unlock(&c1
->lock
);
3300 ast_log(LOG_NOTICE
, "Avoiding deadlock...\n");
3301 return AST_BRIDGE_RETRY
;
3303 if (ast_mutex_trylock(&p1
->lock
)) {
3304 /* Don't block, due to potential for deadlock */
3305 ast_mutex_unlock(&p0
->lock
);
3306 ast_mutex_unlock(&c0
->lock
);
3307 ast_mutex_unlock(&c1
->lock
);
3308 ast_log(LOG_NOTICE
, "Avoiding deadlock...\n");
3309 return AST_BRIDGE_RETRY
;
3312 if ((oi0
== SUB_REAL
) && (oi1
== SUB_REAL
)) {
3313 if (p0
->owner
&& p1
->owner
) {
3314 /* If we don't have a call-wait in a 3-way, and we aren't in a 3-way, we can be master */
3315 if (!p0
->subs
[SUB_CALLWAIT
].inthreeway
&& !p1
->subs
[SUB_REAL
].inthreeway
) {
3319 } else if (!p1
->subs
[SUB_CALLWAIT
].inthreeway
&& !p0
->subs
[SUB_REAL
].inthreeway
) {
3324 ast_log(LOG_WARNING
, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n");
3325 ast_log(LOG_WARNING
, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
3327 oi0
, (p0
->subs
[SUB_CALLWAIT
].dfd
> -1) ? 1 : 0,
3328 p0
->subs
[SUB_REAL
].inthreeway
, p0
->channel
,
3329 oi0
, (p1
->subs
[SUB_CALLWAIT
].dfd
> -1) ? 1 : 0,
3330 p1
->subs
[SUB_REAL
].inthreeway
);
3334 } else if ((oi0
== SUB_REAL
) && (oi1
== SUB_THREEWAY
)) {
3335 if (p1
->subs
[SUB_THREEWAY
].inthreeway
) {
3340 } else if ((oi0
== SUB_THREEWAY
) && (oi1
== SUB_REAL
)) {
3341 if (p0
->subs
[SUB_THREEWAY
].inthreeway
) {
3346 } else if ((oi0
== SUB_REAL
) && (oi1
== SUB_CALLWAIT
)) {
3347 /* We have a real and a call wait. If we're in a three way call, put us in it, otherwise,
3348 don't put us in anything */
3349 if (p1
->subs
[SUB_CALLWAIT
].inthreeway
) {
3354 } else if ((oi0
== SUB_CALLWAIT
) && (oi1
== SUB_REAL
)) {
3355 /* Same as previous */
3356 if (p0
->subs
[SUB_CALLWAIT
].inthreeway
) {
3362 ast_log(LOG_DEBUG
, "master: %d, slave: %d, nothingok: %d\n",
3363 master
? master
->channel
: 0, slave
? slave
->channel
: 0, nothingok
);
3364 if (master
&& slave
) {
3365 /* Stop any tones, or play ringtone as appropriate. If they're bridged
3366 in an active threeway call with a channel that is ringing, we should
3367 indicate ringing. */
3368 if ((oi1
== SUB_THREEWAY
) &&
3369 p1
->subs
[SUB_THREEWAY
].inthreeway
&&
3370 p1
->subs
[SUB_REAL
].owner
&&
3371 p1
->subs
[SUB_REAL
].inthreeway
&&
3372 (p1
->subs
[SUB_REAL
].owner
->_state
== AST_STATE_RINGING
)) {
3373 ast_log(LOG_DEBUG
, "Playing ringback on %s since %s is in a ringing three-way\n", c0
->name
, c1
->name
);
3374 tone_zone_play_tone(p0
->subs
[oi0
].dfd
, DAHDI_TONE_RINGTONE
);
3375 os1
= p1
->subs
[SUB_REAL
].owner
->_state
;
3377 ast_log(LOG_DEBUG
, "Stopping tones on %d/%d talking to %d/%d\n", p0
->channel
, oi0
, p1
->channel
, oi1
);
3378 tone_zone_play_tone(p0
->subs
[oi0
].dfd
, -1);
3380 if ((oi0
== SUB_THREEWAY
) &&
3381 p0
->subs
[SUB_THREEWAY
].inthreeway
&&
3382 p0
->subs
[SUB_REAL
].owner
&&
3383 p0
->subs
[SUB_REAL
].inthreeway
&&
3384 (p0
->subs
[SUB_REAL
].owner
->_state
== AST_STATE_RINGING
)) {
3385 ast_log(LOG_DEBUG
, "Playing ringback on %s since %s is in a ringing three-way\n", c1
->name
, c0
->name
);
3386 tone_zone_play_tone(p1
->subs
[oi1
].dfd
, DAHDI_TONE_RINGTONE
);
3387 os0
= p0
->subs
[SUB_REAL
].owner
->_state
;
3389 ast_log(LOG_DEBUG
, "Stopping tones on %d/%d talking to %d/%d\n", p1
->channel
, oi1
, p0
->channel
, oi0
);
3390 tone_zone_play_tone(p1
->subs
[oi0
].dfd
, -1);
3392 if ((oi0
== SUB_REAL
) && (oi1
== SUB_REAL
)) {
3393 if (!p0
->echocanbridged
|| !p1
->echocanbridged
) {
3394 /* Disable echo cancellation if appropriate */
3395 dahdi_disable_ec(p0
);
3396 dahdi_disable_ec(p1
);
3399 dahdi_link(slave
, master
);
3400 master
->inconference
= inconf
;
3401 } else if (!nothingok
)
3402 ast_log(LOG_WARNING
, "Can't link %d/%s with %d/%s\n", p0
->channel
, subnames
[oi0
], p1
->channel
, subnames
[oi1
]);
3406 t0
= p0
->subs
[SUB_REAL
].inthreeway
;
3407 t1
= p1
->subs
[SUB_REAL
].inthreeway
;
3409 ast_mutex_unlock(&p0
->lock
);
3410 ast_mutex_unlock(&p1
->lock
);
3412 ast_mutex_unlock(&c0
->lock
);
3413 ast_mutex_unlock(&c1
->lock
);
3415 /* Native bridge failed */
3416 if ((!master
|| !slave
) && !nothingok
) {
3417 dahdi_enable_ec(p0
);
3418 dahdi_enable_ec(p1
);
3419 return AST_BRIDGE_FAILED
;
3422 if (option_verbose
> 2)
3423 ast_verbose(VERBOSE_PREFIX_3
"Native bridging %s and %s\n", c0
->name
, c1
->name
);
3425 if (!(flags
& AST_BRIDGE_DTMF_CHANNEL_0
) && (oi0
== SUB_REAL
))
3426 disable_dtmf_detect(op0
);
3428 if (!(flags
& AST_BRIDGE_DTMF_CHANNEL_1
) && (oi1
== SUB_REAL
))
3429 disable_dtmf_detect(op1
);
3432 struct ast_channel
*c0_priority
[2] = {c0
, c1
};
3433 struct ast_channel
*c1_priority
[2] = {c1
, c0
};
3435 /* Here's our main loop... Start by locking things, looking for private parts,
3436 and then balking if anything is wrong */
3437 ast_mutex_lock(&c0
->lock
);
3438 while (ast_mutex_trylock(&c1
->lock
)) {
3439 DEADLOCK_AVOIDANCE(&c0
->lock
);
3446 i0
= dahdi_get_index(c0
, p0
, 1);
3448 i1
= dahdi_get_index(c1
, p1
, 1);
3449 ast_mutex_unlock(&c0
->lock
);
3450 ast_mutex_unlock(&c1
->lock
);
3455 (ofd0
!= c0
->fds
[0]) ||
3456 (ofd1
!= c1
->fds
[0]) ||
3457 (p0
->subs
[SUB_REAL
].owner
&& (os0
> -1) && (os0
!= p0
->subs
[SUB_REAL
].owner
->_state
)) ||
3458 (p1
->subs
[SUB_REAL
].owner
&& (os1
> -1) && (os1
!= p1
->subs
[SUB_REAL
].owner
->_state
)) ||
3459 (oc0
!= p0
->owner
) ||
3460 (oc1
!= p1
->owner
) ||
3461 (t0
!= p0
->subs
[SUB_REAL
].inthreeway
) ||
3462 (t1
!= p1
->subs
[SUB_REAL
].inthreeway
) ||
3465 ast_log(LOG_DEBUG
, "Something changed out on %d/%d to %d/%d, returning -3 to restart\n",
3466 op0
->channel
, oi0
, op1
->channel
, oi1
);
3467 res
= AST_BRIDGE_RETRY
;
3468 goto return_from_bridge
;
3474 if (p0
->transfer
&& p1
->transfer
3476 && !triedtopribridge
) {
3477 pri_channel_bridge(q931c0
, q931c1
);
3478 triedtopribridge
= 1;
3482 who
= ast_waitfor_n(priority
? c0_priority
: c1_priority
, 2, &timeoutms
);
3484 ast_log(LOG_DEBUG
, "Ooh, empty read...\n");
3488 if (!f
|| (f
->frametype
== AST_FRAME_CONTROL
)) {
3491 res
= AST_BRIDGE_COMPLETE
;
3492 goto return_from_bridge
;
3494 if (f
->frametype
== AST_FRAME_DTMF
) {
3495 if ((who
== c0
) && p0
->pulsedial
) {
3497 } else if ((who
== c1
) && p1
->pulsedial
) {
3502 res
= AST_BRIDGE_COMPLETE
;
3503 goto return_from_bridge
;
3508 /* Swap who gets priority */
3509 priority
= !priority
;
3514 dahdi_enable_ec(p0
);
3517 dahdi_enable_ec(p1
);
3519 if (!(flags
& AST_BRIDGE_DTMF_CHANNEL_0
) && (oi0
== SUB_REAL
))
3520 enable_dtmf_detect(op0
);
3522 if (!(flags
& AST_BRIDGE_DTMF_CHANNEL_1
) && (oi1
== SUB_REAL
))
3523 enable_dtmf_detect(op1
);
3525 dahdi_unlink(slave
, master
, 1);
3530 static int dahdi_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
)
3532 struct dahdi_pvt
*p
= newchan
->tech_pvt
;
3534 ast_mutex_lock(&p
->lock
);
3535 ast_log(LOG_DEBUG
, "New owner for channel %d is %s\n", p
->channel
, newchan
->name
);
3536 if (p
->owner
== oldchan
) {
3539 for (x
= 0; x
< 3; x
++)
3540 if (p
->subs
[x
].owner
== oldchan
) {
3542 dahdi_unlink(NULL
, p
, 0);
3543 p
->subs
[x
].owner
= newchan
;
3545 if (newchan
->_state
== AST_STATE_RINGING
)
3546 dahdi_indicate(newchan
, AST_CONTROL_RINGING
, NULL
, 0);
3548 ast_mutex_unlock(&p
->lock
);
3552 static int dahdi_ring_phone(struct dahdi_pvt
*p
)
3556 /* Make sure our transmit state is on hook */
3559 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
3562 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
3567 /* Wait just in case */
3574 ast_log(LOG_WARNING
, "Couldn't ring the phone: %s\n", strerror(errno
));
3582 static void *ss_thread(void *data
);
3584 static struct ast_channel
*dahdi_new(struct dahdi_pvt
*, int, int, int, int, int);
3586 static int attempt_transfer(struct dahdi_pvt
*p
)
3588 /* In order to transfer, we need at least one of the channels to
3589 actually be in a call bridge. We can't conference two applications
3590 together (but then, why would we want to?) */
3591 if (ast_bridged_channel(p
->subs
[SUB_REAL
].owner
)) {
3592 /* The three-way person we're about to transfer to could still be in MOH, so
3593 stop if now if appropriate */
3594 if (ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
))
3595 ast_queue_control(p
->subs
[SUB_THREEWAY
].owner
, AST_CONTROL_UNHOLD
);
3596 if (p
->subs
[SUB_REAL
].owner
->_state
== AST_STATE_RINGING
) {
3597 ast_indicate(ast_bridged_channel(p
->subs
[SUB_REAL
].owner
), AST_CONTROL_RINGING
);
3599 if (p
->subs
[SUB_THREEWAY
].owner
->_state
== AST_STATE_RING
) {
3600 tone_zone_play_tone(p
->subs
[SUB_THREEWAY
].dfd
, DAHDI_TONE_RINGTONE
);
3602 if (ast_channel_masquerade(p
->subs
[SUB_THREEWAY
].owner
, ast_bridged_channel(p
->subs
[SUB_REAL
].owner
))) {
3603 ast_log(LOG_WARNING
, "Unable to masquerade %s as %s\n",
3604 ast_bridged_channel(p
->subs
[SUB_REAL
].owner
)->name
, p
->subs
[SUB_THREEWAY
].owner
->name
);
3607 /* Orphan the channel after releasing the lock */
3608 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
3609 unalloc_sub(p
, SUB_THREEWAY
);
3610 } else if (ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
)) {
3611 ast_queue_control(p
->subs
[SUB_REAL
].owner
, AST_CONTROL_UNHOLD
);
3612 if (p
->subs
[SUB_THREEWAY
].owner
->_state
== AST_STATE_RINGING
) {
3613 ast_indicate(ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
), AST_CONTROL_RINGING
);
3615 if (p
->subs
[SUB_REAL
].owner
->_state
== AST_STATE_RING
) {
3616 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_RINGTONE
);
3618 if (ast_channel_masquerade(p
->subs
[SUB_REAL
].owner
, ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
))) {
3619 ast_log(LOG_WARNING
, "Unable to masquerade %s as %s\n",
3620 ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
)->name
, p
->subs
[SUB_REAL
].owner
->name
);
3623 /* Three-way is now the REAL */
3624 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
3625 ast_mutex_unlock(&p
->subs
[SUB_REAL
].owner
->lock
);
3626 unalloc_sub(p
, SUB_THREEWAY
);
3627 /* Tell the caller not to hangup */
3630 ast_log(LOG_DEBUG
, "Neither %s nor %s are in a bridge, nothing to transfer\n",
3631 p
->subs
[SUB_REAL
].owner
->name
, p
->subs
[SUB_THREEWAY
].owner
->name
);
3632 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3638 static int check_for_conference(struct dahdi_pvt
*p
)
3640 struct dahdi_confinfo ci
;
3641 /* Fine if we already have a master, etc */
3642 if (p
->master
|| (p
->confno
> -1))
3644 memset(&ci
, 0, sizeof(ci
));
3645 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GETCONF
, &ci
)) {
3646 ast_log(LOG_WARNING
, "Failed to get conference info on channel %d: %s\n", p
->channel
, strerror(errno
));
3649 /* If we have no master and don't have a confno, then
3650 if we're in a conference, it's probably a MeetMe room or
3651 some such, so don't let us 3-way out! */
3652 if ((p
->subs
[SUB_REAL
].curconf
.confno
!= ci
.confno
) || (p
->subs
[SUB_REAL
].curconf
.confmode
!= ci
.confmode
)) {
3653 if (option_verbose
> 2)
3654 ast_verbose(VERBOSE_PREFIX_3
"Avoiding 3-way call when in an external conference\n");
3660 static int get_alarms(struct dahdi_pvt
*p
)
3663 struct dahdi_spaninfo zi
;
3664 memset(&zi
, 0, sizeof(zi
));
3665 zi
.spanno
= p
->span
;
3666 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SPANSTAT
, &zi
);
3668 ast_log(LOG_WARNING
, "Unable to determine alarm on channel %d: %s\n", p
->channel
, strerror(errno
));
3674 static void dahdi_handle_dtmfup(struct ast_channel
*ast
, int index
, struct ast_frame
**dest
)
3676 struct dahdi_pvt
*p
= ast
->tech_pvt
;
3677 struct ast_frame
*f
= *dest
;
3680 ast_log(LOG_DEBUG
, "DTMF digit: %c on %s\n", f
->subclass
, ast
->name
);
3682 if (p
->confirmanswer
) {
3684 ast_log(LOG_DEBUG
, "Confirm answer on %s!\n", ast
->name
);
3685 /* Upon receiving a DTMF digit, consider this an answer confirmation instead
3687 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
3688 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
3689 *dest
= &p
->subs
[index
].f
;
3690 /* Reset confirmanswer so DTMF's will behave properly for the duration of the call */
3691 p
->confirmanswer
= 0;
3692 } else if (p
->callwaitcas
) {
3693 if ((f
->subclass
== 'A') || (f
->subclass
== 'D')) {
3695 ast_log(LOG_DEBUG
, "Got some DTMF, but it's for the CAS\n");
3700 if ((f
->subclass
!= 'm') && (f
->subclass
!= 'u'))
3702 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
3703 p
->subs
[index
].f
.subclass
= 0;
3704 *dest
= &p
->subs
[index
].f
;
3705 } else if (f
->subclass
== 'f') {
3706 /* Fax tone -- Handle and return NULL */
3707 if ((p
->callprogress
& 0x6) && !p
->faxhandled
) {
3709 if (strcmp(ast
->exten
, "fax")) {
3710 const char *target_context
= S_OR(ast
->macrocontext
, ast
->context
);
3712 if (ast_exists_extension(ast
, target_context
, "fax", 1, ast
->cid
.cid_num
)) {
3713 if (option_verbose
> 2)
3714 ast_verbose(VERBOSE_PREFIX_3
"Redirecting %s to fax extension\n", ast
->name
);
3715 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
3716 pbx_builtin_setvar_helper(ast
, "FAXEXTEN", ast
->exten
);
3717 if (ast_async_goto(ast
, target_context
, "fax", 1))
3718 ast_log(LOG_WARNING
, "Failed to async goto '%s' into fax of '%s'\n", ast
->name
, target_context
);
3720 ast_log(LOG_NOTICE
, "Fax detected, but no fax extension\n");
3721 } else if (option_debug
)
3722 ast_log(LOG_DEBUG
, "Already in a fax extension, not redirecting\n");
3723 } else if (option_debug
)
3724 ast_log(LOG_DEBUG
, "Fax already handled\n");
3725 dahdi_confmute(p
, 0);
3726 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
3727 p
->subs
[index
].f
.subclass
= 0;
3728 *dest
= &p
->subs
[index
].f
;
3729 } else if (f
->subclass
== 'm') {
3730 /* Confmute request */
3731 dahdi_confmute(p
, 1);
3732 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
3733 p
->subs
[index
].f
.subclass
= 0;
3734 *dest
= &p
->subs
[index
].f
;
3735 } else if (f
->subclass
== 'u') {
3737 dahdi_confmute(p
, 0);
3738 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
3739 p
->subs
[index
].f
.subclass
= 0;
3740 *dest
= &p
->subs
[index
].f
;
3742 dahdi_confmute(p
, 0);
3745 static void handle_alarms(struct dahdi_pvt
*p
, int alarms
)
3747 const char *alarm_str
= alarm2str(alarms
);
3749 /* hack alert! Zaptel 1.4 and DAHDI expose FXO battery as an alarm, but this code
3750 * doesn't know what to do with it. Don't confuse users with log messages. */
3751 if (!strcasecmp(alarm_str
, "No Alarm") || !strcasecmp(alarm_str
, "Unknown Alarm")) {
3752 p
->unknown_alarm
= 1;
3755 p
->unknown_alarm
= 0;
3758 ast_log(LOG_WARNING
, "Detected alarm on channel %d: %s\n", p
->channel
, alarm_str
);
3759 manager_event(EVENT_FLAG_SYSTEM
, "Alarm",
3762 alarm_str
, p
->channel
);
3765 static struct ast_frame
*dahdi_handle_event(struct ast_channel
*ast
)
3770 struct dahdi_pvt
*p
= ast
->tech_pvt
;
3772 pthread_attr_t attr
;
3773 struct ast_channel
*chan
;
3774 struct ast_frame
*f
;
3776 index
= dahdi_get_index(ast
, p
, 0);
3778 if (p
->outsigmod
> -1)
3779 mysig
= p
->outsigmod
;
3780 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
3781 p
->subs
[index
].f
.subclass
= 0;
3782 p
->subs
[index
].f
.datalen
= 0;
3783 p
->subs
[index
].f
.samples
= 0;
3784 p
->subs
[index
].f
.mallocd
= 0;
3785 p
->subs
[index
].f
.offset
= 0;
3786 p
->subs
[index
].f
.src
= "dahdi_handle_event";
3787 p
->subs
[index
].f
.data
= NULL
;
3788 f
= &p
->subs
[index
].f
;
3791 return &p
->subs
[index
].f
;
3792 if (p
->fake_event
) {
3793 res
= p
->fake_event
;
3796 res
= dahdi_get_event(p
->subs
[index
].dfd
);
3799 ast_log(LOG_DEBUG
, "Got event %s(%d) on channel %d (index %d)\n", event2str(res
), res
, p
->channel
, index
);
3801 if (res
& (DAHDI_EVENT_PULSEDIGIT
| DAHDI_EVENT_DTMFUP
)) {
3802 p
->pulsedial
= (res
& DAHDI_EVENT_PULSEDIGIT
) ? 1 : 0;
3804 ast_log(LOG_DEBUG
, "Detected %sdigit '%c'\n", p
->pulsedial
? "pulse ": "", res
& 0xff);
3806 if (!p
->proceeding
&& p
->sig
== SIG_PRI
&& p
->pri
&& p
->pri
->overlapdial
) {
3810 p
->subs
[index
].f
.frametype
= AST_FRAME_DTMF_END
;
3811 p
->subs
[index
].f
.subclass
= res
& 0xff;
3815 dahdi_handle_dtmfup(ast
, index
, &f
);
3819 if (res
& DAHDI_EVENT_DTMFDOWN
) {
3821 ast_log(LOG_DEBUG
, "DTMF Down '%c'\n", res
& 0xff);
3822 /* Mute conference */
3823 dahdi_confmute(p
, 1);
3824 p
->subs
[index
].f
.frametype
= AST_FRAME_DTMF_BEGIN
;
3825 p
->subs
[index
].f
.subclass
= res
& 0xff;
3826 return &p
->subs
[index
].f
;
3830 #ifdef DAHDI_EVENT_EC_DISABLED
3831 case DAHDI_EVENT_EC_DISABLED
:
3832 if (option_verbose
> 2)
3833 ast_verbose(VERBOSE_PREFIX_3
"Channel %d echo canceler disabled due to CED detection\n", p
->channel
);
3837 case DAHDI_EVENT_BITSCHANGED
:
3838 ast_log(LOG_WARNING
, "Recieved bits changed on %s signalling?\n", sig2str(p
->sig
));
3839 case DAHDI_EVENT_PULSE_START
:
3840 /* Stop tone if there's a pulse start and the PBX isn't started */
3842 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
3844 case DAHDI_EVENT_DIALCOMPLETE
:
3845 if (p
->inalarm
) break;
3846 if ((p
->radio
|| (p
->oprmode
< 0))) break;
3847 if (ioctl(p
->subs
[index
].dfd
,DAHDI_DIALING
,&x
) == -1) {
3848 ast_log(LOG_DEBUG
, "DAHDI_DIALING ioctl failed on %s: %s\n",ast
->name
, strerror(errno
));
3851 if (!x
) { /* if not still dialing in driver */
3855 ast_copy_string(p
->dop
.dialstr
, p
->echorest
, sizeof(p
->dop
.dialstr
));
3856 p
->dop
.op
= DAHDI_DIAL_OP_REPLACE
;
3857 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
);
3861 if ((mysig
== SIG_E911
) || (mysig
== SIG_FGC_CAMA
) || (mysig
== SIG_FGC_CAMAMF
)) {
3862 /* if thru with dialing after offhook */
3863 if (ast
->_state
== AST_STATE_DIALING_OFFHOOK
) {
3864 ast_setstate(ast
, AST_STATE_UP
);
3865 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
3866 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
3868 } else { /* if to state wait for offhook to dial rest */
3869 /* we now wait for off hook */
3870 ast_setstate(ast
,AST_STATE_DIALING_OFFHOOK
);
3873 if (ast
->_state
== AST_STATE_DIALING
) {
3874 if ((p
->callprogress
& 1) && CANPROGRESSDETECT(p
) && p
->dsp
&& p
->outgoing
) {
3875 ast_log(LOG_DEBUG
, "Done dialing, but waiting for progress detection before doing more...\n");
3876 } else if (p
->confirmanswer
|| (!p
->dialednone
&& ((mysig
== SIG_EM
) || (mysig
== SIG_EM_E1
) || (mysig
== SIG_EMWINK
) || (mysig
== SIG_FEATD
) || (mysig
== SIG_FEATDMF_TA
) || (mysig
== SIG_FEATDMF
) || (mysig
== SIG_E911
) || (mysig
== SIG_FGC_CAMA
) || (mysig
== SIG_FGC_CAMAMF
) || (mysig
== SIG_FEATB
) || (mysig
== SIG_SF
) || (mysig
== SIG_SFWINK
) || (mysig
== SIG_SF_FEATD
) || (mysig
== SIG_SF_FEATDMF
) || (mysig
== SIG_SF_FEATB
)))) {
3877 ast_setstate(ast
, AST_STATE_RINGING
);
3878 } else if (!p
->answeronpolarityswitch
) {
3879 ast_setstate(ast
, AST_STATE_UP
);
3880 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
3881 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
3882 /* If aops=0 and hops=1, this is necessary */
3883 p
->polarity
= POLARITY_REV
;
3885 /* Start clean, so we can catch the change to REV polarity when party answers */
3886 p
->polarity
= POLARITY_IDLE
;
3892 case DAHDI_EVENT_ALARM
:
3894 if (!p
->pri
|| !p
->pri
->pri
|| (pri_get_timer(p
->pri
->pri
, PRI_TIMER_T309
) < 0)) {
3895 /* T309 is not enabled : hangup calls when alarm occurs */
3897 if (p
->pri
&& p
->pri
->pri
) {
3898 if (!pri_grab(p
, p
->pri
)) {
3899 pri_hangup(p
->pri
->pri
, p
->call
, -1);
3900 pri_destroycall(p
->pri
->pri
, p
->call
);
3904 ast_log(LOG_WARNING
, "Failed to grab PRI!\n");
3906 ast_log(LOG_WARNING
, "The PRI Call has not been destroyed\n");
3909 p
->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3912 p
->bearer
->inalarm
= 1;
3916 res
= get_alarms(p
);
3917 handle_alarms(p
, res
);
3919 if (!p
->pri
|| !p
->pri
->pri
|| pri_get_timer(p
->pri
->pri
, PRI_TIMER_T309
) < 0) {
3920 /* fall through intentionally */
3925 case DAHDI_EVENT_ONHOOK
:
3927 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
3928 p
->subs
[index
].f
.subclass
= AST_CONTROL_RADIO_UNKEY
;
3933 if (p
->oprmode
!= -1) break;
3934 if ((p
->sig
== SIG_FXOLS
) || (p
->sig
== SIG_FXOKS
) || (p
->sig
== SIG_FXOGS
))
3936 /* Make sure it starts ringing */
3937 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_RINGOFF
);
3938 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_RING
);
3939 save_conference(p
->oprpeer
);
3940 tone_zone_play_tone(p
->oprpeer
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_RINGTONE
);
3948 p
->onhooktime
= time(NULL
);
3950 /* Check for some special conditions regarding call waiting */
3951 if (index
== SUB_REAL
) {
3952 /* The normal line was hung up */
3953 if (p
->subs
[SUB_CALLWAIT
].owner
) {
3954 /* There's a call waiting call, so ring the phone, but make it unowned in the mean time */
3955 swap_subs(p
, SUB_CALLWAIT
, SUB_REAL
);
3956 if (option_verbose
> 2)
3957 ast_verbose(VERBOSE_PREFIX_3
"Channel %d still has (callwait) call, ringing phone\n", p
->channel
);
3958 unalloc_sub(p
, SUB_CALLWAIT
);
3960 p
->subs
[index
].needanswer
= 0;
3961 p
->subs
[index
].needringing
= 0;
3963 p
->callwaitingrepeat
= 0;
3966 /* Don't start streaming audio yet if the incoming call isn't up yet */
3967 if (p
->subs
[SUB_REAL
].owner
->_state
!= AST_STATE_UP
)
3969 dahdi_ring_phone(p
);
3970 } else if (p
->subs
[SUB_THREEWAY
].owner
) {
3971 unsigned int mssinceflash
;
3972 /* Here we have to retain the lock on both the main channel, the 3-way channel, and
3973 the private structure -- not especially easy or clean */
3974 while (p
->subs
[SUB_THREEWAY
].owner
&& ast_mutex_trylock(&p
->subs
[SUB_THREEWAY
].owner
->lock
)) {
3975 /* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
3976 ast_mutex_unlock(&p
->lock
);
3977 DEADLOCK_AVOIDANCE(&ast
->lock
);
3978 /* We can grab ast and p in that order, without worry. We should make sure
3979 nothing seriously bad has happened though like some sort of bizarre double
3981 ast_mutex_lock(&p
->lock
);
3982 if (p
->owner
!= ast
) {
3983 ast_log(LOG_WARNING
, "This isn't good...\n");
3987 if (!p
->subs
[SUB_THREEWAY
].owner
) {
3988 ast_log(LOG_NOTICE
, "Whoa, threeway disappeared kinda randomly.\n");
3991 mssinceflash
= ast_tvdiff_ms(ast_tvnow(), p
->flashtime
);
3992 ast_log(LOG_DEBUG
, "Last flash was %d ms ago\n", mssinceflash
);
3993 if (mssinceflash
< MIN_MS_SINCE_FLASH
) {
3994 /* It hasn't been long enough since the last flashook. This is probably a bounce on
3995 hanging up. Hangup both channels now */
3996 if (p
->subs
[SUB_THREEWAY
].owner
)
3997 ast_queue_hangup(p
->subs
[SUB_THREEWAY
].owner
);
3998 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3999 ast_log(LOG_DEBUG
, "Looks like a bounced flash, hanging up both calls on %d\n", p
->channel
);
4000 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4001 } else if ((ast
->pbx
) || (ast
->_state
== AST_STATE_UP
)) {
4003 /* In any case this isn't a threeway call anymore */
4004 p
->subs
[SUB_REAL
].inthreeway
= 0;
4005 p
->subs
[SUB_THREEWAY
].inthreeway
= 0;
4006 /* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */
4007 if (!p
->transfertobusy
&& ast
->_state
== AST_STATE_BUSY
) {
4008 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4009 /* Swap subs and dis-own channel */
4010 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4012 /* Ring the phone */
4013 dahdi_ring_phone(p
);
4015 if ((res
= attempt_transfer(p
)) < 0) {
4016 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
4017 if (p
->subs
[SUB_THREEWAY
].owner
)
4018 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4020 /* Don't actually hang up at this point */
4021 if (p
->subs
[SUB_THREEWAY
].owner
)
4022 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4027 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
4028 if (p
->subs
[SUB_THREEWAY
].owner
)
4029 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4032 ast_mutex_unlock(&p
->subs
[SUB_THREEWAY
].owner
->lock
);
4033 /* Swap subs and dis-own channel */
4034 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4036 /* Ring the phone */
4037 dahdi_ring_phone(p
);
4041 ast_log(LOG_WARNING
, "Got a hangup and my index is %d?\n", index
);
4045 dahdi_disable_ec(p
);
4049 case DAHDI_EVENT_RINGOFFHOOK
:
4050 if (p
->inalarm
) break;
4053 if ((p
->sig
== SIG_FXOLS
) || (p
->sig
== SIG_FXOKS
) || (p
->sig
== SIG_FXOGS
))
4055 /* Make sure it stops ringing */
4056 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_RINGOFF
);
4057 tone_zone_play_tone(p
->oprpeer
->subs
[SUB_REAL
].dfd
, -1);
4058 restore_conference(p
->oprpeer
);
4064 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4065 p
->subs
[index
].f
.subclass
= AST_CONTROL_RADIO_KEY
;
4068 /* for E911, its supposed to wait for offhook then dial
4069 the second half of the dial string */
4070 if (((mysig
== SIG_E911
) || (mysig
== SIG_FGC_CAMA
) || (mysig
== SIG_FGC_CAMAMF
)) && (ast
->_state
== AST_STATE_DIALING_OFFHOOK
)) {
4071 c
= strchr(p
->dialdest
, '/');
4076 if (*c
) snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*0%s#", c
);
4077 else ast_copy_string(p
->dop
.dialstr
,"M*2#", sizeof(p
->dop
.dialstr
));
4078 if (strlen(p
->dop
.dialstr
) > 4) {
4079 memset(p
->echorest
, 'w', sizeof(p
->echorest
) - 1);
4080 strcpy(p
->echorest
+ (p
->echotraining
/ 401) + 1, p
->dop
.dialstr
+ strlen(p
->dop
.dialstr
) - 2);
4081 p
->echorest
[sizeof(p
->echorest
) - 1] = '\0';
4083 p
->dop
.dialstr
[strlen(p
->dop
.dialstr
)-2] = '\0';
4086 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
)) {
4087 int saveerr
= errno
;
4090 ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
4091 ast_log(LOG_WARNING
, "Dialing failed on channel %d: %s\n", p
->channel
, strerror(saveerr
));
4095 return &p
->subs
[index
].f
;
4101 switch (ast
->_state
) {
4102 case AST_STATE_RINGING
:
4105 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4106 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
4107 /* Make sure it stops ringing */
4108 dahdi_set_hook(p
->subs
[index
].dfd
, DAHDI_OFFHOOK
);
4109 ast_log(LOG_DEBUG
, "channel %d answered\n", p
->channel
);
4111 /* Cancel any running CallerID spill */
4117 if (p
->confirmanswer
) {
4118 /* Ignore answer if "confirm answer" is enabled */
4119 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4120 p
->subs
[index
].f
.subclass
= 0;
4121 } else if (!ast_strlen_zero(p
->dop
.dialstr
)) {
4122 /* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */
4123 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
);
4125 ast_log(LOG_WARNING
, "Unable to initiate dialing on trunk channel %d: %s\n", p
->channel
, strerror(errno
));
4126 p
->dop
.dialstr
[0] = '\0';
4129 ast_log(LOG_DEBUG
, "Sent FXO deferred digit string: %s\n", p
->dop
.dialstr
);
4130 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4131 p
->subs
[index
].f
.subclass
= 0;
4134 p
->dop
.dialstr
[0] = '\0';
4135 ast_setstate(ast
, AST_STATE_DIALING
);
4137 ast_setstate(ast
, AST_STATE_UP
);
4138 return &p
->subs
[index
].f
;
4139 case AST_STATE_DOWN
:
4140 ast_setstate(ast
, AST_STATE_RING
);
4142 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4143 p
->subs
[index
].f
.subclass
= AST_CONTROL_OFFHOOK
;
4144 ast_log(LOG_DEBUG
, "channel %d picked up\n", p
->channel
);
4145 return &p
->subs
[index
].f
;
4147 /* Make sure it stops ringing */
4148 dahdi_set_hook(p
->subs
[index
].dfd
, DAHDI_OFFHOOK
);
4149 /* Okay -- probably call waiting*/
4150 if (ast_bridged_channel(p
->owner
))
4151 ast_queue_control(p
->owner
, AST_CONTROL_UNHOLD
);
4152 p
->subs
[index
].needunhold
= 1;
4154 case AST_STATE_RESERVED
:
4155 /* Start up dialtone */
4156 if (has_voicemail(p
))
4157 res
= tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_STUTTER
);
4159 res
= tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_DIALTONE
);
4162 ast_log(LOG_WARNING
, "FXO phone off hook in weird state %d??\n", ast
->_state
);
4168 if (ast
->_state
== AST_STATE_RING
) {
4169 p
->ringt
= p
->ringt_base
;
4178 case SIG_FEATDMF_TA
:
4181 case SIG_FGC_CAMAMF
:
4186 case SIG_SF_FEATDMF
:
4188 if (ast
->_state
== AST_STATE_PRERING
)
4189 ast_setstate(ast
, AST_STATE_RING
);
4190 if ((ast
->_state
== AST_STATE_DOWN
) || (ast
->_state
== AST_STATE_RING
)) {
4192 ast_log(LOG_DEBUG
, "Ring detected\n");
4193 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4194 p
->subs
[index
].f
.subclass
= AST_CONTROL_RING
;
4195 } else if (p
->outgoing
&& ((ast
->_state
== AST_STATE_RINGING
) || (ast
->_state
== AST_STATE_DIALING
))) {
4197 ast_log(LOG_DEBUG
, "Line answered\n");
4198 if (p
->confirmanswer
) {
4199 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4200 p
->subs
[index
].f
.subclass
= 0;
4202 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4203 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
4204 ast_setstate(ast
, AST_STATE_UP
);
4206 } else if (ast
->_state
!= AST_STATE_RING
)
4207 ast_log(LOG_WARNING
, "Ring/Off-hook in strange state %d on channel %d\n", ast
->_state
, p
->channel
);
4210 ast_log(LOG_WARNING
, "Don't know how to handle ring/off hook for signalling %d\n", p
->sig
);
4213 #ifdef DAHDI_EVENT_RINGBEGIN
4214 case DAHDI_EVENT_RINGBEGIN
:
4219 if (ast
->_state
== AST_STATE_RING
) {
4220 p
->ringt
= p
->ringt_base
;
4226 case DAHDI_EVENT_RINGEROFF
:
4227 if (p
->inalarm
) break;
4228 if ((p
->radio
|| (p
->oprmode
< 0))) break;
4230 if ((ast
->rings
> p
->cidrings
) && (p
->cidspill
)) {
4231 ast_log(LOG_WARNING
, "Didn't finish Caller-ID spill. Cancelling.\n");
4236 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4237 p
->subs
[index
].f
.subclass
= AST_CONTROL_RINGING
;
4239 case DAHDI_EVENT_RINGERON
:
4241 case DAHDI_EVENT_NOALARM
:
4244 /* Extremely unlikely but just in case */
4246 p
->bearer
->inalarm
= 0;
4248 if (!p
->unknown_alarm
) {
4249 ast_log(LOG_NOTICE
, "Alarm cleared on channel %d\n", p
->channel
);
4250 manager_event(EVENT_FLAG_SYSTEM
, "AlarmClear",
4251 "Channel: %d\r\n", p
->channel
);
4253 p
->unknown_alarm
= 0;
4256 case DAHDI_EVENT_WINKFLASH
:
4257 if (p
->inalarm
) break;
4258 if (p
->radio
) break;
4259 if (p
->oprmode
< 0) break;
4262 struct dahdi_params par
;
4264 if (ioctl(p
->oprpeer
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &par
) != -1)
4266 if (!par
.rxisoffhook
)
4268 /* Make sure it stops ringing */
4269 dahdi_set_hook(p
->oprpeer
->subs
[SUB_REAL
].dfd
, DAHDI_RINGOFF
);
4270 dahdi_set_hook(p
->oprpeer
->subs
[SUB_REAL
].dfd
, DAHDI_RING
);
4272 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_RINGTONE
);
4277 /* Remember last time we got a flash-hook */
4278 gettimeofday(&p
->flashtime
, NULL
);
4283 ast_log(LOG_DEBUG
, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
4284 index
, p
->subs
[SUB_REAL
].dfd
, p
->subs
[SUB_CALLWAIT
].dfd
, p
->subs
[SUB_THREEWAY
].dfd
);
4287 if (index
!= SUB_REAL
) {
4288 ast_log(LOG_WARNING
, "Got flash hook with index %d on channel %d?!?\n", index
, p
->channel
);
4292 if (p
->subs
[SUB_CALLWAIT
].owner
) {
4293 /* Swap to call-wait */
4294 swap_subs(p
, SUB_REAL
, SUB_CALLWAIT
);
4295 tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, -1);
4296 p
->owner
= p
->subs
[SUB_REAL
].owner
;
4297 ast_log(LOG_DEBUG
, "Making %s the new owner\n", p
->owner
->name
);
4298 if (p
->owner
->_state
== AST_STATE_RINGING
) {
4299 ast_setstate(p
->owner
, AST_STATE_UP
);
4300 p
->subs
[SUB_REAL
].needanswer
= 1;
4302 p
->callwaitingrepeat
= 0;
4304 /* Start music on hold if appropriate */
4305 if (!p
->subs
[SUB_CALLWAIT
].inthreeway
&& ast_bridged_channel(p
->subs
[SUB_CALLWAIT
].owner
)) {
4306 ast_queue_control_data(p
->subs
[SUB_CALLWAIT
].owner
, AST_CONTROL_HOLD
,
4307 S_OR(p
->mohsuggest
, NULL
),
4308 !ast_strlen_zero(p
->mohsuggest
) ? strlen(p
->mohsuggest
) + 1 : 0);
4310 p
->subs
[SUB_CALLWAIT
].needhold
= 1;
4311 if (ast_bridged_channel(p
->subs
[SUB_REAL
].owner
)) {
4312 ast_queue_control_data(p
->subs
[SUB_REAL
].owner
, AST_CONTROL_HOLD
,
4313 S_OR(p
->mohsuggest
, NULL
),
4314 !ast_strlen_zero(p
->mohsuggest
) ? strlen(p
->mohsuggest
) + 1 : 0);
4316 p
->subs
[SUB_REAL
].needunhold
= 1;
4317 } else if (!p
->subs
[SUB_THREEWAY
].owner
) {
4321 if (!p
->threewaycalling
) {
4322 /* Just send a flash if no 3-way calling */
4323 p
->subs
[SUB_REAL
].needflash
= 1;
4325 } else if (!check_for_conference(p
)) {
4326 if (p
->dahditrcallerid
&& p
->owner
) {
4327 if (p
->owner
->cid
.cid_num
)
4328 ast_copy_string(cid_num
, p
->owner
->cid
.cid_num
, sizeof(cid_num
));
4329 if (p
->owner
->cid
.cid_name
)
4330 ast_copy_string(cid_name
, p
->owner
->cid
.cid_name
, sizeof(cid_name
));
4332 /* XXX This section needs much more error checking!!! XXX */
4333 /* Start a 3-way call if feasible */
4335 (ast
->_state
== AST_STATE_UP
) ||
4336 (ast
->_state
== AST_STATE_RING
))) {
4337 ast_log(LOG_DEBUG
, "Flash when call not up or ringing\n");
4340 if (alloc_sub(p
, SUB_THREEWAY
)) {
4341 ast_log(LOG_WARNING
, "Unable to allocate three-way subchannel\n");
4344 /* Make new channel */
4345 chan
= dahdi_new(p
, AST_STATE_RESERVED
, 0, SUB_THREEWAY
, 0, 0);
4346 if (p
->dahditrcallerid
) {
4347 if (!p
->origcid_num
)
4348 p
->origcid_num
= ast_strdup(p
->cid_num
);
4349 if (!p
->origcid_name
)
4350 p
->origcid_name
= ast_strdup(p
->cid_name
);
4351 ast_copy_string(p
->cid_num
, cid_num
, sizeof(p
->cid_num
));
4352 ast_copy_string(p
->cid_name
, cid_name
, sizeof(p
->cid_name
));
4354 /* Swap things around between the three-way and real call */
4355 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4356 /* Disable echo canceller for better dialing */
4357 dahdi_disable_ec(p
);
4358 res
= tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_DIALRECALL
);
4360 ast_log(LOG_WARNING
, "Unable to start dial recall tone on channel %d\n", p
->channel
);
4362 pthread_attr_init(&attr
);
4363 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
4365 ast_log(LOG_WARNING
, "Cannot allocate new structure on channel %d\n", p
->channel
);
4366 } else if (ast_pthread_create(&threadid
, &attr
, ss_thread
, chan
)) {
4367 ast_log(LOG_WARNING
, "Unable to start simple switch on channel %d\n", p
->channel
);
4368 res
= tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
4372 struct ast_channel
*other
= ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
);
4373 int way3bridge
= 0, cdr3way
= 0;
4376 other
= ast_bridged_channel(p
->subs
[SUB_REAL
].owner
);
4380 if (p
->subs
[SUB_THREEWAY
].owner
->cdr
)
4383 if (option_verbose
> 2)
4384 ast_verbose(VERBOSE_PREFIX_3
"Started three way call on channel %d\n", p
->channel
);
4385 /* Start music on hold if appropriate */
4386 if (ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
)) {
4387 ast_queue_control_data(p
->subs
[SUB_THREEWAY
].owner
, AST_CONTROL_HOLD
,
4388 S_OR(p
->mohsuggest
, NULL
),
4389 !ast_strlen_zero(p
->mohsuggest
) ? strlen(p
->mohsuggest
) + 1 : 0);
4391 p
->subs
[SUB_THREEWAY
].needhold
= 1;
4393 pthread_attr_destroy(&attr
);
4396 /* Already have a 3 way call */
4397 if (p
->subs
[SUB_THREEWAY
].inthreeway
) {
4398 /* Call is already up, drop the last person */
4400 ast_log(LOG_DEBUG
, "Got flash with three way call up, dropping last call on %d\n", p
->channel
);
4401 /* If the primary call isn't answered yet, use it */
4402 if ((p
->subs
[SUB_REAL
].owner
->_state
!= AST_STATE_UP
) && (p
->subs
[SUB_THREEWAY
].owner
->_state
== AST_STATE_UP
)) {
4403 /* Swap back -- we're dropping the real 3-way that isn't finished yet*/
4404 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4405 p
->owner
= p
->subs
[SUB_REAL
].owner
;
4407 /* Drop the last call and stop the conference */
4408 if (option_verbose
> 2)
4409 ast_verbose(VERBOSE_PREFIX_3
"Dropping three-way call on %s\n", p
->subs
[SUB_THREEWAY
].owner
->name
);
4410 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
4411 p
->subs
[SUB_REAL
].inthreeway
= 0;
4412 p
->subs
[SUB_THREEWAY
].inthreeway
= 0;
4414 /* Lets see what we're up to */
4415 if (((ast
->pbx
) || (ast
->_state
== AST_STATE_UP
)) &&
4416 (p
->transfertobusy
|| (ast
->_state
!= AST_STATE_BUSY
))) {
4417 int otherindex
= SUB_THREEWAY
;
4418 struct ast_channel
*other
= ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
);
4419 int way3bridge
= 0, cdr3way
= 0;
4422 other
= ast_bridged_channel(p
->subs
[SUB_REAL
].owner
);
4426 if (p
->subs
[SUB_THREEWAY
].owner
->cdr
)
4429 if (option_verbose
> 2)
4430 ast_verbose(VERBOSE_PREFIX_3
"Building conference on call on %s and %s\n", p
->subs
[SUB_THREEWAY
].owner
->name
, p
->subs
[SUB_REAL
].owner
->name
);
4431 /* Put them in the threeway, and flip */
4432 p
->subs
[SUB_THREEWAY
].inthreeway
= 1;
4433 p
->subs
[SUB_REAL
].inthreeway
= 1;
4434 if (ast
->_state
== AST_STATE_UP
) {
4435 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4436 otherindex
= SUB_REAL
;
4438 if (p
->subs
[otherindex
].owner
&& ast_bridged_channel(p
->subs
[otherindex
].owner
))
4439 ast_queue_control(p
->subs
[otherindex
].owner
, AST_CONTROL_UNHOLD
);
4440 p
->subs
[otherindex
].needunhold
= 1;
4441 p
->owner
= p
->subs
[SUB_REAL
].owner
;
4442 if (ast
->_state
== AST_STATE_RINGING
) {
4443 ast_log(LOG_DEBUG
, "Enabling ringtone on real and threeway\n");
4444 res
= tone_zone_play_tone(p
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_RINGTONE
);
4445 res
= tone_zone_play_tone(p
->subs
[SUB_THREEWAY
].dfd
, DAHDI_TONE_RINGTONE
);
4448 if (option_verbose
> 2)
4449 ast_verbose(VERBOSE_PREFIX_3
"Dumping incomplete call on on %s\n", p
->subs
[SUB_THREEWAY
].owner
->name
);
4450 swap_subs(p
, SUB_THREEWAY
, SUB_REAL
);
4451 p
->subs
[SUB_THREEWAY
].owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
4452 p
->owner
= p
->subs
[SUB_REAL
].owner
;
4453 if (p
->subs
[SUB_REAL
].owner
&& ast_bridged_channel(p
->subs
[SUB_REAL
].owner
))
4454 ast_queue_control(p
->subs
[SUB_REAL
].owner
, AST_CONTROL_UNHOLD
);
4455 p
->subs
[SUB_REAL
].needunhold
= 1;
4474 ast_log(LOG_DEBUG
, "Ignoring wink on channel %d\n", p
->channel
);
4476 ast_log(LOG_DEBUG
, "Got wink in weird state %d on channel %d\n", ast
->_state
, p
->channel
);
4478 case SIG_FEATDMF_TA
:
4479 switch (p
->whichwink
) {
4481 ast_log(LOG_DEBUG
, "ANI2 set to '%d' and ANI is '%s'\n", p
->owner
->cid
.cid_ani2
, p
->owner
->cid
.cid_ani
);
4482 snprintf(p
->dop
.dialstr
, sizeof(p
->dop
.dialstr
), "M*%d%s#", p
->owner
->cid
.cid_ani2
, p
->owner
->cid
.cid_ani
);
4485 ast_copy_string(p
->dop
.dialstr
, p
->finaldial
, sizeof(p
->dop
.dialstr
));
4488 ast_log(LOG_WARNING
, "Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
4495 case SIG_FGC_CAMAMF
:
4498 case SIG_SF_FEATDMF
:
4500 /* FGD MF *Must* wait for wink */
4501 if (!ast_strlen_zero(p
->dop
.dialstr
)) {
4502 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
);
4504 ast_log(LOG_WARNING
, "Unable to initiate dialing on trunk channel %d: %s\n", p
->channel
, strerror(errno
));
4505 p
->dop
.dialstr
[0] = '\0';
4508 ast_log(LOG_DEBUG
, "Sent deferred digit string: %s\n", p
->dop
.dialstr
);
4510 p
->dop
.dialstr
[0] = '\0';
4513 ast_log(LOG_WARNING
, "Don't know how to handle ring/off hoook for signalling %d\n", p
->sig
);
4516 case DAHDI_EVENT_HOOKCOMPLETE
:
4517 if (p
->inalarm
) break;
4518 if ((p
->radio
|| (p
->oprmode
< 0))) break;
4520 case SIG_FXSLS
: /* only interesting for FXS */
4530 if (!ast_strlen_zero(p
->dop
.dialstr
)) {
4531 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &p
->dop
);
4533 ast_log(LOG_WARNING
, "Unable to initiate dialing on trunk channel %d: %s\n", p
->channel
, strerror(errno
));
4534 p
->dop
.dialstr
[0] = '\0';
4537 ast_log(LOG_DEBUG
, "Sent deferred digit string: %s\n", p
->dop
.dialstr
);
4539 p
->dop
.dialstr
[0] = '\0';
4540 p
->dop
.op
= DAHDI_DIAL_OP_REPLACE
;
4543 case SIG_FEATDMF_TA
:
4546 case SIG_FGC_CAMAMF
:
4548 case SIG_SF_FEATDMF
:
4550 ast_log(LOG_DEBUG
, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p
->channel
);
4556 case DAHDI_EVENT_POLARITY
:
4558 * If we get a Polarity Switch event, check to see
4559 * if we should change the polarity state and
4560 * mark the channel as UP or if this is an indication
4561 * of remote end disconnect.
4563 if (p
->polarity
== POLARITY_IDLE
) {
4564 p
->polarity
= POLARITY_REV
;
4565 if (p
->answeronpolarityswitch
&&
4566 ((ast
->_state
== AST_STATE_DIALING
) ||
4567 (ast
->_state
== AST_STATE_RINGING
))) {
4568 ast_log(LOG_DEBUG
, "Answering on polarity switch!\n");
4569 ast_setstate(p
->owner
, AST_STATE_UP
);
4570 if (p
->hanguponpolarityswitch
) {
4571 gettimeofday(&p
->polaritydelaytv
, NULL
);
4574 ast_log(LOG_DEBUG
, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p
->channel
, ast
->_state
);
4576 /* Removed else statement from here as it was preventing hangups from ever happening*/
4577 /* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
4578 if (p
->hanguponpolarityswitch
&&
4579 (p
->polarityonanswerdelay
> 0) &&
4580 (p
->polarity
== POLARITY_REV
) &&
4581 ((ast
->_state
== AST_STATE_UP
) || (ast
->_state
== AST_STATE_RING
)) ) {
4582 /* Added log_debug information below to provide a better indication of what is going on */
4583 ast_log(LOG_DEBUG
, "Polarity Reversal event occured - DEBUG 1: 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
) );
4585 if (ast_tvdiff_ms(ast_tvnow(), p
->polaritydelaytv
) > p
->polarityonanswerdelay
) {
4586 ast_log(LOG_DEBUG
, "Polarity Reversal detected and now Hanging up on channel %d\n", p
->channel
);
4587 ast_softhangup(p
->owner
, AST_SOFTHANGUP_EXPLICIT
);
4588 p
->polarity
= POLARITY_IDLE
;
4590 ast_log(LOG_DEBUG
, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p
->channel
, ast
->_state
);
4593 p
->polarity
= POLARITY_IDLE
;
4594 ast_log(LOG_DEBUG
, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p
->channel
, ast
->_state
);
4596 /* Added more log_debug information below to provide a better indication of what is going on */
4597 ast_log(LOG_DEBUG
, "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
) );
4600 ast_log(LOG_DEBUG
, "Dunno what to do with event %d on channel %d\n", res
, p
->channel
);
4602 return &p
->subs
[index
].f
;
4605 static struct ast_frame
*__dahdi_exception(struct ast_channel
*ast
)
4607 struct dahdi_pvt
*p
= ast
->tech_pvt
;
4611 struct ast_frame
*f
;
4614 index
= dahdi_get_index(ast
, p
, 1);
4616 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4617 p
->subs
[index
].f
.datalen
= 0;
4618 p
->subs
[index
].f
.samples
= 0;
4619 p
->subs
[index
].f
.mallocd
= 0;
4620 p
->subs
[index
].f
.offset
= 0;
4621 p
->subs
[index
].f
.subclass
= 0;
4622 p
->subs
[index
].f
.delivery
= ast_tv(0,0);
4623 p
->subs
[index
].f
.src
= "dahdi_exception";
4624 p
->subs
[index
].f
.data
= NULL
;
4627 if ((!p
->owner
) && (!(p
->radio
|| (p
->oprmode
< 0)))) {
4628 /* If nobody owns us, absorb the event appropriately, otherwise
4629 we loop indefinitely. This occurs when, during call waiting, the
4630 other end hangs up our channel so that it no longer exists, but we
4631 have neither FLASH'd nor ONHOOK'd to signify our desire to
4632 change to the other channel. */
4633 if (p
->fake_event
) {
4634 res
= p
->fake_event
;
4637 res
= dahdi_get_event(p
->subs
[SUB_REAL
].dfd
);
4638 /* Switch to real if there is one and this isn't something really silly... */
4639 if ((res
!= DAHDI_EVENT_RINGEROFF
) && (res
!= DAHDI_EVENT_RINGERON
) &&
4640 (res
!= DAHDI_EVENT_HOOKCOMPLETE
)) {
4641 ast_log(LOG_DEBUG
, "Restoring owner of channel %d on event %d\n", p
->channel
, res
);
4642 p
->owner
= p
->subs
[SUB_REAL
].owner
;
4643 if (p
->owner
&& ast_bridged_channel(p
->owner
))
4644 ast_queue_control(p
->owner
, AST_CONTROL_UNHOLD
);
4645 p
->subs
[SUB_REAL
].needunhold
= 1;
4648 case DAHDI_EVENT_ONHOOK
:
4649 dahdi_disable_ec(p
);
4651 if (option_verbose
> 2)
4652 ast_verbose(VERBOSE_PREFIX_3
"Channel %s still has call, ringing phone\n", p
->owner
->name
);
4653 dahdi_ring_phone(p
);
4654 p
->callwaitingrepeat
= 0;
4657 ast_log(LOG_WARNING
, "Absorbed on hook, but nobody is left!?!?\n");
4660 case DAHDI_EVENT_RINGOFFHOOK
:
4662 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
4663 if (p
->owner
&& (p
->owner
->_state
== AST_STATE_RINGING
)) {
4664 p
->subs
[SUB_REAL
].needanswer
= 1;
4668 case DAHDI_EVENT_HOOKCOMPLETE
:
4669 case DAHDI_EVENT_RINGERON
:
4670 case DAHDI_EVENT_RINGEROFF
:
4673 case DAHDI_EVENT_WINKFLASH
:
4674 gettimeofday(&p
->flashtime
, NULL
);
4676 if (option_verbose
> 2)
4677 ast_verbose(VERBOSE_PREFIX_3
"Channel %d flashed to other channel %s\n", p
->channel
, p
->owner
->name
);
4678 if (p
->owner
->_state
!= AST_STATE_UP
) {
4679 /* Answer if necessary */
4680 usedindex
= dahdi_get_index(p
->owner
, p
, 0);
4681 if (usedindex
> -1) {
4682 p
->subs
[usedindex
].needanswer
= 1;
4684 ast_setstate(p
->owner
, AST_STATE_UP
);
4686 p
->callwaitingrepeat
= 0;
4688 if (ast_bridged_channel(p
->owner
))
4689 ast_queue_control(p
->owner
, AST_CONTROL_UNHOLD
);
4690 p
->subs
[SUB_REAL
].needunhold
= 1;
4692 ast_log(LOG_WARNING
, "Absorbed on hook, but nobody is left!?!?\n");
4696 ast_log(LOG_WARNING
, "Don't know how to absorb event %s\n", event2str(res
));
4698 f
= &p
->subs
[index
].f
;
4701 if (!(p
->radio
|| (p
->oprmode
< 0)) && option_debug
)
4702 ast_log(LOG_DEBUG
, "Exception on %d, channel %d\n", ast
->fds
[0],p
->channel
);
4703 /* If it's not us, return NULL immediately */
4704 if (ast
!= p
->owner
) {
4705 ast_log(LOG_WARNING
, "We're %s, not %s\n", ast
->name
, p
->owner
->name
);
4706 f
= &p
->subs
[index
].f
;
4709 f
= dahdi_handle_event(ast
);
4713 static struct ast_frame
*dahdi_exception(struct ast_channel
*ast
)
4715 struct dahdi_pvt
*p
= ast
->tech_pvt
;
4716 struct ast_frame
*f
;
4717 ast_mutex_lock(&p
->lock
);
4718 f
= __dahdi_exception(ast
);
4719 ast_mutex_unlock(&p
->lock
);
4723 static struct ast_frame
*dahdi_read(struct ast_channel
*ast
)
4725 struct dahdi_pvt
*p
= ast
->tech_pvt
;
4729 struct ast_frame
*f
;
4731 while (ast_mutex_trylock(&p
->lock
)) {
4732 DEADLOCK_AVOIDANCE(&ast
->lock
);
4735 index
= dahdi_get_index(ast
, p
, 0);
4737 /* Hang up if we don't really exist */
4739 ast_log(LOG_WARNING
, "We dont exist?\n");
4740 ast_mutex_unlock(&p
->lock
);
4744 if ((p
->radio
|| (p
->oprmode
< 0)) && p
->inalarm
) return NULL
;
4746 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4747 p
->subs
[index
].f
.datalen
= 0;
4748 p
->subs
[index
].f
.samples
= 0;
4749 p
->subs
[index
].f
.mallocd
= 0;
4750 p
->subs
[index
].f
.offset
= 0;
4751 p
->subs
[index
].f
.subclass
= 0;
4752 p
->subs
[index
].f
.delivery
= ast_tv(0,0);
4753 p
->subs
[index
].f
.src
= "dahdi_read";
4754 p
->subs
[index
].f
.data
= NULL
;
4756 /* make sure it sends initial key state as first frame */
4757 if ((p
->radio
|| (p
->oprmode
< 0)) && (!p
->firstradio
))
4759 struct dahdi_params ps
;
4761 ps
.channo
= p
->channel
;
4762 if (ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &ps
) < 0) {
4763 ast_mutex_unlock(&p
->lock
);
4767 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4770 p
->subs
[index
].f
.subclass
= AST_CONTROL_RADIO_KEY
;
4774 p
->subs
[index
].f
.subclass
= AST_CONTROL_RADIO_UNKEY
;
4776 ast_mutex_unlock(&p
->lock
);
4777 return &p
->subs
[index
].f
;
4779 if (p
->ringt
== 1) {
4780 ast_mutex_unlock(&p
->lock
);
4783 else if (p
->ringt
> 0)
4786 if (p
->subs
[index
].needringing
) {
4787 /* Send ringing frame if requested */
4788 p
->subs
[index
].needringing
= 0;
4789 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4790 p
->subs
[index
].f
.subclass
= AST_CONTROL_RINGING
;
4791 ast_setstate(ast
, AST_STATE_RINGING
);
4792 ast_mutex_unlock(&p
->lock
);
4793 return &p
->subs
[index
].f
;
4796 if (p
->subs
[index
].needbusy
) {
4797 /* Send busy frame if requested */
4798 p
->subs
[index
].needbusy
= 0;
4799 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4800 p
->subs
[index
].f
.subclass
= AST_CONTROL_BUSY
;
4801 ast_mutex_unlock(&p
->lock
);
4802 return &p
->subs
[index
].f
;
4805 if (p
->subs
[index
].needcongestion
) {
4806 /* Send congestion frame if requested */
4807 p
->subs
[index
].needcongestion
= 0;
4808 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4809 p
->subs
[index
].f
.subclass
= AST_CONTROL_CONGESTION
;
4810 ast_mutex_unlock(&p
->lock
);
4811 return &p
->subs
[index
].f
;
4814 if (p
->subs
[index
].needcallerid
) {
4815 ast_set_callerid(ast
, S_OR(p
->lastcid_num
, NULL
),
4816 S_OR(p
->lastcid_name
, NULL
),
4817 S_OR(p
->lastcid_num
, NULL
)
4819 p
->subs
[index
].needcallerid
= 0;
4822 if (p
->subs
[index
].needanswer
) {
4823 /* Send answer frame if requested */
4824 p
->subs
[index
].needanswer
= 0;
4825 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4826 p
->subs
[index
].f
.subclass
= AST_CONTROL_ANSWER
;
4827 ast_mutex_unlock(&p
->lock
);
4828 return &p
->subs
[index
].f
;
4831 if (p
->subs
[index
].needflash
) {
4832 /* Send answer frame if requested */
4833 p
->subs
[index
].needflash
= 0;
4834 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4835 p
->subs
[index
].f
.subclass
= AST_CONTROL_FLASH
;
4836 ast_mutex_unlock(&p
->lock
);
4837 return &p
->subs
[index
].f
;
4840 if (p
->subs
[index
].needhold
) {
4841 /* Send answer frame if requested */
4842 p
->subs
[index
].needhold
= 0;
4843 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4844 p
->subs
[index
].f
.subclass
= AST_CONTROL_HOLD
;
4845 ast_mutex_unlock(&p
->lock
);
4846 ast_log(LOG_DEBUG
, "Sending hold on '%s'\n", ast
->name
);
4847 return &p
->subs
[index
].f
;
4850 if (p
->subs
[index
].needunhold
) {
4851 /* Send answer frame if requested */
4852 p
->subs
[index
].needunhold
= 0;
4853 p
->subs
[index
].f
.frametype
= AST_FRAME_CONTROL
;
4854 p
->subs
[index
].f
.subclass
= AST_CONTROL_UNHOLD
;
4855 ast_mutex_unlock(&p
->lock
);
4856 ast_log(LOG_DEBUG
, "Sending unhold on '%s'\n", ast
->name
);
4857 return &p
->subs
[index
].f
;
4860 if (ast
->rawreadformat
== AST_FORMAT_SLINEAR
) {
4861 if (!p
->subs
[index
].linear
) {
4862 p
->subs
[index
].linear
= 1;
4863 res
= dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
4865 ast_log(LOG_WARNING
, "Unable to set channel %d (index %d) to linear mode.\n", p
->channel
, index
);
4867 } else if ((ast
->rawreadformat
== AST_FORMAT_ULAW
) ||
4868 (ast
->rawreadformat
== AST_FORMAT_ALAW
)) {
4869 if (p
->subs
[index
].linear
) {
4870 p
->subs
[index
].linear
= 0;
4871 res
= dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
4873 ast_log(LOG_WARNING
, "Unable to set channel %d (index %d) to companded mode.\n", p
->channel
, index
);
4876 ast_log(LOG_WARNING
, "Don't know how to read frames in format %s\n", ast_getformatname(ast
->rawreadformat
));
4877 ast_mutex_unlock(&p
->lock
);
4880 readbuf
= ((unsigned char *)p
->subs
[index
].buffer
) + AST_FRIENDLY_OFFSET
;
4881 CHECK_BLOCKING(ast
);
4882 res
= read(p
->subs
[index
].dfd
, readbuf
, p
->subs
[index
].linear
? READ_SIZE
* 2 : READ_SIZE
);
4883 ast_clear_flag(ast
, AST_FLAG_BLOCKING
);
4884 /* Check for hangup */
4888 if (errno
== EAGAIN
) {
4889 /* Return "NULL" frame if there is nobody there */
4890 ast_mutex_unlock(&p
->lock
);
4891 return &p
->subs
[index
].f
;
4892 } else if (errno
== ELAST
) {
4893 f
= __dahdi_exception(ast
);
4895 ast_log(LOG_WARNING
, "dahdi_rec: %s\n", strerror(errno
));
4897 ast_mutex_unlock(&p
->lock
);
4900 if (res
!= (p
->subs
[index
].linear
? READ_SIZE
* 2 : READ_SIZE
)) {
4901 ast_log(LOG_DEBUG
, "Short read (%d/%d), must be an event...\n", res
, p
->subs
[index
].linear
? READ_SIZE
* 2 : READ_SIZE
);
4902 f
= __dahdi_exception(ast
);
4903 ast_mutex_unlock(&p
->lock
);
4906 if (p
->tdd
) { /* if in TDD mode, see if we receive that */
4909 c
= tdd_feed(p
->tdd
,readbuf
,READ_SIZE
);
4911 ast_log(LOG_DEBUG
,"tdd_feed failed\n");
4912 ast_mutex_unlock(&p
->lock
);
4915 if (c
) { /* if a char to return */
4916 p
->subs
[index
].f
.subclass
= 0;
4917 p
->subs
[index
].f
.frametype
= AST_FRAME_TEXT
;
4918 p
->subs
[index
].f
.mallocd
= 0;
4919 p
->subs
[index
].f
.offset
= AST_FRIENDLY_OFFSET
;
4920 p
->subs
[index
].f
.data
= p
->subs
[index
].buffer
+ AST_FRIENDLY_OFFSET
;
4921 p
->subs
[index
].f
.datalen
= 1;
4922 *((char *) p
->subs
[index
].f
.data
) = c
;
4923 ast_mutex_unlock(&p
->lock
);
4924 return &p
->subs
[index
].f
;
4927 /* Ensure the CW timer decrements only on a single subchannel */
4928 if (p
->callwaitingrepeat
&& dahdi_get_index(ast
, p
, 1) == SUB_REAL
) {
4929 p
->callwaitingrepeat
--;
4933 /* Repeat callwaiting */
4934 if (p
->callwaitingrepeat
== 1) {
4936 dahdi_callwait(ast
);
4939 if (p
->cidcwexpire
== 1) {
4940 if (option_verbose
> 2)
4941 ast_verbose(VERBOSE_PREFIX_3
"CPE does not support Call Waiting Caller*ID.\n");
4942 restore_conference(p
);
4944 if (p
->subs
[index
].linear
) {
4945 p
->subs
[index
].f
.datalen
= READ_SIZE
* 2;
4947 p
->subs
[index
].f
.datalen
= READ_SIZE
;
4949 /* Handle CallerID Transmission */
4950 if ((p
->owner
== ast
) && p
->cidspill
&&((ast
->_state
== AST_STATE_UP
) || (ast
->rings
== p
->cidrings
))) {
4954 p
->subs
[index
].f
.frametype
= AST_FRAME_VOICE
;
4955 p
->subs
[index
].f
.subclass
= ast
->rawreadformat
;
4956 p
->subs
[index
].f
.samples
= READ_SIZE
;
4957 p
->subs
[index
].f
.mallocd
= 0;
4958 p
->subs
[index
].f
.offset
= AST_FRIENDLY_OFFSET
;
4959 p
->subs
[index
].f
.data
= p
->subs
[index
].buffer
+ AST_FRIENDLY_OFFSET
/ sizeof(p
->subs
[index
].buffer
[0]);
4961 ast_log(LOG_DEBUG
, "Read %d of voice on %s\n", p
->subs
[index
].f
.datalen
, ast
->name
);
4963 if (p
->dialing
|| /* Transmitting something */
4964 (index
&& (ast
->_state
!= AST_STATE_UP
)) || /* Three-way or callwait that isn't up */
4965 ((index
== SUB_CALLWAIT
) && !p
->subs
[SUB_CALLWAIT
].inthreeway
) /* Inactive and non-confed call-wait */
4967 /* Whoops, we're still dialing, or in a state where we shouldn't transmit....
4968 don't send anything */
4969 p
->subs
[index
].f
.frametype
= AST_FRAME_NULL
;
4970 p
->subs
[index
].f
.subclass
= 0;
4971 p
->subs
[index
].f
.samples
= 0;
4972 p
->subs
[index
].f
.mallocd
= 0;
4973 p
->subs
[index
].f
.offset
= 0;
4974 p
->subs
[index
].f
.data
= NULL
;
4975 p
->subs
[index
].f
.datalen
= 0;
4977 if (p
->dsp
&& (!p
->ignoredtmf
|| p
->callwaitcas
|| p
->busydetect
|| p
->callprogress
) && !index
) {
4978 /* Perform busy detection. etc on the dahdi line */
4979 f
= ast_dsp_process(ast
, p
->dsp
, &p
->subs
[index
].f
);
4981 if ((f
->frametype
== AST_FRAME_CONTROL
) && (f
->subclass
== AST_CONTROL_BUSY
)) {
4982 if ((ast
->_state
== AST_STATE_UP
) && !p
->outgoing
) {
4983 /* Treat this as a "hangup" instead of a "busy" on the assumption that
4987 } else if (f
->frametype
== AST_FRAME_DTMF
) {
4989 if (!p
->proceeding
&& p
->sig
==SIG_PRI
&& p
->pri
&& p
->pri
->overlapdial
) {
4990 /* Don't accept in-band DTMF when in overlap dial mode */
4991 f
->frametype
= AST_FRAME_NULL
;
4995 /* DSP clears us of being pulse */
5000 f
= &p
->subs
[index
].f
;
5002 if (f
&& (f
->frametype
== AST_FRAME_DTMF
))
5003 dahdi_handle_dtmfup(ast
, index
, &f
);
5005 /* If we have a fake_event, trigger exception to handle it */
5007 ast_set_flag(ast
, AST_FLAG_EXCEPTION
);
5009 ast_mutex_unlock(&p
->lock
);
5013 static int my_dahdi_write(struct dahdi_pvt
*p
, unsigned char *buf
, int len
, int index
, int linear
)
5019 fd
= p
->subs
[index
].dfd
;
5022 if (size
> (linear
? READ_SIZE
* 2 : READ_SIZE
))
5023 size
= (linear
? READ_SIZE
* 2 : READ_SIZE
);
5024 res
= write(fd
, buf
, size
);
5027 ast_log(LOG_DEBUG
, "Write returned %d (%s) on channel %d\n", res
, strerror(errno
), p
->channel
);
5036 static int dahdi_write(struct ast_channel
*ast
, struct ast_frame
*frame
)
5038 struct dahdi_pvt
*p
= ast
->tech_pvt
;
5041 index
= dahdi_get_index(ast
, p
, 0);
5043 ast_log(LOG_WARNING
, "%s doesn't really exist?\n", ast
->name
);
5049 ast_mutex_lock(&p
->lock
);
5050 if (!p
->proceeding
&& p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
) {
5052 if (!pri_grab(p
, p
->pri
)) {
5053 pri_progress(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), !p
->digital
);
5056 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5060 ast_mutex_unlock(&p
->lock
);
5063 /* Write a frame of (presumably voice) data */
5064 if (frame
->frametype
!= AST_FRAME_VOICE
) {
5065 if (frame
->frametype
!= AST_FRAME_IMAGE
)
5066 ast_log(LOG_WARNING
, "Don't know what to do with frame type '%d'\n", frame
->frametype
);
5069 if ((frame
->subclass
!= AST_FORMAT_SLINEAR
) &&
5070 (frame
->subclass
!= AST_FORMAT_ULAW
) &&
5071 (frame
->subclass
!= AST_FORMAT_ALAW
)) {
5072 ast_log(LOG_WARNING
, "Cannot handle frames in %d format\n", frame
->subclass
);
5077 ast_log(LOG_DEBUG
, "Dropping frame since I'm still dialing on %s...\n",ast
->name
);
5082 ast_log(LOG_DEBUG
, "Dropping frame since there is no active owner on %s...\n",ast
->name
);
5087 ast_log(LOG_DEBUG
, "Dropping frame since I've still got a callerid spill\n");
5090 /* Return if it's not valid data */
5091 if (!frame
->data
|| !frame
->datalen
)
5094 if (frame
->subclass
== AST_FORMAT_SLINEAR
) {
5095 if (!p
->subs
[index
].linear
) {
5096 p
->subs
[index
].linear
= 1;
5097 res
= dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
5099 ast_log(LOG_WARNING
, "Unable to set linear mode on channel %d\n", p
->channel
);
5101 res
= my_dahdi_write(p
, (unsigned char *)frame
->data
, frame
->datalen
, index
, 1);
5104 if (p
->subs
[index
].linear
) {
5105 p
->subs
[index
].linear
= 0;
5106 res
= dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
5108 ast_log(LOG_WARNING
, "Unable to set companded mode on channel %d\n", p
->channel
);
5110 res
= my_dahdi_write(p
, (unsigned char *)frame
->data
, frame
->datalen
, index
, 0);
5113 ast_log(LOG_WARNING
, "write failed: %s\n", strerror(errno
));
5119 static int dahdi_indicate(struct ast_channel
*chan
, int condition
, const void *data
, size_t datalen
)
5121 struct dahdi_pvt
*p
= chan
->tech_pvt
;
5124 int func
= DAHDI_FLASH
;
5125 ast_mutex_lock(&p
->lock
);
5126 index
= dahdi_get_index(chan
, p
, 0);
5128 ast_log(LOG_DEBUG
, "Requested indication %d on channel %s\n", condition
, chan
->name
);
5129 if (index
== SUB_REAL
) {
5130 switch (condition
) {
5131 case AST_CONTROL_BUSY
:
5133 if (p
->priindication_oob
&& p
->sig
== SIG_PRI
) {
5134 chan
->hangupcause
= AST_CAUSE_USER_BUSY
;
5135 chan
->_softhangup
|= AST_SOFTHANGUP_DEV
;
5137 } else if (!p
->progress
&& p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
) {
5139 if (!pri_grab(p
, p
->pri
)) {
5140 pri_progress(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), 1);
5144 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5147 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_BUSY
);
5150 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_BUSY
);
5152 case AST_CONTROL_RINGING
:
5154 if ((!p
->alerting
) && p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
&& (chan
->_state
!= AST_STATE_UP
)) {
5156 if (!pri_grab(p
, p
->pri
)) {
5157 pri_acknowledge(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), !p
->digital
);
5161 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5166 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_RINGTONE
);
5167 if (chan
->_state
!= AST_STATE_UP
) {
5168 if ((chan
->_state
!= AST_STATE_RING
) ||
5169 ((p
->sig
!= SIG_FXSKS
) &&
5170 (p
->sig
!= SIG_FXSLS
) &&
5171 (p
->sig
!= SIG_FXSGS
)))
5172 ast_setstate(chan
, AST_STATE_RINGING
);
5175 case AST_CONTROL_PROCEEDING
:
5176 ast_log(LOG_DEBUG
,"Received AST_CONTROL_PROCEEDING on %s\n",chan
->name
);
5178 if (!p
->proceeding
&& p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
) {
5180 if (!pri_grab(p
, p
->pri
)) {
5181 pri_proceeding(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), !p
->digital
);
5185 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5190 /* don't continue in ast_indicate */
5193 case AST_CONTROL_PROGRESS
:
5194 ast_log(LOG_DEBUG
,"Received AST_CONTROL_PROGRESS on %s\n",chan
->name
);
5196 p
->digital
= 0; /* Digital-only calls isn't allows any inband progress messages */
5197 if (!p
->progress
&& p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
) {
5199 if (!pri_grab(p
, p
->pri
)) {
5200 pri_progress(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), 1);
5204 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5209 /* don't continue in ast_indicate */
5212 case AST_CONTROL_CONGESTION
:
5213 chan
->hangupcause
= AST_CAUSE_CONGESTION
;
5215 if (p
->priindication_oob
&& p
->sig
== SIG_PRI
) {
5216 chan
->hangupcause
= AST_CAUSE_SWITCH_CONGESTION
;
5217 chan
->_softhangup
|= AST_SOFTHANGUP_DEV
;
5219 } else if (!p
->progress
&& p
->sig
==SIG_PRI
&& p
->pri
&& !p
->outgoing
) {
5221 if (!pri_grab(p
, p
->pri
)) {
5222 pri_progress(p
->pri
->pri
,p
->call
, PVT_TO_CHANNEL(p
), 1);
5225 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5228 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5231 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5233 case AST_CONTROL_HOLD
:
5235 if (p
->pri
&& !strcasecmp(p
->mohinterpret
, "passthrough")) {
5236 if (!pri_grab(p
, p
->pri
)) {
5237 res
= pri_notify(p
->pri
->pri
, p
->call
, p
->prioffset
, PRI_NOTIFY_REMOTE_HOLD
);
5240 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5243 ast_moh_start(chan
, data
, p
->mohinterpret
);
5245 case AST_CONTROL_UNHOLD
:
5247 if (p
->pri
&& !strcasecmp(p
->mohinterpret
, "passthrough")) {
5248 if (!pri_grab(p
, p
->pri
)) {
5249 res
= pri_notify(p
->pri
->pri
, p
->call
, p
->prioffset
, PRI_NOTIFY_REMOTE_RETRIEVAL
);
5252 ast_log(LOG_WARNING
, "Unable to grab PRI on span %d\n", p
->span
);
5257 case AST_CONTROL_RADIO_KEY
:
5259 res
= dahdi_set_hook(p
->subs
[index
].dfd
, DAHDI_OFFHOOK
);
5262 case AST_CONTROL_RADIO_UNKEY
:
5264 res
= dahdi_set_hook(p
->subs
[index
].dfd
, DAHDI_RINGOFF
);
5267 case AST_CONTROL_FLASH
:
5268 /* flash hookswitch */
5269 if (ISTRUNK(p
) && (p
->sig
!= SIG_PRI
)) {
5270 /* Clear out the dial buffer */
5271 p
->dop
.dialstr
[0] = '\0';
5272 if ((ioctl(p
->subs
[SUB_REAL
].dfd
,DAHDI_HOOK
,&func
) == -1) && (errno
!= EINPROGRESS
)) {
5273 ast_log(LOG_WARNING
, "Unable to flash external trunk on channel %s: %s\n",
5274 chan
->name
, strerror(errno
));
5280 case AST_CONTROL_SRCUPDATE
:
5284 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5289 ast_mutex_unlock(&p
->lock
);
5293 static struct ast_channel
*dahdi_new(struct dahdi_pvt
*i
, int state
, int startpbx
, int index
, int law
, int transfercapability
)
5295 struct ast_channel
*tmp
;
5301 struct dahdi_params ps
;
5302 char chanprefix
[*dahdi_chan_name_len
+ 4];
5304 if (i
->subs
[index
].owner
) {
5305 ast_log(LOG_WARNING
, "Channel %d already has a %s call\n", i
->channel
,subnames
[index
]);
5313 if (i
->bearer
|| (i
->pri
&& (i
->sig
== SIG_FXSKS
)))
5314 b2
= ast_safe_string_alloc("%d:%d-%d", i
->pri
->trunkgroup
, i
->channel
, y
);
5317 if (i
->channel
== CHAN_PSEUDO
)
5318 b2
= ast_safe_string_alloc("pseudo-%ld", ast_random());
5320 b2
= ast_safe_string_alloc("%d-%d", i
->channel
, y
);
5321 for (x
= 0; x
< 3; x
++) {
5322 if ((index
!= x
) && i
->subs
[x
].owner
&& !strcasecmp(b2
, i
->subs
[x
].owner
->name
+ (!strncmp(i
->subs
[x
].owner
->name
, "Zap", 3) ? 4 : 6)))
5327 strcpy(chanprefix
, dahdi_chan_name
);
5328 strcat(chanprefix
, "/%s");
5329 tmp
= ast_channel_alloc(0, state
, i
->cid_num
, i
->cid_name
, i
->accountcode
, i
->exten
, i
->context
, i
->amaflags
, chanprefix
, b2
);
5330 if (b2
) /*!> b2 can be freed now, it's been copied into the channel structure */
5334 tmp
->tech
= chan_tech
;
5335 ps
.channo
= i
->channel
;
5336 res
= ioctl(i
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &ps
);
5338 ast_log(LOG_WARNING
, "Unable to get parameters, assuming MULAW: %s\n", strerror(errno
));
5339 ps
.curlaw
= DAHDI_LAW_MULAW
;
5341 if (ps
.curlaw
== DAHDI_LAW_ALAW
)
5342 deflaw
= AST_FORMAT_ALAW
;
5344 deflaw
= AST_FORMAT_ULAW
;
5346 if (law
== DAHDI_LAW_ALAW
)
5347 deflaw
= AST_FORMAT_ALAW
;
5349 deflaw
= AST_FORMAT_ULAW
;
5351 tmp
->fds
[0] = i
->subs
[index
].dfd
;
5352 tmp
->nativeformats
= AST_FORMAT_SLINEAR
| deflaw
;
5353 /* Start out assuming ulaw since it's smaller :) */
5354 tmp
->rawreadformat
= deflaw
;
5355 tmp
->readformat
= deflaw
;
5356 tmp
->rawwriteformat
= deflaw
;
5357 tmp
->writeformat
= deflaw
;
5358 i
->subs
[index
].linear
= 0;
5359 dahdi_setlinear(i
->subs
[index
].dfd
, i
->subs
[index
].linear
);
5361 if (index
== SUB_REAL
) {
5362 if (i
->busydetect
&& CANBUSYDETECT(i
))
5363 features
|= DSP_FEATURE_BUSY_DETECT
;
5364 if ((i
->callprogress
& 1) && CANPROGRESSDETECT(i
))
5365 features
|= DSP_FEATURE_CALL_PROGRESS
;
5366 if ((!i
->outgoing
&& (i
->callprogress
& 4)) ||
5367 (i
->outgoing
&& (i
->callprogress
& 2))) {
5368 features
|= DSP_FEATURE_FAX_DETECT
;
5370 #ifdef DAHDI_TONEDETECT
5371 x
= DAHDI_TONEDETECT_ON
| DAHDI_TONEDETECT_MUTE
;
5372 if (ioctl(i
->subs
[index
].dfd
, DAHDI_TONEDETECT
, &x
)) {
5374 i
->hardwaredtmf
= 0;
5375 features
|= DSP_FEATURE_DTMF_DETECT
;
5376 #ifdef DAHDI_TONEDETECT
5377 } else if (NEED_MFDETECT(i
)) {
5378 i
->hardwaredtmf
= 1;
5379 features
|= DSP_FEATURE_DTMF_DETECT
;
5385 ast_log(LOG_DEBUG
, "Already have a dsp on %s?\n", tmp
->name
);
5387 if (i
->channel
!= CHAN_PSEUDO
)
5388 i
->dsp
= ast_dsp_new();
5392 i
->dsp_features
= features
;
5394 /* We cannot do progress detection until receives PROGRESS message */
5395 if (i
->outgoing
&& (i
->sig
== SIG_PRI
)) {
5396 /* Remember requested DSP features, don't treat
5397 talking as ANSWER */
5398 i
->dsp_features
= features
& ~DSP_PROGRESS_TALK
;
5402 ast_dsp_set_features(i
->dsp
, features
);
5403 ast_dsp_digitmode(i
->dsp
, DSP_DIGITMODE_DTMF
| i
->dtmfrelax
);
5404 if (!ast_strlen_zero(progzone
))
5405 ast_dsp_set_call_progress_zone(i
->dsp
, progzone
);
5406 if (i
->busydetect
&& CANBUSYDETECT(i
)) {
5407 ast_dsp_set_busy_count(i
->dsp
, i
->busycount
);
5408 ast_dsp_set_busy_pattern(i
->dsp
, i
->busy_tonelength
, i
->busy_quietlength
);
5414 if (state
== AST_STATE_RING
)
5417 if ((i
->sig
== SIG_FXOKS
) || (i
->sig
== SIG_FXOGS
) || (i
->sig
== SIG_FXOLS
)) {
5418 /* Only FXO signalled stuff can be picked up */
5419 tmp
->callgroup
= i
->callgroup
;
5420 tmp
->pickupgroup
= i
->pickupgroup
;
5422 if (!ast_strlen_zero(i
->language
))
5423 ast_string_field_set(tmp
, language
, i
->language
);
5426 if (!ast_strlen_zero(i
->accountcode
))
5427 ast_string_field_set(tmp
, accountcode
, i
->accountcode
);
5429 tmp
->amaflags
= i
->amaflags
;
5430 i
->subs
[index
].owner
= tmp
;
5431 ast_copy_string(tmp
->context
, i
->context
, sizeof(tmp
->context
));
5432 ast_string_field_set(tmp
, call_forward
, i
->call_forward
);
5433 /* If we've been told "no ADSI" then enforce it */
5435 tmp
->adsicpe
= AST_ADSI_UNAVAILABLE
;
5436 if (!ast_strlen_zero(i
->exten
))
5437 ast_copy_string(tmp
->exten
, i
->exten
, sizeof(tmp
->exten
));
5438 if (!ast_strlen_zero(i
->rdnis
))
5439 tmp
->cid
.cid_rdnis
= ast_strdup(i
->rdnis
);
5440 if (!ast_strlen_zero(i
->dnid
))
5441 tmp
->cid
.cid_dnid
= ast_strdup(i
->dnid
);
5443 /* Don't use ast_set_callerid() here because it will
5444 * generate a needless NewCallerID event */
5446 if (!ast_strlen_zero(i
->cid_ani
))
5447 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_ani
);
5449 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
5451 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
5453 tmp
->cid
.cid_pres
= i
->callingpres
;
5454 tmp
->cid
.cid_ton
= i
->cid_ton
;
5456 tmp
->transfercapability
= transfercapability
;
5457 pbx_builtin_setvar_helper(tmp
, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability
));
5458 if (transfercapability
& PRI_TRANS_CAP_DIGITAL
)
5460 /* Assume calls are not idle calls unless we're told differently */
5462 i
->alreadyhungup
= 0;
5464 /* clear the fake event in case we posted one before we had ast_channel */
5466 /* Assure there is no confmute on this channel */
5467 dahdi_confmute(i
, 0);
5468 /* Configure the new channel jb */
5469 ast_jb_configure(tmp
, &global_jbconf
);
5471 if (ast_pbx_start(tmp
)) {
5472 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
5479 ast_module_ref(ast_module_info
->self
);
5485 static int my_getsigstr(struct ast_channel
*chan
, char *str
, const char *term
, int ms
)
5489 *str
= 0; /* start with empty output buffer */
5492 /* Wait for the first digit (up to specified ms). */
5493 c
= ast_waitfordigit(chan
, ms
);
5494 /* if timeout, hangup or error, return as such */
5499 if (strchr(term
, c
))
5504 static int dahdi_wink(struct dahdi_pvt
*p
, int index
)
5507 dahdi_set_hook(p
->subs
[index
].dfd
, DAHDI_WINK
);
5510 /* set bits of interest */
5511 j
= DAHDI_IOMUX_SIGEVENT
;
5512 /* wait for some happening */
5513 if (ioctl(p
->subs
[index
].dfd
,DAHDI_IOMUX
,&j
) == -1) return(-1);
5514 /* exit loop if we have it */
5515 if (j
& DAHDI_IOMUX_SIGEVENT
) break;
5517 /* get the event info */
5518 if (ioctl(p
->subs
[index
].dfd
,DAHDI_GETEVENT
,&j
) == -1) return(-1);
5522 static void *ss_thread(void *data
)
5524 struct ast_channel
*chan
= data
;
5525 struct dahdi_pvt
*p
= chan
->tech_pvt
;
5526 char exten
[AST_MAX_EXTENSION
] = "";
5527 char exten2
[AST_MAX_EXTENSION
] = "";
5528 unsigned char buf
[256];
5531 struct callerid_state
*cs
= NULL
;
5532 char *name
= NULL
, *number
= NULL
;
5539 struct ast_smdi_md_message
*smdi_msg
= NULL
;
5550 /* in the bizarre case where the channel has become a zombie before we
5551 even get started here, abort safely
5554 ast_log(LOG_WARNING
, "Channel became a zombie before simple switch could be started (%s)\n", chan
->name
);
5558 if (option_verbose
> 2)
5559 ast_verbose( VERBOSE_PREFIX_3
"Starting simple switch on '%s'\n", chan
->name
);
5560 index
= dahdi_get_index(chan
, p
, 1);
5562 ast_log(LOG_WARNING
, "Huh?\n");
5567 ast_dsp_digitreset(p
->dsp
);
5571 /* Now loop looking for an extension */
5572 ast_copy_string(exten
, p
->exten
, sizeof(exten
));
5573 len
= strlen(exten
);
5575 while ((len
< AST_MAX_EXTENSION
-1) && ast_matchmore_extension(chan
, chan
->context
, exten
, 1, p
->cid_num
)) {
5576 if (len
&& !ast_ignore_pattern(chan
->context
, exten
))
5577 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5579 tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALTONE
);
5580 if (ast_exists_extension(chan
, chan
->context
, exten
, 1, p
->cid_num
))
5581 timeout
= matchdigittimeout
;
5583 timeout
= gendigittimeout
;
5584 res
= ast_waitfordigit(chan
, timeout
);
5586 ast_log(LOG_DEBUG
, "waitfordigit returned < 0...\n");
5595 /* if no extension was received ('unspecified') on overlap call, use the 's' extension */
5596 if (ast_strlen_zero(exten
)) {
5597 if (option_verbose
> 2)
5598 ast_verbose(VERBOSE_PREFIX_3
"Going to extension s|1 because of empty extension received on overlap call\n");
5602 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5603 if (ast_exists_extension(chan
, chan
->context
, exten
, 1, p
->cid_num
)) {
5604 /* Start the real PBX */
5605 ast_copy_string(chan
->exten
, exten
, sizeof(chan
->exten
));
5606 if (p
->dsp
) ast_dsp_digitreset(p
->dsp
);
5608 ast_setstate(chan
, AST_STATE_RING
);
5609 res
= ast_pbx_run(chan
);
5611 ast_log(LOG_WARNING
, "PBX exited non-zero!\n");
5614 ast_log(LOG_DEBUG
, "No such possible extension '%s' in context '%s'\n", exten
, chan
->context
);
5615 chan
->hangupcause
= AST_CAUSE_UNALLOCATED
;
5618 /* Since we send release complete here, we won't get one */
5626 case SIG_FEATDMF_TA
:
5628 case SIG_FGC_CAMAMF
:
5632 case SIG_SF_FEATDMF
:
5635 if (dahdi_wink(p
, index
))
5642 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5644 ast_dsp_digitreset(p
->dsp
);
5645 /* set digit mode appropriately */
5647 if (NEED_MFDETECT(p
))
5648 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_MF
| p
->dtmfrelax
);
5650 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_DTMF
| p
->dtmfrelax
);
5652 memset(dtmfbuf
, 0, sizeof(dtmfbuf
));
5653 /* Wait for the first digit only if immediate=no */
5655 /* Wait for the first digit (up to 5 seconds). */
5656 res
= ast_waitfordigit(chan
, 5000);
5660 /* save first char */
5665 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "*", 3000);
5667 res
= my_getsigstr(chan
, dtmfbuf
+ strlen(dtmfbuf
), "*", 3000);
5668 if ((res
< 1) && (p
->dsp
)) ast_dsp_digitreset(p
->dsp
);
5670 case SIG_FEATDMF_TA
:
5671 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "#", 3000);
5672 if ((res
< 1) && (p
->dsp
)) ast_dsp_digitreset(p
->dsp
);
5673 if (dahdi_wink(p
, index
)) goto quit
;
5675 /* Wait for the first digit (up to 5 seconds). */
5676 res
= ast_waitfordigit(chan
, 5000);
5677 if (res
<= 0) break;
5679 /* fall through intentionally */
5682 case SIG_FGC_CAMAMF
:
5683 case SIG_SF_FEATDMF
:
5684 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "#", 3000);
5685 /* if international caca, do it again to get real ANO */
5686 if ((p
->sig
== SIG_FEATDMF
) && (dtmfbuf
[1] != '0') && (strlen(dtmfbuf
) != 14))
5688 if (dahdi_wink(p
, index
)) goto quit
;
5690 /* Wait for the first digit (up to 5 seconds). */
5691 res
= ast_waitfordigit(chan
, 5000);
5692 if (res
<= 0) break;
5694 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "#", 3000);
5697 /* if E911, take off hook */
5698 if (p
->sig
== SIG_E911
)
5699 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
5700 res
= my_getsigstr(chan
, dtmfbuf
+ strlen(dtmfbuf
), "#", 3000);
5702 if ((res
< 1) && (p
->dsp
)) ast_dsp_digitreset(p
->dsp
);
5706 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "#", 3000);
5707 if ((res
< 1) && (p
->dsp
)) ast_dsp_digitreset(p
->dsp
);
5710 /* if we received a '*', we are actually receiving Feature Group D
5711 dial syntax, so use that mode; otherwise, fall through to normal
5715 res
= my_getsigstr(chan
, dtmfbuf
+ 1, "*", 3000);
5717 res
= my_getsigstr(chan
, dtmfbuf
+ strlen(dtmfbuf
), "*", 3000);
5718 if ((res
< 1) && (p
->dsp
)) ast_dsp_digitreset(p
->dsp
);
5722 /* If we got the first digit, get the rest */
5724 dtmfbuf
[len
] = '\0';
5725 while ((len
< AST_MAX_EXTENSION
-1) && ast_matchmore_extension(chan
, chan
->context
, dtmfbuf
, 1, p
->cid_num
)) {
5726 if (ast_exists_extension(chan
, chan
->context
, dtmfbuf
, 1, p
->cid_num
)) {
5727 timeout
= matchdigittimeout
;
5729 timeout
= gendigittimeout
;
5731 res
= ast_waitfordigit(chan
, timeout
);
5733 ast_log(LOG_DEBUG
, "waitfordigit returned < 0...\n");
5737 dtmfbuf
[len
++] = res
;
5738 dtmfbuf
[len
] = '\0';
5747 ast_log(LOG_WARNING
, "getdtmf on channel %d: %s\n", p
->channel
, strerror(errno
));
5750 } else if (res
< 0) {
5751 ast_log(LOG_DEBUG
, "Got hung up before digits finished\n");
5756 if (p
->sig
== SIG_FGC_CAMA
) {
5759 if (ast_safe_sleep(chan
,1000) == -1) {
5763 dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
5764 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_MF
| p
->dtmfrelax
);
5765 res
= my_getsigstr(chan
, anibuf
, "#", 10000);
5766 if ((res
> 0) && (strlen(anibuf
) > 2)) {
5767 if (anibuf
[strlen(anibuf
) - 1] == '#')
5768 anibuf
[strlen(anibuf
) - 1] = 0;
5769 ast_set_callerid(chan
, anibuf
+ 2, NULL
, anibuf
+ 2);
5771 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_DTMF
| p
->dtmfrelax
);
5774 ast_copy_string(exten
, dtmfbuf
, sizeof(exten
));
5775 if (ast_strlen_zero(exten
))
5776 ast_copy_string(exten
, "s", sizeof(exten
));
5777 if (p
->sig
== SIG_FEATD
|| p
->sig
== SIG_EMWINK
) {
5778 /* Look for Feature Group D on all E&M Wink and Feature Group D trunks */
5779 if (exten
[0] == '*') {
5781 ast_copy_string(exten2
, exten
, sizeof(exten2
));
5782 /* Parse out extension and callerid */
5784 s1
= strsep(&stringp
, "*");
5785 s2
= strsep(&stringp
, "*");
5787 if (!ast_strlen_zero(p
->cid_num
))
5788 ast_set_callerid(chan
, p
->cid_num
, NULL
, p
->cid_num
);
5790 ast_set_callerid(chan
, s1
, NULL
, s1
);
5791 ast_copy_string(exten
, s2
, sizeof(exten
));
5793 ast_copy_string(exten
, s1
, sizeof(exten
));
5794 } else if (p
->sig
== SIG_FEATD
)
5795 ast_log(LOG_WARNING
, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p
->channel
);
5797 if ((p
->sig
== SIG_FEATDMF
) || (p
->sig
== SIG_FEATDMF_TA
)) {
5798 if (exten
[0] == '*') {
5800 ast_copy_string(exten2
, exten
, sizeof(exten2
));
5801 /* Parse out extension and callerid */
5803 s1
= strsep(&stringp
, "#");
5804 s2
= strsep(&stringp
, "#");
5806 if (!ast_strlen_zero(p
->cid_num
))
5807 ast_set_callerid(chan
, p
->cid_num
, NULL
, p
->cid_num
);
5810 ast_set_callerid(chan
, s1
+ 2, NULL
, s1
+ 2);
5811 ast_copy_string(exten
, s2
+ 1, sizeof(exten
));
5813 ast_copy_string(exten
, s1
+ 2, sizeof(exten
));
5815 ast_log(LOG_WARNING
, "Got a non-Feature Group D input on channel %d. Assuming E&M Wink instead\n", p
->channel
);
5817 if ((p
->sig
== SIG_E911
) || (p
->sig
== SIG_FGC_CAMAMF
)) {
5818 if (exten
[0] == '*') {
5820 ast_copy_string(exten2
, exten
, sizeof(exten2
));
5821 /* Parse out extension and callerid */
5823 s1
= strsep(&stringp
, "#");
5824 s2
= strsep(&stringp
, "#");
5825 if (s2
&& (*(s2
+ 1) == '0')) {
5827 ast_set_callerid(chan
, s2
+ 2, NULL
, s2
+ 2);
5829 if (s1
) ast_copy_string(exten
, s1
, sizeof(exten
));
5830 else ast_copy_string(exten
, "911", sizeof(exten
));
5832 ast_log(LOG_WARNING
, "Got a non-E911/FGC CAMA input on channel %d. Assuming E&M Wink instead\n", p
->channel
);
5834 if (p
->sig
== SIG_FEATB
) {
5835 if (exten
[0] == '*') {
5837 ast_copy_string(exten2
, exten
, sizeof(exten2
));
5838 /* Parse out extension and callerid */
5840 s1
= strsep(&stringp
, "#");
5841 ast_copy_string(exten
, exten2
+ 1, sizeof(exten
));
5843 ast_log(LOG_WARNING
, "Got a non-Feature Group B input on channel %d. Assuming E&M Wink instead\n", p
->channel
);
5845 if ((p
->sig
== SIG_FEATDMF
) || (p
->sig
== SIG_FEATDMF_TA
)) {
5846 dahdi_wink(p
, index
);
5847 /* some switches require a minimum guard time between
5848 the last FGD wink and something that answers
5849 immediately. This ensures it */
5850 if (ast_safe_sleep(chan
,100)) goto quit
;
5853 if (NEED_MFDETECT(p
)) {
5855 if (!p
->hardwaredtmf
)
5856 ast_dsp_digitmode(p
->dsp
,DSP_DIGITMODE_DTMF
| p
->dtmfrelax
);
5858 ast_dsp_free(p
->dsp
);
5864 if (ast_exists_extension(chan
, chan
->context
, exten
, 1, chan
->cid
.cid_num
)) {
5865 ast_copy_string(chan
->exten
, exten
, sizeof(chan
->exten
));
5866 if (p
->dsp
) ast_dsp_digitreset(p
->dsp
);
5867 res
= ast_pbx_run(chan
);
5869 ast_log(LOG_WARNING
, "PBX exited non-zero\n");
5870 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5874 if (option_verbose
> 2)
5875 ast_verbose(VERBOSE_PREFIX_2
"Unknown extension '%s' in context '%s' requested\n", exten
, chan
->context
);
5877 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_INFO
);
5879 ast_log(LOG_WARNING
, "Unable to start special tone on %d\n", p
->channel
);
5882 res
= ast_streamfile(chan
, "ss-noservice", chan
->language
);
5884 ast_waitstream(chan
, "");
5885 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5893 /* Read the first digit */
5894 timeout
= firstdigittimeout
;
5895 /* If starting a threeway call, never timeout on the first digit so someone
5896 can use flash-hook as a "hold" feature */
5897 if (p
->subs
[SUB_THREEWAY
].owner
)
5899 while (len
< AST_MAX_EXTENSION
-1) {
5900 /* Read digit unless it's supposed to be immediate, in which case the
5901 only answer is 's' */
5905 res
= ast_waitfordigit(chan
, timeout
);
5908 ast_log(LOG_DEBUG
, "waitfordigit returned < 0...\n");
5909 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5916 if (!ast_ignore_pattern(chan
->context
, exten
))
5917 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5919 tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALTONE
);
5920 if (ast_exists_extension(chan
, chan
->context
, exten
, 1, p
->cid_num
) && strcmp(exten
, ast_parking_ext())) {
5921 if (!res
|| !ast_matchmore_extension(chan
, chan
->context
, exten
, 1, p
->cid_num
)) {
5923 /* Record this as the forwarding extension */
5924 ast_copy_string(p
->call_forward
, exten
, sizeof(p
->call_forward
));
5925 if (option_verbose
> 2)
5926 ast_verbose(VERBOSE_PREFIX_3
"Setting call forward to '%s' on channel %d\n", p
->call_forward
, p
->channel
);
5927 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
5931 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5933 memset(exten
, 0, sizeof(exten
));
5934 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALTONE
);
5938 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
5939 ast_copy_string(chan
->exten
, exten
, sizeof(chan
->exten
));
5940 if (!ast_strlen_zero(p
->cid_num
)) {
5941 if (!p
->hidecallerid
)
5942 ast_set_callerid(chan
, p
->cid_num
, NULL
, p
->cid_num
);
5944 ast_set_callerid(chan
, NULL
, NULL
, p
->cid_num
);
5946 if (!ast_strlen_zero(p
->cid_name
)) {
5947 if (!p
->hidecallerid
)
5948 ast_set_callerid(chan
, NULL
, p
->cid_name
, NULL
);
5950 ast_setstate(chan
, AST_STATE_RING
);
5952 res
= ast_pbx_run(chan
);
5954 ast_log(LOG_WARNING
, "PBX exited non-zero\n");
5955 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5960 /* It's a match, but they just typed a digit, and there is an ambiguous match,
5961 so just set the timeout to matchdigittimeout and wait some more */
5962 timeout
= matchdigittimeout
;
5964 } else if (res
== 0) {
5965 ast_log(LOG_DEBUG
, "not enough digits (and no ambiguous match)...\n");
5966 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
5967 dahdi_wait_event(p
->subs
[index
].dfd
);
5970 } else if (p
->callwaiting
&& !strcmp(exten
, "*70")) {
5971 if (option_verbose
> 2)
5972 ast_verbose(VERBOSE_PREFIX_3
"Disabling call waiting on %s\n", chan
->name
);
5973 /* Disable call waiting if enabled */
5975 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
5977 ast_log(LOG_WARNING
, "Unable to do dial recall on channel %s: %s\n",
5978 chan
->name
, strerror(errno
));
5981 ioctl(p
->subs
[index
].dfd
,DAHDI_CONFDIAG
,&len
);
5982 memset(exten
, 0, sizeof(exten
));
5983 timeout
= firstdigittimeout
;
5985 } else if (!strcmp(exten
,ast_pickup_ext())) {
5986 /* Scan all channels and see if there are any
5987 * ringing channels that have call groups
5988 * that equal this channels pickup group
5990 if (index
== SUB_REAL
) {
5991 /* Switch us from Third call to Call Wait */
5992 if (p
->subs
[SUB_THREEWAY
].owner
) {
5993 /* If you make a threeway call and the *8# a call, it should actually
5994 look like a callwait */
5995 alloc_sub(p
, SUB_CALLWAIT
);
5996 swap_subs(p
, SUB_CALLWAIT
, SUB_THREEWAY
);
5997 unalloc_sub(p
, SUB_THREEWAY
);
6000 if (ast_pickup_call(chan
)) {
6001 ast_log(LOG_DEBUG
, "No call pickup possible...\n");
6002 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
6003 dahdi_wait_event(p
->subs
[index
].dfd
);
6008 ast_log(LOG_WARNING
, "Huh? Got *8# on call not on real\n");
6013 } else if (!p
->hidecallerid
&& !strcmp(exten
, "*67")) {
6014 if (option_verbose
> 2)
6015 ast_verbose(VERBOSE_PREFIX_3
"Disabling Caller*ID on %s\n", chan
->name
);
6016 /* Disable Caller*ID if enabled */
6017 p
->hidecallerid
= 1;
6018 if (chan
->cid
.cid_num
)
6019 free(chan
->cid
.cid_num
);
6020 chan
->cid
.cid_num
= NULL
;
6021 if (chan
->cid
.cid_name
)
6022 free(chan
->cid
.cid_name
);
6023 chan
->cid
.cid_name
= NULL
;
6024 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6026 ast_log(LOG_WARNING
, "Unable to do dial recall on channel %s: %s\n",
6027 chan
->name
, strerror(errno
));
6030 memset(exten
, 0, sizeof(exten
));
6031 timeout
= firstdigittimeout
;
6032 } else if (p
->callreturn
&& !strcmp(exten
, "*69")) {
6034 if (!ast_strlen_zero(p
->lastcid_num
)) {
6035 res
= ast_say_digit_str(chan
, p
->lastcid_num
, "", chan
->language
);
6038 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6040 } else if (!strcmp(exten
, "*78")) {
6041 /* Do not disturb */
6042 if (option_verbose
> 2)
6043 ast_verbose(VERBOSE_PREFIX_3
"Enabled DND on channel %d\n", p
->channel
);
6044 manager_event(EVENT_FLAG_SYSTEM
, "DNDState",
6045 "Channel: %s/%d\r\n"
6046 "Status: enabled\r\n", dahdi_chan_name
, p
->channel
);
6047 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6050 memset(exten
, 0, sizeof(exten
));
6052 } else if (!strcmp(exten
, "*79")) {
6053 /* Do not disturb */
6054 if (option_verbose
> 2)
6055 ast_verbose(VERBOSE_PREFIX_3
"Disabled DND on channel %d\n", p
->channel
);
6056 manager_event(EVENT_FLAG_SYSTEM
, "DNDState",
6057 "Channel: %s/%d\r\n"
6058 "Status: disabled\r\n", dahdi_chan_name
, p
->channel
);
6059 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6062 memset(exten
, 0, sizeof(exten
));
6064 } else if (p
->cancallforward
&& !strcmp(exten
, "*72")) {
6065 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6067 memset(exten
, 0, sizeof(exten
));
6069 } else if (p
->cancallforward
&& !strcmp(exten
, "*73")) {
6070 if (option_verbose
> 2)
6071 ast_verbose(VERBOSE_PREFIX_3
"Cancelling call forwarding on channel %d\n", p
->channel
);
6072 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6073 memset(p
->call_forward
, 0, sizeof(p
->call_forward
));
6075 memset(exten
, 0, sizeof(exten
));
6077 } else if ((p
->transfer
|| p
->canpark
) && !strcmp(exten
, ast_parking_ext()) &&
6078 p
->subs
[SUB_THREEWAY
].owner
&&
6079 ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
)) {
6080 /* This is a three way call, the main call being a real channel,
6081 and we're parking the first call. */
6082 ast_masq_park_call(ast_bridged_channel(p
->subs
[SUB_THREEWAY
].owner
), chan
, 0, NULL
);
6083 if (option_verbose
> 2)
6084 ast_verbose(VERBOSE_PREFIX_3
"Parking call to '%s'\n", chan
->name
);
6086 } else if (!ast_strlen_zero(p
->lastcid_num
) && !strcmp(exten
, "*60")) {
6087 if (option_verbose
> 2)
6088 ast_verbose(VERBOSE_PREFIX_3
"Blacklisting number %s\n", p
->lastcid_num
);
6089 res
= ast_db_put("blacklist", p
->lastcid_num
, "1");
6091 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6092 memset(exten
, 0, sizeof(exten
));
6095 } else if (p
->hidecallerid
&& !strcmp(exten
, "*82")) {
6096 if (option_verbose
> 2)
6097 ast_verbose(VERBOSE_PREFIX_3
"Enabling Caller*ID on %s\n", chan
->name
);
6098 /* Enable Caller*ID if enabled */
6099 p
->hidecallerid
= 0;
6100 if (chan
->cid
.cid_num
)
6101 free(chan
->cid
.cid_num
);
6102 chan
->cid
.cid_num
= NULL
;
6103 if (chan
->cid
.cid_name
)
6104 free(chan
->cid
.cid_name
);
6105 chan
->cid
.cid_name
= NULL
;
6106 ast_set_callerid(chan
, p
->cid_num
, p
->cid_name
, NULL
);
6107 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_DIALRECALL
);
6109 ast_log(LOG_WARNING
, "Unable to do dial recall on channel %s: %s\n",
6110 chan
->name
, strerror(errno
));
6113 memset(exten
, 0, sizeof(exten
));
6114 timeout
= firstdigittimeout
;
6115 } else if (!strcmp(exten
, "*0")) {
6116 struct ast_channel
*nbridge
=
6117 p
->subs
[SUB_THREEWAY
].owner
;
6118 struct dahdi_pvt
*pbridge
= NULL
;
6119 /* set up the private struct of the bridged one, if any */
6120 if (nbridge
&& ast_bridged_channel(nbridge
))
6121 pbridge
= ast_bridged_channel(nbridge
)->tech_pvt
;
6122 if (nbridge
&& pbridge
&&
6123 (nbridge
->tech
== chan_tech
) &&
6124 (ast_bridged_channel(nbridge
)->tech
== chan_tech
) &&
6126 int func
= DAHDI_FLASH
;
6127 /* Clear out the dial buffer */
6128 p
->dop
.dialstr
[0] = '\0';
6129 /* flash hookswitch */
6130 if ((ioctl(pbridge
->subs
[SUB_REAL
].dfd
,DAHDI_HOOK
,&func
) == -1) && (errno
!= EINPROGRESS
)) {
6131 ast_log(LOG_WARNING
, "Unable to flash external trunk on channel %s: %s\n",
6132 nbridge
->name
, strerror(errno
));
6134 swap_subs(p
, SUB_REAL
, SUB_THREEWAY
);
6135 unalloc_sub(p
, SUB_THREEWAY
);
6136 p
->owner
= p
->subs
[SUB_REAL
].owner
;
6137 if (ast_bridged_channel(p
->subs
[SUB_REAL
].owner
))
6138 ast_queue_control(p
->subs
[SUB_REAL
].owner
, AST_CONTROL_UNHOLD
);
6142 tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
6143 dahdi_wait_event(p
->subs
[index
].dfd
);
6144 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
6145 swap_subs(p
, SUB_REAL
, SUB_THREEWAY
);
6146 unalloc_sub(p
, SUB_THREEWAY
);
6147 p
->owner
= p
->subs
[SUB_REAL
].owner
;
6151 } else if (!ast_canmatch_extension(chan
, chan
->context
, exten
, 1, chan
->cid
.cid_num
) &&
6152 ((exten
[0] != '*') || (strlen(exten
) > 2))) {
6154 ast_log(LOG_DEBUG
, "Can't match %s from '%s' in context %s\n", exten
, chan
->cid
.cid_num
? chan
->cid
.cid_num
: "<Unknown Caller>", chan
->context
);
6158 timeout
= gendigittimeout
;
6159 if (len
&& !ast_ignore_pattern(chan
->context
, exten
))
6160 tone_zone_play_tone(p
->subs
[index
].dfd
, -1);
6168 /* This is a GR-303 trunk actually. Wait for the first ring... */
6169 struct ast_frame
*f
;
6174 ast_setstate(chan
, AST_STATE_RING
);
6175 while (time(NULL
) < start
+ 3) {
6176 res
= ast_waitfor(chan
, 1000);
6180 ast_log(LOG_WARNING
, "Whoa, hangup while waiting for first ring!\n");
6183 } else if ((f
->frametype
== AST_FRAME_CONTROL
) && (f
->subclass
== AST_CONTROL_RING
)) {
6189 ast_log(LOG_DEBUG
, "Got ring!\n");
6197 /* check for SMDI messages */
6198 if (p
->use_smdi
&& p
->smdi_iface
) {
6199 smdi_msg
= ast_smdi_md_message_wait(p
->smdi_iface
, SMDI_MD_WAIT_TIMEOUT
);
6201 if (smdi_msg
!= NULL
) {
6202 ast_copy_string(chan
->exten
, smdi_msg
->fwd_st
, sizeof(chan
->exten
));
6204 if (smdi_msg
->type
== 'B')
6205 pbx_builtin_setvar_helper(chan
, "_SMDI_VM_TYPE", "b");
6206 else if (smdi_msg
->type
== 'N')
6207 pbx_builtin_setvar_helper(chan
, "_SMDI_VM_TYPE", "u");
6209 ast_log(LOG_DEBUG
, "Recieved SMDI message on %s\n", chan
->name
);
6211 ast_log(LOG_WARNING
, "SMDI enabled but no SMDI message present\n");
6215 if (p
->use_callerid
&& (p
->cid_signalling
== CID_SIG_SMDI
&& smdi_msg
)) {
6216 number
= smdi_msg
->calling_st
;
6218 /* If we want caller id, we're in a prering state due to a polarity reversal
6219 * and we're set to use a polarity reversal to trigger the start of caller id,
6220 * grab the caller id and wait for ringing to start... */
6221 } else if (p
->use_callerid
&& (chan
->_state
== AST_STATE_PRERING
&& p
->cid_start
== CID_START_POLARITY
)) {
6222 /* If set to use DTMF CID signalling, listen for DTMF */
6223 if (p
->cid_signalling
== CID_SIG_DTMF
) {
6226 ast_log(LOG_DEBUG
, "Receiving DTMF cid on "
6227 "channel %s\n", chan
->name
);
6228 dahdi_setlinear(p
->subs
[index
].dfd
, 0);
6231 struct ast_frame
*f
;
6232 res
= ast_waitfor(chan
, res
);
6234 ast_log(LOG_WARNING
, "DTMFCID timed out waiting for ring. "
6235 "Exiting simple switch\n");
6242 if (f
->frametype
== AST_FRAME_DTMF
) {
6243 dtmfbuf
[i
++] = f
->subclass
;
6244 ast_log(LOG_DEBUG
, "CID got digit '%c'\n", f
->subclass
);
6248 if (chan
->_state
== AST_STATE_RING
||
6249 chan
->_state
== AST_STATE_RINGING
)
6250 break; /* Got ring */
6253 dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
6254 /* Got cid and ring. */
6255 ast_log(LOG_DEBUG
, "CID got string '%s'\n", dtmfbuf
);
6256 callerid_get_dtmf(dtmfbuf
, dtmfcid
, &flags
);
6257 ast_log(LOG_DEBUG
, "CID is '%s', flags %d\n",
6259 /* If first byte is NULL, we have no cid */
6260 if (!ast_strlen_zero(dtmfcid
))
6264 /* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
6265 } else if ((p
->cid_signalling
== CID_SIG_V23
) || (p
->cid_signalling
== CID_SIG_V23_JP
)) {
6266 cs
= callerid_new(p
->cid_signalling
);
6272 /* Take out of linear mode for Caller*ID processing */
6273 dahdi_setlinear(p
->subs
[index
].dfd
, 0);
6275 /* First we wait and listen for the Caller*ID */
6277 i
= DAHDI_IOMUX_READ
| DAHDI_IOMUX_SIGEVENT
;
6278 if ((res
= ioctl(p
->subs
[index
].dfd
, DAHDI_IOMUX
, &i
))) {
6279 ast_log(LOG_WARNING
, "I/O MUX failed: %s\n", strerror(errno
));
6284 if (i
& DAHDI_IOMUX_SIGEVENT
) {
6285 res
= dahdi_get_event(p
->subs
[index
].dfd
);
6286 ast_log(LOG_NOTICE
, "Got event %d (%s)...\n", res
, event2str(res
));
6288 if (p
->cid_signalling
== CID_SIG_V23_JP
) {
6289 #ifdef DAHDI_EVENT_RINGBEGIN
6290 if (res
== DAHDI_EVENT_RINGBEGIN
) {
6291 res
= dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
6299 } else if (i
& DAHDI_IOMUX_READ
) {
6300 res
= read(p
->subs
[index
].dfd
, buf
, sizeof(buf
));
6302 if (errno
!= ELAST
) {
6303 ast_log(LOG_WARNING
, "read returned error: %s\n", strerror(errno
));
6312 if (p
->cid_signalling
== CID_SIG_V23_JP
) {
6313 res
= callerid_feed_jp(cs
, buf
, res
, AST_LAW(p
));
6315 res
= callerid_feed(cs
, buf
, res
, AST_LAW(p
));
6319 ast_log(LOG_WARNING
, "CallerID feed failed on channel '%s'\n", chan
->name
);
6323 else if (samples
> (8000 * 10))
6328 callerid_get(cs
, &name
, &number
, &flags
);
6329 ast_log(LOG_NOTICE
, "CallerID number: %s, name: %s, flags=%d\n", number
, name
, flags
);
6332 if (p
->cid_signalling
== CID_SIG_V23_JP
) {
6333 res
= dahdi_set_hook(p
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOK
);
6338 /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
6343 struct ast_frame
*f
;
6344 res
= ast_waitfor(chan
, res
);
6346 ast_log(LOG_WARNING
, "CID timed out waiting for ring. "
6347 "Exiting simple switch\n");
6351 if (!(f
= ast_read(chan
))) {
6352 ast_log(LOG_WARNING
, "Hangup received waiting for ring. Exiting simple switch\n");
6357 if (chan
->_state
== AST_STATE_RING
||
6358 chan
->_state
== AST_STATE_RINGING
)
6359 break; /* Got ring */
6362 /* We must have a ring by now, so, if configured, lets try to listen for
6363 * distinctive ringing */
6364 if (p
->usedistinctiveringdetection
== 1) {
6367 /* Clear the current ring data array so we dont have old data in it. */
6368 for (receivedRingT
= 0; receivedRingT
< (sizeof(curRingData
) / sizeof(curRingData
[0])); receivedRingT
++)
6369 curRingData
[receivedRingT
] = 0;
6373 /* Check to see if context is what it should be, if not set to be. */
6374 if (strcmp(p
->context
,p
->defcontext
) != 0) {
6375 ast_copy_string(p
->context
, p
->defcontext
, sizeof(p
->context
));
6376 ast_copy_string(chan
->context
,p
->defcontext
,sizeof(chan
->context
));
6380 i
= DAHDI_IOMUX_READ
| DAHDI_IOMUX_SIGEVENT
;
6381 if ((res
= ioctl(p
->subs
[index
].dfd
, DAHDI_IOMUX
, &i
))) {
6382 ast_log(LOG_WARNING
, "I/O MUX failed: %s\n", strerror(errno
));
6387 if (i
& DAHDI_IOMUX_SIGEVENT
) {
6388 res
= dahdi_get_event(p
->subs
[index
].dfd
);
6389 ast_log(LOG_NOTICE
, "Got event %d (%s)...\n", res
, event2str(res
));
6391 /* Let us detect distinctive ring */
6393 curRingData
[receivedRingT
] = p
->ringt
;
6395 if (p
->ringt
< p
->ringt_base
/2)
6397 /* Increment the ringT counter so we can match it against
6398 values in chan_dahdi.conf for distinctive ring */
6399 if (++receivedRingT
== (sizeof(curRingData
) / sizeof(curRingData
[0])))
6401 } else if (i
& DAHDI_IOMUX_READ
) {
6402 res
= read(p
->subs
[index
].dfd
, buf
, sizeof(buf
));
6404 if (errno
!= ELAST
) {
6405 ast_log(LOG_WARNING
, "read returned error: %s\n", strerror(errno
));
6414 if (p
->ringt
== 1) {
6420 if (option_verbose
> 2)
6421 /* this only shows up if you have n of the dring patterns filled in */
6422 ast_verbose( VERBOSE_PREFIX_3
"Detected ring pattern: %d,%d,%d\n",curRingData
[0],curRingData
[1],curRingData
[2]);
6424 for (counter
= 0; counter
< 3; counter
++) {
6425 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
6428 for (counter1
= 0; counter1
< 3; counter1
++) {
6429 if (curRingData
[counter1
] <= (p
->drings
.ringnum
[counter
].ring
[counter1
]+10) && curRingData
[counter1
] >=
6430 (p
->drings
.ringnum
[counter
].ring
[counter1
]-10)) {
6434 if (distMatches
== 3) {
6435 /* The ring matches, set the context to whatever is for distinctive ring.. */
6436 ast_copy_string(p
->context
, p
->drings
.ringContext
[counter
].contextData
, sizeof(p
->context
));
6437 ast_copy_string(chan
->context
, p
->drings
.ringContext
[counter
].contextData
, sizeof(chan
->context
));
6438 if (option_verbose
> 2)
6439 ast_verbose( VERBOSE_PREFIX_3
"Distinctive Ring matched context %s\n",p
->context
);
6444 /* Restore linear mode (if appropriate) for Caller*ID processing */
6445 dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
6450 ast_log(LOG_WARNING
, "Unable to get caller ID space\n");
6452 ast_log(LOG_WARNING
, "Channel %s in prering "
6453 "state, but I have nothing to do. "
6454 "Terminating simple switch, should be "
6455 "restarted by the actual ring.\n",
6460 } else if (p
->use_callerid
&& p
->cid_start
== CID_START_RING
) {
6461 /* FSK Bell202 callerID */
6462 cs
= callerid_new(p
->cid_signalling
);
6470 /* Clear the current ring data array so we dont have old data in it. */
6471 for (receivedRingT
= 0; receivedRingT
< (sizeof(curRingData
) / sizeof(curRingData
[0])); receivedRingT
++)
6472 curRingData
[receivedRingT
] = 0;
6476 /* Check to see if context is what it should be, if not set to be. */
6477 if (strcmp(p
->context
,p
->defcontext
) != 0) {
6478 ast_copy_string(p
->context
, p
->defcontext
, sizeof(p
->context
));
6479 ast_copy_string(chan
->context
,p
->defcontext
,sizeof(chan
->context
));
6482 /* Take out of linear mode for Caller*ID processing */
6483 dahdi_setlinear(p
->subs
[index
].dfd
, 0);
6485 i
= DAHDI_IOMUX_READ
| DAHDI_IOMUX_SIGEVENT
;
6486 if ((res
= ioctl(p
->subs
[index
].dfd
, DAHDI_IOMUX
, &i
))) {
6487 ast_log(LOG_WARNING
, "I/O MUX failed: %s\n", strerror(errno
));
6492 if (i
& DAHDI_IOMUX_SIGEVENT
) {
6493 res
= dahdi_get_event(p
->subs
[index
].dfd
);
6494 ast_log(LOG_NOTICE
, "Got event %d (%s)...\n", res
, event2str(res
));
6495 /* If we get a PR event, they hung up while processing calerid */
6496 if ( res
== DAHDI_EVENT_POLARITY
&& p
->hanguponpolarityswitch
&& p
->polarity
== POLARITY_REV
) {
6497 ast_log(LOG_DEBUG
, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p
->channel
);
6498 p
->polarity
= POLARITY_IDLE
;
6504 /* Let us detect callerid when the telco uses distinctive ring */
6506 curRingData
[receivedRingT
] = p
->ringt
;
6508 if (p
->ringt
< p
->ringt_base
/2)
6510 /* Increment the ringT counter so we can match it against
6511 values in chan_dahdi.conf for distinctive ring */
6512 if (++receivedRingT
== (sizeof(curRingData
) / sizeof(curRingData
[0])))
6514 } else if (i
& DAHDI_IOMUX_READ
) {
6515 res
= read(p
->subs
[index
].dfd
, buf
, sizeof(buf
));
6517 if (errno
!= ELAST
) {
6518 ast_log(LOG_WARNING
, "read returned error: %s\n", strerror(errno
));
6527 if (p
->ringt
== 1) {
6532 res
= callerid_feed(cs
, buf
, res
, AST_LAW(p
));
6534 ast_log(LOG_WARNING
, "CallerID feed failed: %s\n", strerror(errno
));
6538 else if (samples
> (8000 * 10))
6543 callerid_get(cs
, &name
, &number
, &flags
);
6545 ast_log(LOG_DEBUG
, "CallerID number: %s, name: %s, flags=%d\n", number
, name
, flags
);
6547 if (distinctiveringaftercid
== 1) {
6548 /* Clear the current ring data array so we dont have old data in it. */
6549 for (receivedRingT
= 0; receivedRingT
< 3; receivedRingT
++) {
6550 curRingData
[receivedRingT
] = 0;
6553 if (option_verbose
> 2)
6554 ast_verbose( VERBOSE_PREFIX_3
"Detecting post-CID distinctive ring\n");
6556 i
= DAHDI_IOMUX_READ
| DAHDI_IOMUX_SIGEVENT
;
6557 if ((res
= ioctl(p
->subs
[index
].dfd
, DAHDI_IOMUX
, &i
))) {
6558 ast_log(LOG_WARNING
, "I/O MUX failed: %s\n", strerror(errno
));
6563 if (i
& DAHDI_IOMUX_SIGEVENT
) {
6564 res
= dahdi_get_event(p
->subs
[index
].dfd
);
6565 ast_log(LOG_NOTICE
, "Got event %d (%s)...\n", res
, event2str(res
));
6567 /* Let us detect callerid when the telco uses distinctive ring */
6569 curRingData
[receivedRingT
] = p
->ringt
;
6571 if (p
->ringt
< p
->ringt_base
/2)
6573 /* Increment the ringT counter so we can match it against
6574 values in chan_dahdi.conf for distinctive ring */
6575 if (++receivedRingT
== (sizeof(curRingData
) / sizeof(curRingData
[0])))
6577 } else if (i
& DAHDI_IOMUX_READ
) {
6578 res
= read(p
->subs
[index
].dfd
, buf
, sizeof(buf
));
6580 if (errno
!= ELAST
) {
6581 ast_log(LOG_WARNING
, "read returned error: %s\n", strerror(errno
));
6590 if (p
->ringt
== 1) {
6597 if (p
->usedistinctiveringdetection
== 1) {
6598 if (option_verbose
> 2)
6599 /* this only shows up if you have n of the dring patterns filled in */
6600 ast_verbose( VERBOSE_PREFIX_3
"Detected ring pattern: %d,%d,%d\n",curRingData
[0],curRingData
[1],curRingData
[2]);
6602 for (counter
= 0; counter
< 3; counter
++) {
6603 /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this
6605 if (option_verbose
> 2)
6606 /* this only shows up if you have n of the dring patterns filled in */
6607 ast_verbose( VERBOSE_PREFIX_3
"Checking %d,%d,%d\n",
6608 p
->drings
.ringnum
[counter
].ring
[0],
6609 p
->drings
.ringnum
[counter
].ring
[1],
6610 p
->drings
.ringnum
[counter
].ring
[2]);
6612 for (counter1
= 0; counter1
< 3; counter1
++) {
6613 if (curRingData
[counter1
] <= (p
->drings
.ringnum
[counter
].ring
[counter1
]+10) && curRingData
[counter1
] >=
6614 (p
->drings
.ringnum
[counter
].ring
[counter1
]-10)) {
6618 if (distMatches
== 3) {
6619 /* The ring matches, set the context to whatever is for distinctive ring.. */
6620 ast_copy_string(p
->context
, p
->drings
.ringContext
[counter
].contextData
, sizeof(p
->context
));
6621 ast_copy_string(chan
->context
, p
->drings
.ringContext
[counter
].contextData
, sizeof(chan
->context
));
6622 if (option_verbose
> 2)
6623 ast_verbose( VERBOSE_PREFIX_3
"Distinctive Ring matched context %s\n",p
->context
);
6628 /* Restore linear mode (if appropriate) for Caller*ID processing */
6629 dahdi_setlinear(p
->subs
[index
].dfd
, p
->subs
[index
].linear
);
6634 ast_log(LOG_WARNING
, "CallerID returned with error on channel '%s'\n", chan
->name
);
6637 ast_log(LOG_WARNING
, "Unable to get caller ID space\n");
6643 ast_shrink_phone_number(number
);
6644 ast_set_callerid(chan
, number
, name
, number
);
6647 ASTOBJ_UNREF(smdi_msg
, ast_smdi_md_message_destroy
);
6652 ast_setstate(chan
, AST_STATE_RING
);
6654 p
->ringt
= p
->ringt_base
;
6655 res
= ast_pbx_run(chan
);
6658 ast_log(LOG_WARNING
, "PBX exited non-zero\n");
6662 ast_log(LOG_WARNING
, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p
->sig
), p
->channel
);
6663 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
6665 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", p
->channel
);
6667 res
= tone_zone_play_tone(p
->subs
[index
].dfd
, DAHDI_TONE_CONGESTION
);
6669 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", p
->channel
);
6672 ast_mutex_lock(&ss_thread_lock
);
6674 ast_cond_signal(&ss_thread_complete
);
6675 ast_mutex_unlock(&ss_thread_lock
);
6679 /* destroy a DAHDI channel, identified by its number */
6680 static int dahdi_destroy_channel_bynum(int channel
)
6682 struct dahdi_pvt
*tmp
= NULL
;
6683 struct dahdi_pvt
*prev
= NULL
;
6687 if (tmp
->channel
== channel
) {
6688 int x
= DAHDI_FLASH
;
6689 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 */
6690 destroy_channel(prev
, tmp
, 1);
6691 return RESULT_SUCCESS
;
6696 return RESULT_FAILURE
;
6699 static int handle_init_event(struct dahdi_pvt
*i
, int event
)
6703 pthread_attr_t attr
;
6704 struct ast_channel
*chan
;
6705 pthread_attr_init(&attr
);
6706 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
6707 /* Handle an event on a given channel for the monitor thread. */
6709 case DAHDI_EVENT_NONE
:
6710 case DAHDI_EVENT_BITSCHANGED
:
6712 case DAHDI_EVENT_WINKFLASH
:
6713 case DAHDI_EVENT_RINGOFFHOOK
:
6714 if (i
->inalarm
) break;
6715 if (i
->radio
) break;
6716 /* Got a ring/answer. What kind of channel are we? */
6721 res
= dahdi_set_hook(i
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
6722 if (res
&& (errno
== EBUSY
))
6725 /* Cancel VMWI spill */
6731 /* The channel is immediately up. Start right away */
6732 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_RINGTONE
);
6733 chan
= dahdi_new(i
, AST_STATE_RING
, 1, SUB_REAL
, 0, 0);
6735 ast_log(LOG_WARNING
, "Unable to start PBX on channel %d\n", i
->channel
);
6736 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
6738 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", i
->channel
);
6741 /* Check for callerid, digits, etc */
6742 chan
= dahdi_new(i
, AST_STATE_RESERVED
, 0, SUB_REAL
, 0, 0);
6744 if (has_voicemail(i
))
6745 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_STUTTER
);
6747 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_DIALTONE
);
6749 ast_log(LOG_WARNING
, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i
->channel
);
6750 if (ast_pthread_create(&threadid
, &attr
, ss_thread
, chan
)) {
6751 ast_log(LOG_WARNING
, "Unable to start simple switch thread on channel %d\n", i
->channel
);
6752 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
6754 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", i
->channel
);
6758 ast_log(LOG_WARNING
, "Unable to create channel\n");
6764 i
->ringt
= i
->ringt_base
;
6769 case SIG_FEATDMF_TA
:
6772 case SIG_FGC_CAMAMF
:
6778 case SIG_SF_FEATDMF
:
6781 /* Check for callerid, digits, etc */
6782 chan
= dahdi_new(i
, AST_STATE_RING
, 0, SUB_REAL
, 0, 0);
6783 if (chan
&& ast_pthread_create(&threadid
, &attr
, ss_thread
, chan
)) {
6784 ast_log(LOG_WARNING
, "Unable to start simple switch thread on channel %d\n", i
->channel
);
6785 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
6787 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", i
->channel
);
6790 ast_log(LOG_WARNING
, "Cannot allocate new structure on channel %d\n", i
->channel
);
6794 ast_log(LOG_WARNING
, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i
->sig
), i
->channel
);
6795 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, DAHDI_TONE_CONGESTION
);
6797 ast_log(LOG_WARNING
, "Unable to play congestion tone on channel %d\n", i
->channel
);
6801 case DAHDI_EVENT_NOALARM
:
6803 if (!i
->unknown_alarm
) {
6804 ast_log(LOG_NOTICE
, "Alarm cleared on channel %d\n", i
->channel
);
6805 manager_event(EVENT_FLAG_SYSTEM
, "AlarmClear",
6806 "Channel: %d\r\n", i
->channel
);
6808 i
->unknown_alarm
= 0;
6811 case DAHDI_EVENT_ALARM
:
6813 res
= get_alarms(i
);
6814 handle_alarms(i
, res
);
6815 /* fall thru intentionally */
6816 case DAHDI_EVENT_ONHOOK
:
6819 /* Back on hook. Hang up. */
6825 case SIG_FEATDMF_TA
:
6828 case SIG_FGC_CAMAMF
:
6834 case SIG_SF_FEATDMF
:
6841 case SIG_GR303FXSKS
:
6842 dahdi_disable_ec(i
);
6843 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, -1);
6844 dahdi_set_hook(i
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOK
);
6846 case SIG_GR303FXOKS
:
6848 dahdi_disable_ec(i
);
6849 /* Diddle the battery for the zhone */
6851 dahdi_set_hook(i
->subs
[SUB_REAL
].dfd
, DAHDI_OFFHOOK
);
6854 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, -1);
6855 dahdi_set_hook(i
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOK
);
6858 dahdi_disable_ec(i
);
6859 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, -1);
6862 ast_log(LOG_WARNING
, "Don't know how to handle on hook with signalling %s on channel %d\n", sig2str(i
->sig
), i
->channel
);
6863 res
= tone_zone_play_tone(i
->subs
[SUB_REAL
].dfd
, -1);
6867 case DAHDI_EVENT_POLARITY
:
6872 /* We have already got a PR before the channel was
6873 created, but it wasn't handled. We need polarity
6874 to be REV for remote hangup detection to work.
6875 At least in Spain */
6876 if (i
->hanguponpolarityswitch
)
6877 i
->polarity
= POLARITY_REV
;
6879 if (i
->cid_start
== CID_START_POLARITY
) {
6880 i
->polarity
= POLARITY_REV
;
6881 ast_verbose(VERBOSE_PREFIX_2
"Starting post polarity "
6882 "CID detection on channel %d\n",
6884 chan
= dahdi_new(i
, AST_STATE_PRERING
, 0, SUB_REAL
, 0, 0);
6885 if (chan
&& ast_pthread_create(&threadid
, &attr
, ss_thread
, chan
)) {
6886 ast_log(LOG_WARNING
, "Unable to start simple switch thread on channel %d\n", i
->channel
);
6891 ast_log(LOG_WARNING
, "handle_init_event detected "
6892 "polarity reversal on non-FXO (SIG_FXS) "
6893 "interface %d\n", i
->channel
);
6896 case DAHDI_EVENT_REMOVED
: /* destroy channel */
6898 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
6900 dahdi_destroy_channel_bynum(i
->channel
);
6903 pthread_attr_destroy(&attr
);
6907 static void *do_monitor(void *data
)
6909 int count
, res
, res2
, spoint
, pollres
=0;
6910 struct dahdi_pvt
*i
;
6911 struct dahdi_pvt
*last
= NULL
;
6912 time_t thispass
= 0, lastpass
= 0;
6915 struct pollfd
*pfds
=NULL
;
6917 /* This thread monitors all the frame relay interfaces which are not yet in use
6918 (and thus do not have a separate thread) indefinitely */
6919 /* From here on out, we die whenever asked */
6921 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
)) {
6922 ast_log(LOG_WARNING
, "Unable to set cancel type to asynchronous\n");
6925 ast_log(LOG_DEBUG
, "Monitor starting...\n");
6927 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
6930 /* Lock the interface list */
6931 ast_mutex_lock(&iflock
);
6932 if (!pfds
|| (lastalloc
!= ifcount
)) {
6938 if (!(pfds
= ast_calloc(1, ifcount
* sizeof(*pfds
)))) {
6939 ast_mutex_unlock(&iflock
);
6943 lastalloc
= ifcount
;
6945 /* Build the stuff we're going to poll on, that is the socket of every
6946 dahdi_pvt that does not have an associated owner channel */
6950 if ((i
->subs
[SUB_REAL
].dfd
> -1) && i
->sig
&& (!i
->radio
)) {
6951 if (!i
->owner
&& !i
->subs
[SUB_REAL
].owner
) {
6952 /* This needs to be watched, as it lacks an owner */
6953 pfds
[count
].fd
= i
->subs
[SUB_REAL
].dfd
;
6954 pfds
[count
].events
= POLLPRI
;
6955 pfds
[count
].revents
= 0;
6956 /* Message waiting or r2 channels also get watched for reading */
6958 pfds
[count
].events
|= POLLIN
;
6964 /* Okay, now that we know what to do, release the interface lock */
6965 ast_mutex_unlock(&iflock
);
6967 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
);
6968 pthread_testcancel();
6969 /* Wait at least a second for something to happen */
6970 res
= poll(pfds
, count
, 1000);
6971 pthread_testcancel();
6972 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
6974 /* Okay, poll has finished. Let's see what happened. */
6976 if ((errno
!= EAGAIN
) && (errno
!= EINTR
))
6977 ast_log(LOG_WARNING
, "poll return %d: %s\n", res
, strerror(errno
));
6980 /* Alright, lock the interface list again, and let's look and see what has
6982 ast_mutex_lock(&iflock
);
6985 lastpass
= thispass
;
6986 thispass
= time(NULL
);
6989 if (thispass
!= lastpass
) {
6990 if (!found
&& ((i
== last
) || ((i
== iflist
) && !last
))) {
6993 if (!last
->cidspill
&& !last
->owner
&& !ast_strlen_zero(last
->mailbox
) && (thispass
- last
->onhooktime
> 3) &&
6994 (last
->sig
& __DAHDI_SIG_FXO
)) {
6995 res
= ast_app_has_voicemail(last
->mailbox
, NULL
);
6996 if (last
->msgstate
!= res
) {
6998 ast_log(LOG_DEBUG
, "Message status for %s changed from %d to %d on %d\n", last
->mailbox
, last
->msgstate
, res
, last
->channel
);
6999 x
= DAHDI_FLUSH_BOTH
;
7000 res2
= ioctl(last
->subs
[SUB_REAL
].dfd
, DAHDI_FLUSH
, &x
);
7002 ast_log(LOG_WARNING
, "Unable to flush input on channel %d: %s\n", last
->channel
, strerror(errno
));
7003 if ((last
->cidspill
= ast_calloc(1, MAX_CALLERID_SIZE
))) {
7004 /* Turn on on hook transfer for 4 seconds */
7006 ioctl(last
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOKTRANSFER
, &x
);
7007 last
->cidlen
= vmwi_generate(last
->cidspill
, res
, 1, AST_LAW(last
));
7009 last
->msgstate
= res
;
7010 last
->onhooktime
= thispass
;
7019 if ((i
->subs
[SUB_REAL
].dfd
> -1) && i
->sig
) {
7020 if (i
->radio
&& !i
->owner
)
7022 res
= dahdi_get_event(i
->subs
[SUB_REAL
].dfd
);
7026 ast_log(LOG_DEBUG
, "Monitor doohicky got event %s on radio channel %d\n", event2str(res
), i
->channel
);
7027 /* Don't hold iflock while handling init events */
7028 ast_mutex_unlock(&iflock
);
7029 handle_init_event(i
, res
);
7030 ast_mutex_lock(&iflock
);
7035 pollres
= ast_fdisset(pfds
, i
->subs
[SUB_REAL
].dfd
, count
, &spoint
);
7036 if (pollres
& POLLIN
) {
7037 if (i
->owner
|| i
->subs
[SUB_REAL
].owner
) {
7041 ast_log(LOG_WARNING
, "Whoa.... I'm owned but found (%d) in read...\n", i
->subs
[SUB_REAL
].dfd
);
7046 ast_log(LOG_WARNING
, "Whoa.... I'm reading but have no cidspill (%d)...\n", i
->subs
[SUB_REAL
].dfd
);
7050 res
= read(i
->subs
[SUB_REAL
].dfd
, buf
, sizeof(buf
));
7052 /* We read some number of bytes. Write an equal amount of data */
7053 if (res
> i
->cidlen
- i
->cidpos
)
7054 res
= i
->cidlen
- i
->cidpos
;
7055 res2
= write(i
->subs
[SUB_REAL
].dfd
, i
->cidspill
+ i
->cidpos
, res
);
7058 if (i
->cidpos
>= i
->cidlen
) {
7065 ast_log(LOG_WARNING
, "Write failed: %s\n", strerror(errno
));
7069 ast_log(LOG_WARNING
, "Read failed with %d: %s\n", res
, strerror(errno
));
7072 if (pollres
& POLLPRI
) {
7073 if (i
->owner
|| i
->subs
[SUB_REAL
].owner
) {
7077 ast_log(LOG_WARNING
, "Whoa.... I'm owned but found (%d)...\n", i
->subs
[SUB_REAL
].dfd
);
7081 res
= dahdi_get_event(i
->subs
[SUB_REAL
].dfd
);
7083 ast_log(LOG_DEBUG
, "Monitor doohicky got event %s on channel %d\n", event2str(res
), i
->channel
);
7084 /* Don't hold iflock while handling init events */
7085 ast_mutex_unlock(&iflock
);
7086 handle_init_event(i
, res
);
7087 ast_mutex_lock(&iflock
);
7092 ast_mutex_unlock(&iflock
);
7099 static int restart_monitor(void)
7101 pthread_attr_t attr
;
7102 pthread_attr_init(&attr
);
7103 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
7104 /* If we're supposed to be stopped -- stay stopped */
7105 if (monitor_thread
== AST_PTHREADT_STOP
)
7107 ast_mutex_lock(&monlock
);
7108 if (monitor_thread
== pthread_self()) {
7109 ast_mutex_unlock(&monlock
);
7110 ast_log(LOG_WARNING
, "Cannot kill myself\n");
7113 if (monitor_thread
!= AST_PTHREADT_NULL
) {
7114 /* Wake up the thread */
7115 pthread_kill(monitor_thread
, SIGURG
);
7117 /* Start a new monitor */
7118 if (ast_pthread_create_background(&monitor_thread
, &attr
, do_monitor
, NULL
) < 0) {
7119 ast_mutex_unlock(&monlock
);
7120 ast_log(LOG_ERROR
, "Unable to start monitor thread.\n");
7121 pthread_attr_destroy(&attr
);
7125 ast_mutex_unlock(&monlock
);
7126 pthread_attr_destroy(&attr
);
7131 static int pri_resolve_span(int *span
, int channel
, int offset
, struct dahdi_spaninfo
*si
)
7135 /* Get appropriate trunk group if there is one */
7136 trunkgroup
= pris
[*span
].mastertrunkgroup
;
7138 /* Select a specific trunk group */
7139 for (x
= 0; x
< NUM_SPANS
; x
++) {
7140 if (pris
[x
].trunkgroup
== trunkgroup
) {
7145 ast_log(LOG_WARNING
, "Channel %d on span %d configured to use nonexistent trunk group %d\n", channel
, *span
, trunkgroup
);
7148 if (pris
[*span
].trunkgroup
) {
7149 ast_log(LOG_WARNING
, "Unable to use span %d implicitly since it is trunk group %d (please use spanmap)\n", *span
, pris
[*span
].trunkgroup
);
7151 } else if (pris
[*span
].mastertrunkgroup
) {
7152 ast_log(LOG_WARNING
, "Unable to use span %d implicitly since it is already part of trunk group %d\n", *span
, pris
[*span
].mastertrunkgroup
);
7155 if (si
->totalchans
== 31) {
7157 pris
[*span
].dchannels
[0] = 16 + offset
;
7158 } else if (si
->totalchans
== 24) {
7160 pris
[*span
].dchannels
[0] = 24 + offset
;
7161 } else if (si
->totalchans
== 3) {
7163 pris
[*span
].dchannels
[0] = 3 + offset
;
7165 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
);
7169 pris
[*span
].dchanavail
[0] |= DCHAN_PROVISIONED
;
7170 pris
[*span
].offset
= offset
;
7171 pris
[*span
].span
= *span
+ 1;
7177 static int pri_create_trunkgroup(int trunkgroup
, int *channels
)
7179 struct dahdi_spaninfo si
;
7180 struct dahdi_params p
;
7185 for (x
= 0; x
< NUM_SPANS
; x
++) {
7186 if (pris
[x
].trunkgroup
== trunkgroup
) {
7187 ast_log(LOG_WARNING
, "Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup
, x
+ 1, pris
[x
].dchannels
[0]);
7191 for (y
= 0; y
< NUM_DCHANS
; y
++) {
7194 memset(&si
, 0, sizeof(si
));
7195 memset(&p
, 0, sizeof(p
));
7197 fd
= open("/dev/zap/channel", O_RDWR
);
7199 fd
= open("/dev/dahdi/channel", O_RDWR
);
7202 ast_log(LOG_WARNING
, "Failed to open channel: %s\n", strerror(errno
));
7206 if (ioctl(fd
, DAHDI_SPECIFY
, &x
)) {
7207 ast_log(LOG_WARNING
, "Failed to specify channel %d: %s\n", channels
[y
], strerror(errno
));
7211 if (ioctl(fd
, DAHDI_GET_PARAMS
, &p
)) {
7212 ast_log(LOG_WARNING
, "Failed to get channel parameters for channel %d: %s\n", channels
[y
], strerror(errno
));
7215 if (ioctl(fd
, DAHDI_SPANSTAT
, &si
)) {
7216 ast_log(LOG_WARNING
, "Failed go get span information on channel %d (span %d): %s\n", channels
[y
], p
.spanno
, strerror(errno
));
7220 span
= p
.spanno
- 1;
7221 if (pris
[span
].trunkgroup
) {
7222 ast_log(LOG_WARNING
, "Span %d is already provisioned for trunk group %d\n", span
+ 1, pris
[span
].trunkgroup
);
7226 if (pris
[span
].pvts
[0]) {
7227 ast_log(LOG_WARNING
, "Span %d is already provisioned with channels (implicit PRI maybe?)\n", span
+ 1);
7232 pris
[span
].trunkgroup
= trunkgroup
;
7233 pris
[span
].offset
= channels
[y
] - p
.chanpos
;
7236 pris
[ospan
].dchannels
[y
] = channels
[y
];
7237 pris
[ospan
].dchanavail
[y
] |= DCHAN_PROVISIONED
;
7238 pris
[span
].span
= span
+ 1;
7244 static int pri_create_spanmap(int span
, int trunkgroup
, int logicalspan
)
7246 if (pris
[span
].mastertrunkgroup
) {
7247 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
);
7250 pris
[span
].mastertrunkgroup
= trunkgroup
;
7251 pris
[span
].prilogicalspan
= logicalspan
;
7257 static struct dahdi_pvt
*mkintf(int channel
, const struct dahdi_chan_conf
*conf
, struct dahdi_pri
*pri
, int reloading
)
7259 /* Make a dahdi_pvt structure for this interface (or CRV if "pri" is specified) */
7260 struct dahdi_pvt
*tmp
= NULL
, *tmp2
, *prev
= NULL
;
7263 struct dahdi_bufferinfo bi
;
7269 struct dahdi_pvt
**wlist
;
7270 struct dahdi_pvt
**wend
;
7271 struct dahdi_params p
;
7279 wend
= &pri
->crvend
;
7287 if (!tmp2
->destroy
) {
7288 if (tmp2
->channel
== channel
) {
7293 if (tmp2
->channel
> channel
) {
7301 if (!here
&& reloading
!= 1) {
7302 if (!(tmp
= ast_calloc(1, sizeof(*tmp
)))) {
7307 ast_mutex_init(&tmp
->lock
);
7309 for (x
= 0; x
< 3; x
++)
7310 tmp
->subs
[x
].dfd
= -1;
7311 tmp
->channel
= channel
;
7315 int chan_sig
= conf
->chan
.sig
;
7317 if ((channel
!= CHAN_PSEUDO
) && !pri
) {
7318 snprintf(fn
, sizeof(fn
), "%d", channel
);
7319 /* Open non-blocking */
7320 tmp
->subs
[SUB_REAL
].dfd
= dahdi_open(fn
);
7321 while (tmp
->subs
[SUB_REAL
].dfd
< 0 && reloading
== 2) { /* the kernel may not call dahdi_release fast enough for the open flagbit to be cleared in time */
7323 tmp
->subs
[SUB_REAL
].dfd
= dahdi_open(fn
);
7325 /* Allocate a DAHDI structure */
7326 if (tmp
->subs
[SUB_REAL
].dfd
< 0) {
7327 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
);
7328 destroy_dahdi_pvt(&tmp
);
7331 memset(&p
, 0, sizeof(p
));
7332 res
= ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &p
);
7334 ast_log(LOG_ERROR
, "Unable to get parameters: %s\n", strerror(errno
));
7335 destroy_dahdi_pvt(&tmp
);
7338 if (p
.sigtype
!= (conf
->chan
.sig
& 0x3ffff)) {
7339 ast_log(LOG_ERROR
, "Signalling requested on channel %d is %s but line is in %s signalling\n", channel
, sig2str(conf
->chan
.sig
), sig2str(p
.sigtype
));
7340 destroy_dahdi_pvt(&tmp
);
7343 tmp
->law
= p
.curlaw
;
7344 tmp
->span
= p
.spanno
;
7345 span
= p
.spanno
- 1;
7347 if (channel
== CHAN_PSEUDO
)
7349 else if ((chan_sig
!= SIG_FXOKS
) && (chan_sig
!= SIG_FXSKS
)) {
7350 ast_log(LOG_ERROR
, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
7355 if ((chan_sig
== SIG_PRI
) || (chan_sig
== SIG_GR303FXOKS
) || (chan_sig
== SIG_GR303FXSKS
)) {
7361 if ((chan_sig
== SIG_PRI
) && ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_AUDIOMODE
, &offset
)) {
7362 ast_log(LOG_ERROR
, "Unable to set clear mode on clear channel %d of span %d: %s\n", channel
, p
.spanno
, strerror(errno
));
7363 destroy_dahdi_pvt(&tmp
);
7366 if (span
>= NUM_SPANS
) {
7367 ast_log(LOG_ERROR
, "Channel %d does not lie on a span I know of (%d)\n", channel
, span
);
7368 destroy_dahdi_pvt(&tmp
);
7371 struct dahdi_spaninfo si
;
7373 if (ioctl(tmp
->subs
[SUB_REAL
].dfd
,DAHDI_SPANSTAT
,&si
) == -1) {
7374 ast_log(LOG_ERROR
, "Unable to get span status: %s\n", strerror(errno
));
7375 destroy_dahdi_pvt(&tmp
);
7378 /* Store the logical span first based upon the real span */
7379 tmp
->logicalspan
= pris
[span
].prilogicalspan
;
7380 pri_resolve_span(&span
, channel
, (channel
- p
.chanpos
), &si
);
7382 ast_log(LOG_WARNING
, "Channel %d: Unable to find locate channel/trunk group!\n", channel
);
7383 destroy_dahdi_pvt(&tmp
);
7386 if (chan_sig
== SIG_PRI
)
7387 myswitchtype
= conf
->pri
.switchtype
;
7389 myswitchtype
= PRI_SWITCH_GR303_TMC
;
7390 /* Make sure this isn't a d-channel */
7392 for (x
= 0; x
< NUM_SPANS
; x
++) {
7393 for (y
= 0; y
< NUM_DCHANS
; y
++) {
7394 if (pris
[x
].dchannels
[y
] == tmp
->channel
) {
7401 if (!matchesdchan
) {
7402 if (pris
[span
].nodetype
&& (pris
[span
].nodetype
!= conf
->pri
.nodetype
)) {
7403 ast_log(LOG_ERROR
, "Span %d is already a %s node\n", span
+ 1, pri_node2str(pris
[span
].nodetype
));
7404 destroy_dahdi_pvt(&tmp
);
7407 if (pris
[span
].switchtype
&& (pris
[span
].switchtype
!= myswitchtype
)) {
7408 ast_log(LOG_ERROR
, "Span %d is already a %s switch\n", span
+ 1, pri_switch2str(pris
[span
].switchtype
));
7409 destroy_dahdi_pvt(&tmp
);
7412 if ((pris
[span
].dialplan
) && (pris
[span
].dialplan
!= conf
->pri
.dialplan
)) {
7413 ast_log(LOG_ERROR
, "Span %d is already a %s dialing plan\n", span
+ 1, dialplan2str(pris
[span
].dialplan
));
7414 destroy_dahdi_pvt(&tmp
);
7417 if (!ast_strlen_zero(pris
[span
].idledial
) && strcmp(pris
[span
].idledial
, conf
->pri
.idledial
)) {
7418 ast_log(LOG_ERROR
, "Span %d already has idledial '%s'.\n", span
+ 1, conf
->pri
.idledial
);
7419 destroy_dahdi_pvt(&tmp
);
7422 if (!ast_strlen_zero(pris
[span
].idleext
) && strcmp(pris
[span
].idleext
, conf
->pri
.idleext
)) {
7423 ast_log(LOG_ERROR
, "Span %d already has idleext '%s'.\n", span
+ 1, conf
->pri
.idleext
);
7424 destroy_dahdi_pvt(&tmp
);
7427 if (pris
[span
].minunused
&& (pris
[span
].minunused
!= conf
->pri
.minunused
)) {
7428 ast_log(LOG_ERROR
, "Span %d already has minunused of %d.\n", span
+ 1, conf
->pri
.minunused
);
7429 destroy_dahdi_pvt(&tmp
);
7432 if (pris
[span
].minidle
&& (pris
[span
].minidle
!= conf
->pri
.minidle
)) {
7433 ast_log(LOG_ERROR
, "Span %d already has minidle of %d.\n", span
+ 1, conf
->pri
.minidle
);
7434 destroy_dahdi_pvt(&tmp
);
7437 if (pris
[span
].numchans
>= MAX_CHANNELS
) {
7438 ast_log(LOG_ERROR
, "Unable to add channel %d: Too many channels in trunk group %d!\n", channel
,
7439 pris
[span
].trunkgroup
);
7440 destroy_dahdi_pvt(&tmp
);
7443 pris
[span
].nodetype
= conf
->pri
.nodetype
;
7444 pris
[span
].switchtype
= myswitchtype
;
7445 pris
[span
].nsf
= conf
->pri
.nsf
;
7446 pris
[span
].dialplan
= conf
->pri
.dialplan
;
7447 pris
[span
].localdialplan
= conf
->pri
.localdialplan
;
7448 pris
[span
].pvts
[pris
[span
].numchans
++] = tmp
;
7449 pris
[span
].minunused
= conf
->pri
.minunused
;
7450 pris
[span
].minidle
= conf
->pri
.minidle
;
7451 pris
[span
].overlapdial
= conf
->pri
.overlapdial
;
7452 #ifdef HAVE_PRI_INBANDDISCONNECT
7453 pris
[span
].inbanddisconnect
= conf
->pri
.inbanddisconnect
;
7455 pris
[span
].facilityenable
= conf
->pri
.facilityenable
;
7456 ast_copy_string(pris
[span
].idledial
, conf
->pri
.idledial
, sizeof(pris
[span
].idledial
));
7457 ast_copy_string(pris
[span
].idleext
, conf
->pri
.idleext
, sizeof(pris
[span
].idleext
));
7458 ast_copy_string(pris
[span
].internationalprefix
, conf
->pri
.internationalprefix
, sizeof(pris
[span
].internationalprefix
));
7459 ast_copy_string(pris
[span
].nationalprefix
, conf
->pri
.nationalprefix
, sizeof(pris
[span
].nationalprefix
));
7460 ast_copy_string(pris
[span
].localprefix
, conf
->pri
.localprefix
, sizeof(pris
[span
].localprefix
));
7461 ast_copy_string(pris
[span
].privateprefix
, conf
->pri
.privateprefix
, sizeof(pris
[span
].privateprefix
));
7462 ast_copy_string(pris
[span
].unknownprefix
, conf
->pri
.unknownprefix
, sizeof(pris
[span
].unknownprefix
));
7463 pris
[span
].resetinterval
= conf
->pri
.resetinterval
;
7465 tmp
->pri
= &pris
[span
];
7466 tmp
->prioffset
= offset
;
7469 ast_log(LOG_ERROR
, "Channel %d is reserved for D-channel.\n", offset
);
7470 destroy_dahdi_pvt(&tmp
);
7479 chan_sig
= tmp
->sig
;
7480 memset(&p
, 0, sizeof(p
));
7481 if (tmp
->subs
[SUB_REAL
].dfd
> -1)
7482 res
= ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &p
);
7484 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
7493 case SIG_FEATDMF_TA
:
7499 case SIG_FGC_CAMAMF
:
7501 case SIG_SF_FEATDMF
:
7508 /* XXX Waiting to hear back from Jim if these should be adjustable XXX */
7517 /* Override timing settings based on config file */
7518 if (conf
->timing
.prewinktime
>= 0)
7519 p
.prewinktime
= conf
->timing
.prewinktime
;
7520 if (conf
->timing
.preflashtime
>= 0)
7521 p
.preflashtime
= conf
->timing
.preflashtime
;
7522 if (conf
->timing
.winktime
>= 0)
7523 p
.winktime
= conf
->timing
.winktime
;
7524 if (conf
->timing
.flashtime
>= 0)
7525 p
.flashtime
= conf
->timing
.flashtime
;
7526 if (conf
->timing
.starttime
>= 0)
7527 p
.starttime
= conf
->timing
.starttime
;
7528 if (conf
->timing
.rxwinktime
>= 0)
7529 p
.rxwinktime
= conf
->timing
.rxwinktime
;
7530 if (conf
->timing
.rxflashtime
>= 0)
7531 p
.rxflashtime
= conf
->timing
.rxflashtime
;
7532 if (conf
->timing
.debouncetime
>= 0)
7533 p
.debouncetime
= conf
->timing
.debouncetime
;
7536 /* dont set parms on a pseudo-channel (or CRV) */
7537 if (tmp
->subs
[SUB_REAL
].dfd
>= 0)
7539 res
= ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_SET_PARAMS
, &p
);
7541 ast_log(LOG_ERROR
, "Unable to set parameters: %s\n", strerror(errno
));
7542 destroy_dahdi_pvt(&tmp
);
7547 if (!here
&& (tmp
->subs
[SUB_REAL
].dfd
> -1)) {
7548 memset(&bi
, 0, sizeof(bi
));
7549 res
= ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GET_BUFINFO
, &bi
);
7551 bi
.txbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
7552 bi
.rxbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
7553 bi
.numbufs
= numbufs
;
7554 res
= ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_SET_BUFINFO
, &bi
);
7556 ast_log(LOG_WARNING
, "Unable to set buffer policy on channel %d: %s\n", channel
, strerror(errno
));
7559 ast_log(LOG_WARNING
, "Unable to check buffer policy on channel %d: %s\n", channel
, strerror(errno
));
7562 tmp
->immediate
= conf
->chan
.immediate
;
7563 tmp
->transfertobusy
= conf
->chan
.transfertobusy
;
7564 tmp
->sig
= chan_sig
;
7565 tmp
->outsigmod
= conf
->chan
.outsigmod
;
7566 tmp
->ringt_base
= ringt_base
;
7567 tmp
->firstradio
= 0;
7568 if ((chan_sig
== SIG_FXOKS
) || (chan_sig
== SIG_FXOLS
) || (chan_sig
== SIG_FXOGS
))
7569 tmp
->permcallwaiting
= conf
->chan
.callwaiting
;
7571 tmp
->permcallwaiting
= 0;
7572 /* Flag to destroy the channel must be cleared on new mkif. Part of changes for reload to work */
7574 tmp
->drings
= drings
;
7575 tmp
->usedistinctiveringdetection
= conf
->chan
.usedistinctiveringdetection
;
7576 tmp
->callwaitingcallerid
= conf
->chan
.callwaitingcallerid
;
7577 tmp
->threewaycalling
= conf
->chan
.threewaycalling
;
7578 tmp
->adsi
= conf
->chan
.adsi
;
7579 tmp
->use_smdi
= conf
->chan
.use_smdi
;
7580 tmp
->permhidecallerid
= conf
->chan
.hidecallerid
;
7581 tmp
->callreturn
= conf
->chan
.callreturn
;
7582 tmp
->echocancel
= conf
->chan
.echocancel
;
7583 tmp
->echotraining
= conf
->chan
.echotraining
;
7584 tmp
->pulse
= conf
->chan
.pulse
;
7585 if (tmp
->echocancel
)
7586 tmp
->echocanbridged
= conf
->chan
.echocanbridged
;
7588 if (conf
->chan
.echocanbridged
)
7589 ast_log(LOG_NOTICE
, "echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
7590 tmp
->echocanbridged
= 0;
7592 tmp
->busydetect
= conf
->chan
.busydetect
;
7593 tmp
->busycount
= conf
->chan
.busycount
;
7594 tmp
->busy_tonelength
= conf
->chan
.busy_tonelength
;
7595 tmp
->busy_quietlength
= conf
->chan
.busy_quietlength
;
7596 tmp
->callprogress
= conf
->chan
.callprogress
;
7597 tmp
->cancallforward
= conf
->chan
.cancallforward
;
7598 tmp
->dtmfrelax
= conf
->chan
.dtmfrelax
;
7599 tmp
->callwaiting
= tmp
->permcallwaiting
;
7600 tmp
->hidecallerid
= tmp
->permhidecallerid
;
7601 tmp
->channel
= channel
;
7602 tmp
->stripmsd
= conf
->chan
.stripmsd
;
7603 tmp
->use_callerid
= conf
->chan
.use_callerid
;
7604 tmp
->cid_signalling
= conf
->chan
.cid_signalling
;
7605 tmp
->cid_start
= conf
->chan
.cid_start
;
7606 tmp
->dahditrcallerid
= conf
->chan
.dahditrcallerid
;
7607 tmp
->restrictcid
= conf
->chan
.restrictcid
;
7608 tmp
->use_callingpres
= conf
->chan
.use_callingpres
;
7609 tmp
->priindication_oob
= conf
->chan
.priindication_oob
;
7610 tmp
->priexclusive
= conf
->chan
.priexclusive
;
7611 if (tmp
->usedistinctiveringdetection
) {
7612 if (!tmp
->use_callerid
) {
7613 ast_log(LOG_NOTICE
, "Distinctive Ring detect requires 'usecallerid' be on\n");
7614 tmp
->use_callerid
= 1;
7618 if (tmp
->cid_signalling
== CID_SIG_SMDI
) {
7619 if (!tmp
->use_smdi
) {
7620 ast_log(LOG_WARNING
, "SMDI callerid requires SMDI to be enabled, enabling...\n");
7624 if (tmp
->use_smdi
) {
7625 tmp
->smdi_iface
= ast_smdi_interface_find(conf
->smdi_port
);
7626 if (!(tmp
->smdi_iface
)) {
7627 ast_log(LOG_ERROR
, "Invalid SMDI port specfied, disabling SMDI support\n");
7632 ast_copy_string(tmp
->accountcode
, conf
->chan
.accountcode
, sizeof(tmp
->accountcode
));
7633 tmp
->amaflags
= conf
->chan
.amaflags
;
7636 tmp
->propconfno
= -1;
7638 tmp
->canpark
= conf
->chan
.canpark
;
7639 tmp
->transfer
= conf
->chan
.transfer
;
7640 ast_copy_string(tmp
->defcontext
,conf
->chan
.context
,sizeof(tmp
->defcontext
));
7641 ast_copy_string(tmp
->language
, conf
->chan
.language
, sizeof(tmp
->language
));
7642 ast_copy_string(tmp
->mohinterpret
, conf
->chan
.mohinterpret
, sizeof(tmp
->mohinterpret
));
7643 ast_copy_string(tmp
->mohsuggest
, conf
->chan
.mohsuggest
, sizeof(tmp
->mohsuggest
));
7644 ast_copy_string(tmp
->context
, conf
->chan
.context
, sizeof(tmp
->context
));
7645 ast_copy_string(tmp
->cid_num
, conf
->chan
.cid_num
, sizeof(tmp
->cid_num
));
7647 ast_copy_string(tmp
->cid_name
, conf
->chan
.cid_name
, sizeof(tmp
->cid_name
));
7648 ast_copy_string(tmp
->mailbox
, conf
->chan
.mailbox
, sizeof(tmp
->mailbox
));
7650 tmp
->group
= conf
->chan
.group
;
7651 tmp
->callgroup
= conf
->chan
.callgroup
;
7652 tmp
->pickupgroup
= conf
->chan
.pickupgroup
;
7653 tmp
->rxgain
= conf
->chan
.rxgain
;
7654 tmp
->txgain
= conf
->chan
.txgain
;
7655 tmp
->tonezone
= conf
->chan
.tonezone
;
7656 tmp
->onhooktime
= time(NULL
);
7657 if (tmp
->subs
[SUB_REAL
].dfd
> -1) {
7658 set_actual_gain(tmp
->subs
[SUB_REAL
].dfd
, 0, tmp
->rxgain
, tmp
->txgain
, tmp
->law
);
7660 ast_dsp_digitmode(tmp
->dsp
, DSP_DIGITMODE_DTMF
| tmp
->dtmfrelax
);
7663 if (chan_sig
!= SIG_PRI
)
7664 /* Hang it up to be sure it's good */
7665 dahdi_set_hook(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_ONHOOK
);
7667 ioctl(tmp
->subs
[SUB_REAL
].dfd
,DAHDI_SETTONEZONE
,&tmp
->tonezone
);
7669 /* the dchannel is down so put the channel in alarm */
7670 if (tmp
->pri
&& !pri_is_up(tmp
->pri
)) {
7674 if ((res
= get_alarms(tmp
)) != DAHDI_ALARM_NONE
) {
7676 handle_alarms(tmp
, res
);
7678 /* yes, this looks strange... the unknown_alarm flag is only used to
7679 control whether an 'alarm cleared' message gets generated when we
7680 get an indication that the channel is no longer in alarm status.
7681 however, the channel *could* be in an alarm status that we aren't
7682 aware of (since get_alarms() only reports span alarms, not channel
7683 alarms). setting this flag will cause any potential 'alarm cleared'
7684 message to be suppressed, but if a real alarm occurs before that
7685 happens, this flag will get cleared by it and the situation will
7688 tmp
->unknown_alarm
= 1;
7692 tmp
->polarityonanswerdelay
= conf
->chan
.polarityonanswerdelay
;
7693 tmp
->answeronpolarityswitch
= conf
->chan
.answeronpolarityswitch
;
7694 tmp
->hanguponpolarityswitch
= conf
->chan
.hanguponpolarityswitch
;
7695 tmp
->sendcalleridafter
= conf
->chan
.sendcalleridafter
;
7699 /* nothing on the iflist */
7706 /* at least one member on the iflist */
7707 struct dahdi_pvt
*working
= *wlist
;
7709 /* check if we maybe have to put it on the begining */
7710 if (working
->channel
> tmp
->channel
) {
7713 (*wlist
)->prev
= tmp
;
7716 /* go through all the members and put the member in the right place */
7719 if (working
->next
) {
7720 if (working
->channel
< tmp
->channel
&& working
->next
->channel
> tmp
->channel
) {
7721 tmp
->next
= working
->next
;
7722 tmp
->prev
= working
;
7723 working
->next
->prev
= tmp
;
7724 working
->next
= tmp
;
7729 if (working
->channel
< tmp
->channel
) {
7730 working
->next
= tmp
;
7732 tmp
->prev
= working
;
7737 working
= working
->next
;
7745 static inline int available(struct dahdi_pvt
*p
, int channelmatch
, ast_group_t groupmatch
, int *busy
, int *channelmatched
, int *groupmatched
)
7748 struct dahdi_params par
;
7750 /* First, check group matching */
7752 if ((p
->group
& groupmatch
) != groupmatch
)
7756 /* Check to see if we have a channel match */
7757 if (channelmatch
!= -1) {
7758 if (p
->channel
!= channelmatch
)
7760 *channelmatched
= 1;
7762 /* We're at least busy at this point */
7764 if ((p
->sig
== SIG_FXOKS
) || (p
->sig
== SIG_FXOLS
) || (p
->sig
== SIG_FXOGS
))
7767 /* If do not disturb, definitely not */
7770 /* If guard time, definitely not */
7771 if (p
->guardtime
&& (time(NULL
) < p
->guardtime
))
7774 /* If no owner definitely available */
7779 if (p
->resetting
|| p
->call
)
7785 if (!(p
->radio
|| (p
->oprmode
< 0)))
7787 if (!p
->sig
|| (p
->sig
== SIG_FXSLS
))
7789 /* Check hook state */
7790 if (p
->subs
[SUB_REAL
].dfd
> -1)
7791 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &par
);
7793 /* Assume not off hook on CVRS */
7795 par
.rxisoffhook
= 0;
7798 ast_log(LOG_WARNING
, "Unable to check hook state on channel %d: %s\n", p
->channel
, strerror(errno
));
7799 } else if ((p
->sig
== SIG_FXSKS
) || (p
->sig
== SIG_FXSGS
)) {
7800 /* When "onhook" that means no battery on the line, and thus
7801 it is out of service..., if it's on a TDM card... If it's a channel
7802 bank, there is no telling... */
7803 if (par
.rxbits
> -1)
7805 if (par
.rxisoffhook
)
7808 #ifdef DAHDI_CHECK_HOOKSTATE
7813 } else if (par
.rxisoffhook
) {
7814 ast_log(LOG_DEBUG
, "Channel %d off hook, can't use\n", p
->channel
);
7815 /* Not available when the other end is off hook */
7822 /* If it's not an FXO, forget about call wait */
7823 if ((p
->sig
!= SIG_FXOKS
) && (p
->sig
!= SIG_FXOLS
) && (p
->sig
!= SIG_FXOGS
))
7826 if (!p
->callwaiting
) {
7827 /* If they don't have call waiting enabled, then for sure they're unavailable at this point */
7831 if (p
->subs
[SUB_CALLWAIT
].dfd
> -1) {
7832 /* If there is already a call waiting call, then we can't take a second one */
7836 if ((p
->owner
->_state
!= AST_STATE_UP
) &&
7837 ((p
->owner
->_state
!= AST_STATE_RINGING
) || p
->outgoing
)) {
7838 /* If the current call is not up, then don't allow the call */
7841 if ((p
->subs
[SUB_THREEWAY
].owner
) && (!p
->subs
[SUB_THREEWAY
].inthreeway
)) {
7842 /* Can't take a call wait when the three way calling hasn't been merged yet. */
7849 static struct dahdi_pvt
*chandup(struct dahdi_pvt
*src
)
7851 struct dahdi_pvt
*p
;
7852 struct dahdi_bufferinfo bi
;
7855 if ((p
= ast_malloc(sizeof(*p
)))) {
7856 memcpy(p
, src
, sizeof(struct dahdi_pvt
));
7857 ast_mutex_init(&p
->lock
);
7859 p
->subs
[SUB_REAL
].dfd
= dahdi_open("/dev/zap/pseudo");
7861 p
->subs
[SUB_REAL
].dfd
= dahdi_open("/dev/dahdi/pseudo");
7863 /* Allocate a DAHDI structure */
7864 if (p
->subs
[SUB_REAL
].dfd
< 0) {
7865 ast_log(LOG_ERROR
, "Unable to dup channel: %s\n", strerror(errno
));
7866 destroy_dahdi_pvt(&p
);
7869 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_GET_BUFINFO
, &bi
);
7871 bi
.txbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
7872 bi
.rxbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
7873 bi
.numbufs
= numbufs
;
7874 res
= ioctl(p
->subs
[SUB_REAL
].dfd
, DAHDI_SET_BUFINFO
, &bi
);
7876 ast_log(LOG_WARNING
, "Unable to set buffer policy on dup channel: %s\n", strerror(errno
));
7879 ast_log(LOG_WARNING
, "Unable to check buffer policy on dup channel: %s\n", strerror(errno
));
7886 iflist
->next
->prev
= p
;
7892 static int pri_find_empty_chan(struct dahdi_pri
*pri
, int backwards
)
7900 if (backwards
&& (x
< 0))
7902 if (!backwards
&& (x
>= pri
->numchans
))
7904 if (pri
->pvts
[x
] && !pri
->pvts
[x
]->inalarm
&& !pri
->pvts
[x
]->owner
) {
7905 ast_log(LOG_DEBUG
, "Found empty available channel %d/%d\n",
7906 pri
->pvts
[x
]->logicalspan
, pri
->pvts
[x
]->prioffset
);
7918 static struct ast_channel
*dahdi_request(const char *type
, int format
, void *data
, int *cause
)
7920 ast_group_t groupmatch
= 0;
7921 int channelmatch
= -1;
7925 struct dahdi_pvt
*p
;
7926 struct ast_channel
*tmp
= NULL
;
7937 struct dahdi_pri
*pri
=NULL
;
7939 struct dahdi_pvt
*exit
, *start
, *end
;
7941 int channelmatched
= 0;
7942 int groupmatched
= 0;
7944 /* Assume we're locking the iflock */
7949 dest
= ast_strdupa((char *)data
);
7951 ast_log(LOG_WARNING
, "Channel requested with no data\n");
7954 if (toupper(dest
[0]) == 'G' || toupper(dest
[0])=='R') {
7955 /* Retrieve the group number */
7958 s
= strsep(&stringp
, "/");
7959 if ((res
= sscanf(s
, "%d%c%d", &x
, &opt
, &y
)) < 1) {
7960 ast_log(LOG_WARNING
, "Unable to determine group for data %s\n", (char *)data
);
7963 groupmatch
= ((ast_group_t
) 1 << x
);
7964 if (toupper(dest
[0]) == 'G') {
7965 if (dest
[0] == 'G') {
7971 if (dest
[0] == 'R') {
7973 p
= round_robin
[x
]?round_robin
[x
]->prev
:ifend
;
7977 p
= round_robin
[x
]?round_robin
[x
]->next
:iflist
;
7986 s
= strsep(&stringp
, "/");
7988 if (!strcasecmp(s
, "pseudo")) {
7989 /* Special case for pseudo */
7994 else if ((res
= sscanf(s
, "%d:%d%c%d", &trunkgroup
, &crv
, &opt
, &y
)) > 1) {
7995 if ((trunkgroup
< 1) || (crv
< 1)) {
7996 ast_log(LOG_WARNING
, "Unable to determine trunk group and CRV for data %s\n", (char *)data
);
8000 for (x
= 0; x
< NUM_SPANS
; x
++) {
8001 if (pris
[x
].trunkgroup
== trunkgroup
) {
8010 ast_log(LOG_WARNING
, "Unable to find trunk group %d\n", trunkgroup
);
8017 else if ((res
= sscanf(s
, "%d%c%d", &x
, &opt
, &y
)) < 1) {
8018 ast_log(LOG_WARNING
, "Unable to determine channel for data %s\n", (char *)data
);
8024 /* Search for an unowned channel */
8025 ast_mutex_lock(lock
);
8031 ast_verbose("name = %s, %d, %d, %d\n",p
->owner
? p
->owner
->name
: "<none>", p
->channel
, channelmatch
, groupmatch
);
8034 if (p
&& available(p
, channelmatch
, groupmatch
, &busy
, &channelmatched
, &groupmatched
)) {
8036 ast_log(LOG_DEBUG
, "Using channel %d\n", p
->channel
);
8040 callwait
= (p
->owner
!= NULL
);
8042 if (pri
&& (p
->subs
[SUB_REAL
].dfd
< 0)) {
8043 if (p
->sig
!= SIG_FXSKS
) {
8044 /* Gotta find an actual channel to use for this
8045 CRV if this isn't a callwait */
8046 bearer
= pri_find_empty_chan(pri
, 0);
8048 ast_log(LOG_NOTICE
, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri
->span
, trunkgroup
, crv
);
8052 pri_assign_bearer(p
, pri
, pri
->pvts
[bearer
]);
8054 if (alloc_sub(p
, 0)) {
8055 ast_log(LOG_NOTICE
, "Failed to allocate place holder pseudo channel!\n");
8059 ast_log(LOG_DEBUG
, "Allocated placeholder pseudo channel\n");
8064 if (p
->channel
== CHAN_PSEUDO
) {
8071 if (alloc_sub(p
, SUB_CALLWAIT
)) {
8077 tmp
= dahdi_new(p
, AST_STATE_RESERVED
, 0, p
->owner
? SUB_CALLWAIT
: SUB_REAL
, 0, 0);
8080 /* Log owner to bearer channel, too */
8081 p
->bearer
->owner
= tmp
;
8084 /* Make special notes */
8087 /* Confirm answer */
8088 p
->confirmanswer
= 1;
8089 } else if (opt
== 'r') {
8090 /* Distinctive ring */
8092 ast_log(LOG_WARNING
, "Distinctive ring missing identifier in '%s'\n", (char *)data
);
8094 p
->distinctivering
= y
;
8095 } else if (opt
== 'd') {
8096 /* If this is an ISDN call, make it digital */
8099 tmp
->transfercapability
= AST_TRANS_CAP_DIGITAL
;
8101 ast_log(LOG_WARNING
, "Unknown option '%c' in '%s'\n", opt
, (char *)data
);
8104 /* Note if the call is a call waiting call */
8105 if (tmp
&& callwait
)
8106 tmp
->cdrflags
|= AST_CDR_CALLWAIT
;
8119 /* stop when you roll to the one that we started from */
8123 ast_mutex_unlock(lock
);
8126 *cause
= AST_CAUSE_BUSY
;
8128 if (channelmatched
) {
8130 *cause
= AST_CAUSE_BUSY
;
8131 } else if (groupmatched
) {
8132 *cause
= AST_CAUSE_CONGESTION
;
8141 static struct dahdi_pvt
*pri_find_crv(struct dahdi_pri
*pri
, int crv
)
8143 struct dahdi_pvt
*p
;
8146 if (p
->channel
== crv
)
8154 static int pri_find_principle(struct dahdi_pri
*pri
, int channel
)
8157 int span
= PRI_SPAN(channel
);
8159 struct dahdi_params param
;
8161 int explicit = PRI_EXPLICIT(channel
);
8162 channel
= PRI_CHANNEL(channel
);
8165 spanfd
= pri_active_dchan_fd(pri
);
8166 if (ioctl(spanfd
, DAHDI_GET_PARAMS
, ¶m
))
8168 span
= pris
[param
.spanno
- 1].prilogicalspan
;
8171 for (x
= 0; x
< pri
->numchans
; x
++) {
8172 if (pri
->pvts
[x
] && (pri
->pvts
[x
]->prioffset
== channel
) && (pri
->pvts
[x
]->logicalspan
== span
)) {
8181 static int pri_fixup_principle(struct dahdi_pri
*pri
, int principle
, q931_call
*c
)
8184 struct dahdi_pvt
*crv
;
8190 if ((principle
> -1) &&
8191 (principle
< pri
->numchans
) &&
8192 (pri
->pvts
[principle
]) &&
8193 (pri
->pvts
[principle
]->call
== c
))
8195 /* First, check for other bearers */
8196 for (x
= 0; x
< pri
->numchans
; x
++) {
8199 if (pri
->pvts
[x
]->call
== c
) {
8200 /* Found our call */
8201 if (principle
!= x
) {
8202 struct dahdi_pvt
*new = pri
->pvts
[principle
], *old
= pri
->pvts
[x
];
8204 if (option_verbose
> 2)
8205 ast_verbose(VERBOSE_PREFIX_3
"Moving call from channel %d to channel %d\n",
8206 old
->channel
, new->channel
);
8208 ast_log(LOG_WARNING
, "Can't fix up channel from %d to %d because %d is already in use\n",
8209 old
->channel
, new->channel
, new->channel
);
8212 /* Fix it all up now */
8213 new->owner
= old
->owner
;
8216 ast_string_field_build(new->owner
, name
, "%s/%d:%d-%d", dahdi_chan_name
, pri
->trunkgroup
, new->channel
, 1);
8217 new->owner
->tech_pvt
= new;
8218 new->owner
->fds
[0] = new->subs
[SUB_REAL
].dfd
;
8219 new->subs
[SUB_REAL
].owner
= old
->subs
[SUB_REAL
].owner
;
8220 old
->subs
[SUB_REAL
].owner
= NULL
;
8222 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
);
8223 new->call
= old
->call
;
8226 /* Copy any DSP that may be present */
8227 new->dsp
= old
->dsp
;
8228 new->dsp_features
= old
->dsp_features
;
8230 old
->dsp_features
= 0;
8235 /* Now check for a CRV with no bearer */
8238 if (crv
->call
== c
) {
8239 /* This is our match... Perform some basic checks */
8241 ast_log(LOG_WARNING
, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
8242 else if (pri
->pvts
[principle
]->owner
)
8243 ast_log(LOG_WARNING
, "Tring to fix up a call to a bearer which already has an owner!\n");
8245 /* Looks good. Drop the pseudo channel now, clear up the assignment, and
8246 wakeup the potential sleeper */
8247 dahdi_close(crv
->subs
[SUB_REAL
].dfd
);
8248 pri
->pvts
[principle
]->call
= crv
->call
;
8249 pri_assign_bearer(crv
, pri
, pri
->pvts
[principle
]);
8250 ast_log(LOG_DEBUG
, "Assigning bearer %d/%d to CRV %d:%d\n",
8251 pri
->pvts
[principle
]->logicalspan
, pri
->pvts
[principle
]->prioffset
,
8252 pri
->trunkgroup
, crv
->channel
);
8253 wakeup_sub(crv
, SUB_REAL
, pri
);
8259 ast_log(LOG_WARNING
, "Call specified, but not found?\n");
8263 static void *do_idle_thread(void *vchan
)
8265 struct ast_channel
*chan
= vchan
;
8266 struct dahdi_pvt
*pvt
= chan
->tech_pvt
;
8267 struct ast_frame
*f
;
8269 /* Wait up to 30 seconds for an answer */
8270 int newms
, ms
= 30000;
8271 if (option_verbose
> 2)
8272 ast_verbose(VERBOSE_PREFIX_3
"Initiating idle call on channel %s\n", chan
->name
);
8273 snprintf(ex
, sizeof(ex
), "%d/%s", pvt
->channel
, pvt
->pri
->idledial
);
8274 if (ast_call(chan
, ex
, 0)) {
8275 ast_log(LOG_WARNING
, "Idle dial failed on '%s' to '%s'\n", chan
->name
, ex
);
8279 while ((newms
= ast_waitfor(chan
, ms
)) > 0) {
8285 if (f
->frametype
== AST_FRAME_CONTROL
) {
8286 switch (f
->subclass
) {
8287 case AST_CONTROL_ANSWER
:
8288 /* Launch the PBX */
8289 ast_copy_string(chan
->exten
, pvt
->pri
->idleext
, sizeof(chan
->exten
));
8290 ast_copy_string(chan
->context
, pvt
->pri
->idlecontext
, sizeof(chan
->context
));
8292 if (option_verbose
> 3)
8293 ast_verbose(VERBOSE_PREFIX_3
"Idle channel '%s' answered, sending to %s@%s\n", chan
->name
, chan
->exten
, chan
->context
);
8295 /* It's already hungup, return immediately */
8297 case AST_CONTROL_BUSY
:
8298 if (option_verbose
> 3)
8299 ast_verbose(VERBOSE_PREFIX_3
"Idle channel '%s' busy, waiting...\n", chan
->name
);
8301 case AST_CONTROL_CONGESTION
:
8302 if (option_verbose
> 3)
8303 ast_verbose(VERBOSE_PREFIX_3
"Idle channel '%s' congested, waiting...\n", chan
->name
);
8310 /* Hangup the channel since nothing happend */
8316 #error "Upgrade your libpri"
8318 static void dahdi_pri_message(struct pri
*pri
, char *s
)
8321 int dchan
= -1, span
= -1;
8325 for (x
= 0; x
< NUM_SPANS
; x
++) {
8326 for (y
= 0; y
< NUM_DCHANS
; y
++) {
8327 if (pris
[x
].dchans
[y
])
8330 if (pris
[x
].dchans
[y
] == pri
)
8339 if ((dchan
>= 0) && (span
>= 0)) {
8341 ast_verbose("[Span %d D-Channel %d]%s", span
, dchan
, s
);
8343 ast_verbose("%s", s
);
8345 ast_log(LOG_ERROR
, "PRI debug error: could not find pri associated it with debug message output\n");
8347 ast_verbose("%s", s
);
8349 ast_mutex_lock(&pridebugfdlock
);
8351 if (pridebugfd
>= 0)
8352 write(pridebugfd
, s
, strlen(s
));
8354 ast_mutex_unlock(&pridebugfdlock
);
8357 static void dahdi_pri_error(struct pri
*pri
, char *s
)
8360 int dchan
= -1, span
= -1;
8364 for (x
= 0; x
< NUM_SPANS
; x
++) {
8365 for (y
= 0; y
< NUM_DCHANS
; y
++) {
8366 if (pris
[x
].dchans
[y
])
8369 if (pris
[x
].dchans
[y
] == pri
)
8378 if ((dchan
>= 0) && (span
>= 0)) {
8380 ast_log(LOG_ERROR
, "[Span %d D-Channel %d] PRI: %s", span
, dchan
, s
);
8382 ast_log(LOG_ERROR
, "%s", s
);
8384 ast_log(LOG_ERROR
, "PRI debug error: could not find pri associated it with debug message output\n");
8386 ast_log(LOG_ERROR
, "%s", s
);
8388 ast_mutex_lock(&pridebugfdlock
);
8390 if (pridebugfd
>= 0)
8391 write(pridebugfd
, s
, strlen(s
));
8393 ast_mutex_unlock(&pridebugfdlock
);
8396 static int pri_check_restart(struct dahdi_pri
*pri
)
8400 } while ((pri
->resetpos
< pri
->numchans
) &&
8401 (!pri
->pvts
[pri
->resetpos
] ||
8402 pri
->pvts
[pri
->resetpos
]->call
||
8403 pri
->pvts
[pri
->resetpos
]->resetting
));
8404 if (pri
->resetpos
< pri
->numchans
) {
8405 /* Mark the channel as resetting and restart it */
8406 pri
->pvts
[pri
->resetpos
]->resetting
= 1;
8407 pri_reset(pri
->pri
, PVT_TO_CHANNEL(pri
->pvts
[pri
->resetpos
]));
8410 time(&pri
->lastreset
);
8415 static int pri_hangup_all(struct dahdi_pvt
*p
, struct dahdi_pri
*pri
)
8419 ast_mutex_unlock(&pri
->lock
);
8420 ast_mutex_lock(&p
->lock
);
8423 for (x
= 0; x
< 3; x
++) {
8424 while (p
->subs
[x
].owner
&& ast_mutex_trylock(&p
->subs
[x
].owner
->lock
)) {
8426 DEADLOCK_AVOIDANCE(&p
->lock
);
8428 if (p
->subs
[x
].owner
) {
8429 ast_queue_hangup(p
->subs
[x
].owner
);
8430 ast_mutex_unlock(&p
->subs
[x
].owner
->lock
);
8434 ast_mutex_unlock(&p
->lock
);
8435 ast_mutex_lock(&pri
->lock
);
8439 static char * redirectingreason2str(int redirectingreason
)
8441 switch (redirectingreason
) {
8449 return "UNCONDITIONAL";
8451 return "NOREDIRECT";
8455 static void apply_plan_to_number(char *buf
, size_t size
, const struct dahdi_pri
*pri
, const char *number
, const int plan
)
8458 case PRI_INTERNATIONAL_ISDN
: /* Q.931 dialplan == 0x11 international dialplan => prepend international prefix digits */
8459 snprintf(buf
, size
, "%s%s", pri
->internationalprefix
, number
);
8461 case PRI_NATIONAL_ISDN
: /* Q.931 dialplan == 0x21 national dialplan => prepend national prefix digits */
8462 snprintf(buf
, size
, "%s%s", pri
->nationalprefix
, number
);
8464 case PRI_LOCAL_ISDN
: /* Q.931 dialplan == 0x41 local dialplan => prepend local prefix digits */
8465 snprintf(buf
, size
, "%s%s", pri
->localprefix
, number
);
8467 case PRI_PRIVATE
: /* Q.931 dialplan == 0x49 private dialplan => prepend private prefix digits */
8468 snprintf(buf
, size
, "%s%s", pri
->privateprefix
, number
);
8470 case PRI_UNKNOWN
: /* Q.931 dialplan == 0x00 unknown dialplan => prepend unknown prefix digits */
8471 snprintf(buf
, size
, "%s%s", pri
->unknownprefix
, number
);
8473 default: /* other Q.931 dialplan => don't twiddle with callingnum */
8474 snprintf(buf
, size
, "%s", number
);
8479 static int dahdi_setlaw(int dfd
, int law
)
8482 res
= ioctl(dfd
, DAHDI_SETLAW
, &law
);
8488 static void *pri_dchannel(void *vpri
)
8490 struct dahdi_pri
*pri
= vpri
;
8492 struct pollfd fds
[NUM_DCHANS
];
8499 struct ast_channel
*c
;
8500 struct timeval tv
, lowest
, *next
;
8501 struct timeval lastidle
= { 0, 0 };
8505 struct ast_channel
*idle
;
8511 struct dahdi_pvt
*crv
;
8513 pthread_attr_t attr
;
8515 char plancallingnum
[256];
8516 char plancallingani
[256];
8517 char calledtonstr
[10];
8519 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
8521 gettimeofday(&lastidle
, NULL
);
8522 if (!ast_strlen_zero(pri
->idledial
) && !ast_strlen_zero(pri
->idleext
)) {
8523 /* Need to do idle dialing, check to be sure though */
8524 cc
= strchr(pri
->idleext
, '@');
8528 ast_copy_string(pri
->idlecontext
, cc
, sizeof(pri
->idlecontext
));
8530 /* Extensions may not be loaded yet */
8531 if (!ast_exists_extension(NULL
, pri
->idlecontext
, pri
->idleext
, 1, NULL
))
8532 ast_log(LOG_WARNING
, "Extension '%s @ %s' does not exist\n", pri
->idleext
, pri
->idlecontext
);
8537 ast_log(LOG_WARNING
, "Idle dial string '%s' lacks '@context'\n", pri
->idleext
);
8540 for (i
= 0; i
< NUM_DCHANS
; i
++) {
8541 if (!pri
->dchannels
[i
])
8543 fds
[i
].fd
= pri
->fds
[i
];
8544 fds
[i
].events
= POLLIN
| POLLPRI
;
8549 ast_mutex_lock(&pri
->lock
);
8550 if (pri
->switchtype
!= PRI_SWITCH_GR303_TMC
&& (pri
->resetinterval
> 0)) {
8551 if (pri
->resetting
&& pri_is_up(pri
)) {
8552 if (pri
->resetpos
< 0)
8553 pri_check_restart(pri
);
8555 if (!pri
->resetting
&& (t
- pri
->lastreset
) >= pri
->resetinterval
) {
8561 /* Look for any idle channels if appropriate */
8562 if (doidling
&& pri_is_up(pri
)) {
8566 for (x
= pri
->numchans
; x
>= 0; x
--) {
8567 if (pri
->pvts
[x
] && !pri
->pvts
[x
]->owner
&&
8568 !pri
->pvts
[x
]->call
) {
8569 if (haveidles
< pri
->minunused
) {
8571 } else if (!pri
->pvts
[x
]->resetting
) {
8575 } else if (pri
->pvts
[x
] && pri
->pvts
[x
]->owner
&& pri
->pvts
[x
]->isidlecall
)
8578 if (nextidle
> -1) {
8579 if (ast_tvdiff_ms(ast_tvnow(), lastidle
) > 1000) {
8580 /* Don't create a new idle call more than once per second */
8581 snprintf(idlen
, sizeof(idlen
), "%d/%s", pri
->pvts
[nextidle
]->channel
, pri
->idledial
);
8582 idle
= dahdi_request(dahdi_chan_name
, AST_FORMAT_ULAW
, idlen
, &cause
);
8584 pri
->pvts
[nextidle
]->isidlecall
= 1;
8585 if (ast_pthread_create_background(&p
, NULL
, do_idle_thread
, idle
)) {
8586 ast_log(LOG_WARNING
, "Unable to start new thread for idle channel '%s'\n", idle
->name
);
8590 ast_log(LOG_WARNING
, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen
);
8591 gettimeofday(&lastidle
, NULL
);
8593 } else if ((haveidles
< pri
->minunused
) &&
8594 (activeidles
> pri
->minidle
)) {
8595 /* Mark something for hangup if there is something
8596 that can be hungup */
8597 for (x
= pri
->numchans
; x
>= 0; x
--) {
8598 /* find a candidate channel */
8599 if (pri
->pvts
[x
] && pri
->pvts
[x
]->owner
&& pri
->pvts
[x
]->isidlecall
) {
8600 pri
->pvts
[x
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
8602 /* Stop if we have enough idle channels or
8603 can't spare any more active idle ones */
8604 if ((haveidles
>= pri
->minunused
) ||
8605 (activeidles
<= pri
->minidle
))
8611 /* Start with reasonable max */
8612 lowest
= ast_tv(60, 0);
8613 for (i
= 0; i
< NUM_DCHANS
; i
++) {
8614 /* Find lowest available d-channel */
8615 if (!pri
->dchannels
[i
])
8617 if ((next
= pri_schedule_next(pri
->dchans
[i
]))) {
8618 /* We need relative time here */
8619 tv
= ast_tvsub(*next
, ast_tvnow());
8620 if (tv
.tv_sec
< 0) {
8623 if (doidling
|| pri
->resetting
) {
8624 if (tv
.tv_sec
> 1) {
8628 if (tv
.tv_sec
> 60) {
8632 } else if (doidling
|| pri
->resetting
) {
8633 /* Make sure we stop at least once per second if we're
8634 monitoring idle channels */
8637 /* Don't poll for more than 60 seconds */
8640 if (!i
|| ast_tvcmp(tv
, lowest
) < 0) {
8644 ast_mutex_unlock(&pri
->lock
);
8646 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
);
8647 pthread_testcancel();
8649 res
= poll(fds
, numdchans
, lowest
.tv_sec
* 1000 + lowest
.tv_usec
/ 1000);
8650 pthread_testcancel();
8651 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, NULL
);
8653 ast_mutex_lock(&pri
->lock
);
8655 for (which
= 0; which
< NUM_DCHANS
; which
++) {
8656 if (!pri
->dchans
[which
])
8658 /* Just a timeout, run the scheduler */
8659 e
= pri_schedule_run(pri
->dchans
[which
]);
8663 } else if (res
> -1) {
8664 for (which
= 0; which
< NUM_DCHANS
; which
++) {
8665 if (!pri
->dchans
[which
])
8667 if (fds
[which
].revents
& POLLPRI
) {
8668 /* Check for an event */
8670 res
= ioctl(pri
->fds
[which
], DAHDI_GETEVENT
, &x
);
8672 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
);
8673 /* Keep track of alarm state */
8674 if (x
== DAHDI_EVENT_ALARM
) {
8675 pri
->dchanavail
[which
] &= ~(DCHAN_NOTINALARM
| DCHAN_UP
);
8676 pri_find_dchan(pri
);
8677 } else if (x
== DAHDI_EVENT_NOALARM
) {
8678 pri
->dchanavail
[which
] |= DCHAN_NOTINALARM
;
8679 pri_restart(pri
->dchans
[which
]);
8683 ast_log(LOG_DEBUG
, "Got event %s (%d) on D-channel for span %d\n", event2str(x
), x
, pri
->span
);
8684 } else if (fds
[which
].revents
& POLLIN
) {
8685 e
= pri_check_event(pri
->dchans
[which
]);
8690 } else if (errno
!= EINTR
)
8691 ast_log(LOG_WARNING
, "pri_event returned error %d (%s)\n", errno
, strerror(errno
));
8695 pri_dump_event(pri
->dchans
[which
], e
);
8697 if (e
->e
!= PRI_EVENT_DCHAN_DOWN
) {
8698 if (!(pri
->dchanavail
[which
] & DCHAN_UP
)) {
8699 if (option_verbose
> 1)
8700 ast_verbose(VERBOSE_PREFIX_2
"%s D-Channel on span %d up\n", pri_order(which
), pri
->span
);
8702 pri
->dchanavail
[which
] |= DCHAN_UP
;
8704 if (pri
->dchanavail
[which
] & DCHAN_UP
) {
8705 if (option_verbose
> 1)
8706 ast_verbose(VERBOSE_PREFIX_2
"%s D-Channel on span %d down\n", pri_order(which
), pri
->span
);
8708 pri
->dchanavail
[which
] &= ~DCHAN_UP
;
8711 if ((e
->e
!= PRI_EVENT_DCHAN_UP
) && (e
->e
!= PRI_EVENT_DCHAN_DOWN
) && (pri
->pri
!= pri
->dchans
[which
]))
8712 /* Must be an NFAS group that has the secondary dchan active */
8713 pri
->pri
= pri
->dchans
[which
];
8716 case PRI_EVENT_DCHAN_UP
:
8717 if (!pri
->pri
) pri_find_dchan(pri
);
8719 /* Note presense of D-channel */
8720 time(&pri
->lastreset
);
8722 /* Restart in 5 seconds */
8723 if (pri
->resetinterval
> -1) {
8724 pri
->lastreset
-= pri
->resetinterval
;
8725 pri
->lastreset
+= 5;
8728 /* Take the channels from inalarm condition */
8729 for (i
= 0; i
< pri
->numchans
; i
++)
8731 pri
->pvts
[i
]->inalarm
= 0;
8734 case PRI_EVENT_DCHAN_DOWN
:
8735 pri_find_dchan(pri
);
8736 if (!pri_is_up(pri
)) {
8738 /* Hangup active channels and put them in alarm mode */
8739 for (i
= 0; i
< pri
->numchans
; i
++) {
8740 struct dahdi_pvt
*p
= pri
->pvts
[i
];
8742 if (!p
->pri
|| !p
->pri
->pri
|| pri_get_timer(p
->pri
->pri
, PRI_TIMER_T309
) < 0) {
8743 /* T309 is not enabled : hangup calls when alarm occurs */
8745 if (p
->pri
&& p
->pri
->pri
) {
8746 pri_hangup(p
->pri
->pri
, p
->call
, -1);
8747 pri_destroycall(p
->pri
->pri
, p
->call
);
8750 ast_log(LOG_WARNING
, "The PRI Call have not been destroyed\n");
8753 pri_hangup_all(p
->realcall
, pri
);
8754 } else if (p
->owner
)
8755 p
->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
8762 case PRI_EVENT_RESTART
:
8763 if (e
->restart
.channel
> -1) {
8764 chanpos
= pri_find_principle(pri
, e
->restart
.channel
);
8766 ast_log(LOG_WARNING
, "Restart requested on odd/unavailable channel number %d/%d on span %d\n",
8767 PRI_SPAN(e
->restart
.channel
), PRI_CHANNEL(e
->restart
.channel
), pri
->span
);
8769 if (option_verbose
> 2)
8770 ast_verbose(VERBOSE_PREFIX_3
"B-channel %d/%d restarted on span %d\n",
8771 PRI_SPAN(e
->restart
.channel
), PRI_CHANNEL(e
->restart
.channel
), pri
->span
);
8772 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
8773 if (pri
->pvts
[chanpos
]->call
) {
8774 pri_destroycall(pri
->pri
, pri
->pvts
[chanpos
]->call
);
8775 pri
->pvts
[chanpos
]->call
= NULL
;
8777 /* Force soft hangup if appropriate */
8778 if (pri
->pvts
[chanpos
]->realcall
)
8779 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
8780 else if (pri
->pvts
[chanpos
]->owner
)
8781 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
8782 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8785 if (option_verbose
> 2)
8786 ast_verbose(VERBOSE_PREFIX_2
"Restart on requested on entire span %d\n", pri
->span
);
8787 for (x
= 0; x
< pri
->numchans
; x
++)
8789 ast_mutex_lock(&pri
->pvts
[x
]->lock
);
8790 if (pri
->pvts
[x
]->call
) {
8791 pri_destroycall(pri
->pri
, pri
->pvts
[x
]->call
);
8792 pri
->pvts
[x
]->call
= NULL
;
8794 if (pri
->pvts
[chanpos
]->realcall
)
8795 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
8796 else if (pri
->pvts
[x
]->owner
)
8797 pri
->pvts
[x
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
8798 ast_mutex_unlock(&pri
->pvts
[x
]->lock
);
8802 case PRI_EVENT_KEYPAD_DIGIT
:
8803 chanpos
= pri_find_principle(pri
, e
->digit
.channel
);
8805 ast_log(LOG_WARNING
, "KEYPAD_DIGITs received on unconfigured channel %d/%d span %d\n",
8806 PRI_SPAN(e
->digit
.channel
), PRI_CHANNEL(e
->digit
.channel
), pri
->span
);
8808 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->digit
.call
);
8810 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
8811 /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */
8812 if (pri
->overlapdial
&& pri
->pvts
[chanpos
]->call
==e
->digit
.call
&& pri
->pvts
[chanpos
]->owner
) {
8813 /* how to do that */
8814 int digitlen
= strlen(e
->digit
.digits
);
8817 for (i
= 0; i
< digitlen
; i
++) {
8818 digit
= e
->digit
.digits
[i
];
8820 struct ast_frame f
= { AST_FRAME_DTMF
, digit
, };
8821 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
8825 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8830 case PRI_EVENT_INFO_RECEIVED
:
8831 chanpos
= pri_find_principle(pri
, e
->ring
.channel
);
8833 ast_log(LOG_WARNING
, "INFO received on unconfigured channel %d/%d span %d\n",
8834 PRI_SPAN(e
->ring
.channel
), PRI_CHANNEL(e
->ring
.channel
), pri
->span
);
8836 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->ring
.call
);
8838 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
8839 /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */
8840 if (pri
->overlapdial
&& pri
->pvts
[chanpos
]->call
==e
->ring
.call
&& pri
->pvts
[chanpos
]->owner
) {
8841 /* how to do that */
8842 int digitlen
= strlen(e
->ring
.callednum
);
8845 for (i
= 0; i
< digitlen
; i
++) {
8846 digit
= e
->ring
.callednum
[i
];
8848 struct ast_frame f
= { AST_FRAME_DTMF
, digit
, };
8849 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
8853 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8857 case PRI_EVENT_RING
:
8859 if (e
->ring
.channel
== -1)
8860 chanpos
= pri_find_empty_chan(pri
, 1);
8862 chanpos
= pri_find_principle(pri
, e
->ring
.channel
);
8863 /* if no channel specified find one empty */
8865 ast_log(LOG_WARNING
, "Ring requested on unconfigured channel %d/%d span %d\n",
8866 PRI_SPAN(e
->ring
.channel
), PRI_CHANNEL(e
->ring
.channel
), pri
->span
);
8868 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
8869 if (pri
->pvts
[chanpos
]->owner
) {
8870 if (pri
->pvts
[chanpos
]->call
== e
->ring
.call
) {
8871 ast_log(LOG_WARNING
, "Duplicate setup requested on channel %d/%d already in use on span %d\n",
8872 PRI_SPAN(e
->ring
.channel
), PRI_CHANNEL(e
->ring
.channel
), pri
->span
);
8875 /* This is where we handle initial glare */
8876 ast_log(LOG_DEBUG
, "Ring requested on channel %d/%d already in use or previously requested on span %d. Attempting to renegotiating channel.\n",
8877 PRI_SPAN(e
->ring
.channel
), PRI_CHANNEL(e
->ring
.channel
), pri
->span
);
8878 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8883 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8885 if ((chanpos
< 0) && (e
->ring
.flexible
))
8886 chanpos
= pri_find_empty_chan(pri
, 1);
8888 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
8889 if (pri
->switchtype
== PRI_SWITCH_GR303_TMC
) {
8890 /* Should be safe to lock CRV AFAIK while bearer is still locked */
8891 crv
= pri_find_crv(pri
, pri_get_crv(pri
->pri
, e
->ring
.call
, NULL
));
8893 ast_mutex_lock(&crv
->lock
);
8894 if (!crv
|| crv
->owner
) {
8895 pri
->pvts
[chanpos
]->call
= NULL
;
8898 crv
->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
8899 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
);
8901 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
);
8902 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_INVALID_CALL_REFERENCE
);
8904 ast_mutex_unlock(&crv
->lock
);
8905 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
8909 pri
->pvts
[chanpos
]->call
= e
->ring
.call
;
8910 apply_plan_to_number(plancallingnum
, sizeof(plancallingnum
), pri
, e
->ring
.callingnum
, e
->ring
.callingplan
);
8911 if (pri
->pvts
[chanpos
]->use_callerid
) {
8912 ast_shrink_phone_number(plancallingnum
);
8913 ast_copy_string(pri
->pvts
[chanpos
]->cid_num
, plancallingnum
, sizeof(pri
->pvts
[chanpos
]->cid_num
));
8915 if (!ast_strlen_zero(e
->ring
.callingani
)) {
8916 apply_plan_to_number(plancallingani
, sizeof(plancallingani
), pri
, e
->ring
.callingani
, e
->ring
.callingplanani
);
8917 ast_shrink_phone_number(plancallingani
);
8918 ast_copy_string(pri
->pvts
[chanpos
]->cid_ani
, plancallingani
, sizeof(pri
->pvts
[chanpos
]->cid_ani
));
8920 pri
->pvts
[chanpos
]->cid_ani
[0] = '\0';
8923 ast_copy_string(pri
->pvts
[chanpos
]->cid_name
, e
->ring
.callingname
, sizeof(pri
->pvts
[chanpos
]->cid_name
));
8924 pri
->pvts
[chanpos
]->cid_ton
= e
->ring
.callingplan
; /* this is the callingplan (TON/NPI), e->ring.callingplan>>4 would be the TON */
8926 pri
->pvts
[chanpos
]->cid_num
[0] = '\0';
8927 pri
->pvts
[chanpos
]->cid_ani
[0] = '\0';
8928 pri
->pvts
[chanpos
]->cid_name
[0] = '\0';
8929 pri
->pvts
[chanpos
]->cid_ton
= 0;
8931 apply_plan_to_number(pri
->pvts
[chanpos
]->rdnis
, sizeof(pri
->pvts
[chanpos
]->rdnis
), pri
,
8932 e
->ring
.redirectingnum
, e
->ring
.callingplanrdnis
);
8933 /* If immediate=yes go to s|1 */
8934 if (pri
->pvts
[chanpos
]->immediate
) {
8935 if (option_verbose
> 2)
8936 ast_verbose(VERBOSE_PREFIX_3
"Going to extension s|1 because of immediate=yes\n");
8937 pri
->pvts
[chanpos
]->exten
[0] = 's';
8938 pri
->pvts
[chanpos
]->exten
[1] = '\0';
8940 /* Get called number */
8941 else if (!ast_strlen_zero(e
->ring
.callednum
)) {
8942 ast_copy_string(pri
->pvts
[chanpos
]->exten
, e
->ring
.callednum
, sizeof(pri
->pvts
[chanpos
]->exten
));
8943 ast_copy_string(pri
->pvts
[chanpos
]->dnid
, e
->ring
.callednum
, sizeof(pri
->pvts
[chanpos
]->dnid
));
8944 } else if (pri
->overlapdial
)
8945 pri
->pvts
[chanpos
]->exten
[0] = '\0';
8947 /* Some PRI circuits are set up to send _no_ digits. Handle them as 's'. */
8948 pri
->pvts
[chanpos
]->exten
[0] = 's';
8949 pri
->pvts
[chanpos
]->exten
[1] = '\0';
8951 /* Set DNID on all incoming calls -- even immediate */
8952 if (!ast_strlen_zero(e
->ring
.callednum
))
8953 ast_copy_string(pri
->pvts
[chanpos
]->dnid
, e
->ring
.callednum
, sizeof(pri
->pvts
[chanpos
]->dnid
));
8954 /* No number yet, but received "sending complete"? */
8955 if (e
->ring
.complete
&& (ast_strlen_zero(e
->ring
.callednum
))) {
8956 if (option_verbose
> 2)
8957 ast_verbose(VERBOSE_PREFIX_3
"Going to extension s|1 because of Complete received\n");
8958 pri
->pvts
[chanpos
]->exten
[0] = 's';
8959 pri
->pvts
[chanpos
]->exten
[1] = '\0';
8961 /* Make sure extension exists (or in overlap dial mode, can exist) */
8962 if ((pri
->overlapdial
&& ast_canmatch_extension(NULL
, pri
->pvts
[chanpos
]->context
, pri
->pvts
[chanpos
]->exten
, 1, pri
->pvts
[chanpos
]->cid_num
)) ||
8963 ast_exists_extension(NULL
, pri
->pvts
[chanpos
]->context
, pri
->pvts
[chanpos
]->exten
, 1, pri
->pvts
[chanpos
]->cid_num
)) {
8966 if (pri
->switchtype
!= PRI_SWITCH_GR303_TMC
) {
8967 /* Set to audio mode at this point */
8969 if (ioctl(pri
->pvts
[chanpos
]->subs
[SUB_REAL
].dfd
, DAHDI_AUDIOMODE
, &law
) == -1)
8970 ast_log(LOG_WARNING
, "Unable to set audio mode on channel %d to %d: %s\n", pri
->pvts
[chanpos
]->channel
, law
, strerror(errno
));
8972 if (e
->ring
.layer1
== PRI_LAYER_1_ALAW
)
8973 law
= DAHDI_LAW_ALAW
;
8975 law
= DAHDI_LAW_MULAW
;
8976 res
= dahdi_setlaw(pri
->pvts
[chanpos
]->subs
[SUB_REAL
].dfd
, law
);
8978 ast_log(LOG_WARNING
, "Unable to set law on channel %d\n", pri
->pvts
[chanpos
]->channel
);
8979 res
= set_actual_gain(pri
->pvts
[chanpos
]->subs
[SUB_REAL
].dfd
, 0, pri
->pvts
[chanpos
]->rxgain
, pri
->pvts
[chanpos
]->txgain
, law
);
8981 ast_log(LOG_WARNING
, "Unable to set gains on channel %d\n", pri
->pvts
[chanpos
]->channel
);
8982 if (e
->ring
.complete
|| !pri
->overlapdial
) {
8983 /* Just announce proceeding */
8984 pri
->pvts
[chanpos
]->proceeding
= 1;
8985 pri_proceeding(pri
->pri
, e
->ring
.call
, PVT_TO_CHANNEL(pri
->pvts
[chanpos
]), 0);
8987 if (pri
->switchtype
!= PRI_SWITCH_GR303_TMC
)
8988 pri_need_more_info(pri
->pri
, e
->ring
.call
, PVT_TO_CHANNEL(pri
->pvts
[chanpos
]), 1);
8990 pri_answer(pri
->pri
, e
->ring
.call
, PVT_TO_CHANNEL(pri
->pvts
[chanpos
]), 1);
8992 /* Get the use_callingpres state */
8993 pri
->pvts
[chanpos
]->callingpres
= e
->ring
.callingpres
;
8996 if (!e
->ring
.complete
&& pri
->overlapdial
&& ast_matchmore_extension(NULL
, pri
->pvts
[chanpos
]->context
, pri
->pvts
[chanpos
]->exten
, 1, pri
->pvts
[chanpos
]->cid_num
)) {
8997 /* Release the PRI lock while we create the channel */
8998 ast_mutex_unlock(&pri
->lock
);
9000 /* Set bearer and such */
9001 pri_assign_bearer(crv
, pri
, pri
->pvts
[chanpos
]);
9002 c
= dahdi_new(crv
, AST_STATE_RESERVED
, 0, SUB_REAL
, law
, e
->ring
.ctype
);
9003 pri
->pvts
[chanpos
]->owner
= &inuse
;
9004 ast_log(LOG_DEBUG
, "Started up crv %d:%d on bearer channel %d\n", pri
->trunkgroup
, crv
->channel
, crv
->bearer
->channel
);
9006 c
= dahdi_new(pri
->pvts
[chanpos
], AST_STATE_RESERVED
, 0, SUB_REAL
, law
, e
->ring
.ctype
);
9009 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9011 if (!ast_strlen_zero(e
->ring
.callingsubaddr
)) {
9012 pbx_builtin_setvar_helper(c
, "CALLINGSUBADDR", e
->ring
.callingsubaddr
);
9014 if (e
->ring
.ani2
>= 0) {
9015 snprintf(ani2str
, 5, "%.2d", e
->ring
.ani2
);
9016 pbx_builtin_setvar_helper(c
, "ANI2", ani2str
);
9019 #ifdef SUPPORT_USERUSER
9020 if (!ast_strlen_zero(e
->ring
.useruserinfo
)) {
9021 pbx_builtin_setvar_helper(c
, "USERUSERINFO", e
->ring
.useruserinfo
);
9025 snprintf(calledtonstr
, sizeof(calledtonstr
)-1, "%d", e
->ring
.calledplan
);
9026 pbx_builtin_setvar_helper(c
, "CALLEDTON", calledtonstr
);
9027 if (e
->ring
.redirectingreason
>= 0)
9028 pbx_builtin_setvar_helper(c
, "PRIREDIRECTREASON", redirectingreason2str(e
->ring
.redirectingreason
));
9030 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9031 ast_mutex_lock(&pri
->lock
);
9033 pthread_attr_init(&attr
);
9034 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
9035 if (c
&& !ast_pthread_create(&threadid
, &attr
, ss_thread
, c
)) {
9036 if (option_verbose
> 2)
9037 ast_verbose(VERBOSE_PREFIX_3
"Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
9038 plancallingnum
, S_OR(pri
->pvts
[chanpos
]->exten
, "<unspecified>"),
9039 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9041 ast_log(LOG_WARNING
, "Unable to start PBX on channel %d/%d, span %d\n",
9042 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9046 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_SWITCH_CONGESTION
);
9047 pri
->pvts
[chanpos
]->call
= NULL
;
9050 pthread_attr_destroy(&attr
);
9052 ast_mutex_unlock(&pri
->lock
);
9053 /* Release PRI lock while we create the channel */
9054 c
= dahdi_new(pri
->pvts
[chanpos
], AST_STATE_RING
, 1, SUB_REAL
, law
, e
->ring
.ctype
);
9056 char calledtonstr
[10];
9058 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9060 if (e
->ring
.ani2
>= 0) {
9061 snprintf(ani2str
, 5, "%d", e
->ring
.ani2
);
9062 pbx_builtin_setvar_helper(c
, "ANI2", ani2str
);
9065 #ifdef SUPPORT_USERUSER
9066 if (!ast_strlen_zero(e
->ring
.useruserinfo
)) {
9067 pbx_builtin_setvar_helper(c
, "USERUSERINFO", e
->ring
.useruserinfo
);
9071 if (e
->ring
.redirectingreason
>= 0)
9072 pbx_builtin_setvar_helper(c
, "PRIREDIRECTREASON", redirectingreason2str(e
->ring
.redirectingreason
));
9074 snprintf(calledtonstr
, sizeof(calledtonstr
)-1, "%d", e
->ring
.calledplan
);
9075 pbx_builtin_setvar_helper(c
, "CALLEDTON", calledtonstr
);
9077 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9078 ast_mutex_lock(&pri
->lock
);
9080 if (option_verbose
> 2)
9081 ast_verbose(VERBOSE_PREFIX_3
"Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
9082 plancallingnum
, pri
->pvts
[chanpos
]->exten
,
9083 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9084 dahdi_enable_ec(pri
->pvts
[chanpos
]);
9087 ast_mutex_lock(&pri
->lock
);
9089 ast_log(LOG_WARNING
, "Unable to start PBX on channel %d/%d, span %d\n",
9090 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9091 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_SWITCH_CONGESTION
);
9092 pri
->pvts
[chanpos
]->call
= NULL
;
9096 if (option_verbose
> 2)
9097 ast_verbose(VERBOSE_PREFIX_3
"Extension '%s' in context '%s' from '%s' does not exist. Rejecting call on channel %d/%d, span %d\n",
9098 pri
->pvts
[chanpos
]->exten
, pri
->pvts
[chanpos
]->context
, pri
->pvts
[chanpos
]->cid_num
, pri
->pvts
[chanpos
]->logicalspan
,
9099 pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9100 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_UNALLOCATED
);
9101 pri
->pvts
[chanpos
]->call
= NULL
;
9102 pri
->pvts
[chanpos
]->exten
[0] = '\0';
9105 ast_mutex_unlock(&crv
->lock
);
9106 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9108 if (e
->ring
.flexible
)
9109 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
);
9111 pri_hangup(pri
->pri
, e
->ring
.call
, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
);
9114 case PRI_EVENT_RINGING
:
9115 chanpos
= pri_find_principle(pri
, e
->ringing
.channel
);
9117 ast_log(LOG_WARNING
, "Ringing requested on unconfigured channel %d/%d span %d\n",
9118 PRI_SPAN(e
->ringing
.channel
), PRI_CHANNEL(e
->ringing
.channel
), pri
->span
);
9120 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->ringing
.call
);
9122 ast_log(LOG_WARNING
, "Ringing requested on channel %d/%d not in use on span %d\n",
9123 PRI_SPAN(e
->ringing
.channel
), PRI_CHANNEL(e
->ringing
.channel
), pri
->span
);
9125 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9126 if (ast_strlen_zero(pri
->pvts
[chanpos
]->dop
.dialstr
)) {
9127 dahdi_enable_ec(pri
->pvts
[chanpos
]);
9128 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needringing
= 1;
9129 pri
->pvts
[chanpos
]->alerting
= 1;
9131 ast_log(LOG_DEBUG
, "Deferring ringing notification because of extra digits to dial...\n");
9132 #ifdef PRI_PROGRESS_MASK
9133 if (e
->ringing
.progressmask
& PRI_PROG_INBAND_AVAILABLE
) {
9135 if (e
->ringing
.progress
== 8) {
9137 /* Now we can do call progress detection */
9138 if (pri
->pvts
[chanpos
]->dsp
&& pri
->pvts
[chanpos
]->dsp_features
) {
9139 /* RINGING detection isn't required because we got ALERTING signal */
9140 ast_dsp_set_features(pri
->pvts
[chanpos
]->dsp
, pri
->pvts
[chanpos
]->dsp_features
& ~DSP_PROGRESS_RINGING
);
9141 pri
->pvts
[chanpos
]->dsp_features
= 0;
9145 #ifdef SUPPORT_USERUSER
9146 if (!ast_strlen_zero(e
->ringing
.useruserinfo
)) {
9147 struct ast_channel
*owner
= pri
->pvts
[chanpos
]->owner
;
9148 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9149 pbx_builtin_setvar_helper(owner
, "USERUSERINFO", e
->ringing
.useruserinfo
);
9150 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9154 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9158 case PRI_EVENT_PROGRESS
:
9159 /* Get chan value if e->e is not PRI_EVNT_RINGING */
9160 chanpos
= pri_find_principle(pri
, e
->proceeding
.channel
);
9162 #ifdef PRI_PROGRESS_MASK
9163 if ((!pri
->pvts
[chanpos
]->progress
) || (e
->proceeding
.progressmask
& PRI_PROG_INBAND_AVAILABLE
)) {
9165 if ((!pri
->pvts
[chanpos
]->progress
) || (e
->proceeding
.progress
== 8)) {
9167 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_PROGRESS
, };
9169 if (e
->proceeding
.cause
> -1) {
9170 if (option_verbose
> 2)
9171 ast_verbose(VERBOSE_PREFIX_3
"PROGRESS with cause code %d received\n", e
->proceeding
.cause
);
9173 /* Work around broken, out of spec USER_BUSY cause in a progress message */
9174 if (e
->proceeding
.cause
== AST_CAUSE_USER_BUSY
) {
9175 if (pri
->pvts
[chanpos
]->owner
) {
9176 if (option_verbose
> 2)
9177 ast_verbose(VERBOSE_PREFIX_3
"PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
9179 pri
->pvts
[chanpos
]->owner
->hangupcause
= e
->proceeding
.cause
;
9180 f
.subclass
= AST_CONTROL_BUSY
;
9185 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9186 ast_log(LOG_DEBUG
, "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
9187 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
,pri
->span
);
9188 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
9189 #ifdef PRI_PROGRESS_MASK
9190 if (e
->proceeding
.progressmask
& PRI_PROG_INBAND_AVAILABLE
) {
9192 if (e
->proceeding
.progress
== 8) {
9194 /* Now we can do call progress detection */
9195 if (pri
->pvts
[chanpos
]->dsp
&& pri
->pvts
[chanpos
]->dsp_features
) {
9196 ast_dsp_set_features(pri
->pvts
[chanpos
]->dsp
, pri
->pvts
[chanpos
]->dsp_features
);
9197 pri
->pvts
[chanpos
]->dsp_features
= 0;
9200 pri
->pvts
[chanpos
]->progress
= 1;
9201 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9205 case PRI_EVENT_PROCEEDING
:
9206 chanpos
= pri_find_principle(pri
, e
->proceeding
.channel
);
9208 if (!pri
->pvts
[chanpos
]->proceeding
) {
9209 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_PROCEEDING
, };
9211 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9212 ast_log(LOG_DEBUG
, "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
9213 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
,pri
->span
);
9214 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
9215 #ifdef PRI_PROGRESS_MASK
9216 if (e
->proceeding
.progressmask
& PRI_PROG_INBAND_AVAILABLE
) {
9218 if (e
->proceeding
.progress
== 8) {
9220 /* Now we can do call progress detection */
9221 if (pri
->pvts
[chanpos
]->dsp
&& pri
->pvts
[chanpos
]->dsp_features
) {
9222 ast_dsp_set_features(pri
->pvts
[chanpos
]->dsp
, pri
->pvts
[chanpos
]->dsp_features
);
9223 pri
->pvts
[chanpos
]->dsp_features
= 0;
9225 /* Bring voice path up */
9226 f
.subclass
= AST_CONTROL_PROGRESS
;
9227 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
9229 pri
->pvts
[chanpos
]->proceeding
= 1;
9230 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9234 case PRI_EVENT_FACNAME
:
9235 chanpos
= pri_find_principle(pri
, e
->facname
.channel
);
9237 ast_log(LOG_WARNING
, "Facility Name requested on unconfigured channel %d/%d span %d\n",
9238 PRI_SPAN(e
->facname
.channel
), PRI_CHANNEL(e
->facname
.channel
), pri
->span
);
9240 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->facname
.call
);
9242 ast_log(LOG_WARNING
, "Facility Name requested on channel %d/%d not in use on span %d\n",
9243 PRI_SPAN(e
->facname
.channel
), PRI_CHANNEL(e
->facname
.channel
), pri
->span
);
9245 /* Re-use *69 field for PRI */
9246 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9247 ast_copy_string(pri
->pvts
[chanpos
]->lastcid_num
, e
->facname
.callingnum
, sizeof(pri
->pvts
[chanpos
]->lastcid_num
));
9248 ast_copy_string(pri
->pvts
[chanpos
]->lastcid_name
, e
->facname
.callingname
, sizeof(pri
->pvts
[chanpos
]->lastcid_name
));
9249 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needcallerid
=1;
9250 dahdi_enable_ec(pri
->pvts
[chanpos
]);
9251 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9255 case PRI_EVENT_ANSWER
:
9256 chanpos
= pri_find_principle(pri
, e
->answer
.channel
);
9258 ast_log(LOG_WARNING
, "Answer on unconfigured channel %d/%d span %d\n",
9259 PRI_SPAN(e
->answer
.channel
), PRI_CHANNEL(e
->answer
.channel
), pri
->span
);
9261 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->answer
.call
);
9263 ast_log(LOG_WARNING
, "Answer requested on channel %d/%d not in use on span %d\n",
9264 PRI_SPAN(e
->answer
.channel
), PRI_CHANNEL(e
->answer
.channel
), pri
->span
);
9266 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9267 /* Now we can do call progress detection */
9269 /* We changed this so it turns on the DSP no matter what... progress or no progress.
9270 * By this time, we need DTMF detection and other features that were previously disabled
9272 if (pri
->pvts
[chanpos
]->dsp
&& pri
->pvts
[chanpos
]->dsp_features
) {
9273 ast_dsp_set_features(pri
->pvts
[chanpos
]->dsp
, pri
->pvts
[chanpos
]->dsp_features
);
9274 pri
->pvts
[chanpos
]->dsp_features
= 0;
9276 if (pri
->pvts
[chanpos
]->realcall
&& (pri
->pvts
[chanpos
]->realcall
->sig
== SIG_FXSKS
)) {
9277 ast_log(LOG_DEBUG
, "Starting up GR-303 trunk now that we got CONNECT...\n");
9279 res
= ioctl(pri
->pvts
[chanpos
]->subs
[SUB_REAL
].dfd
, DAHDI_HOOK
, &x
);
9281 if (errno
!= EINPROGRESS
) {
9282 ast_log(LOG_WARNING
, "Unable to start channel: %s\n", strerror(errno
));
9285 } else if (!ast_strlen_zero(pri
->pvts
[chanpos
]->dop
.dialstr
)) {
9286 pri
->pvts
[chanpos
]->dialing
= 1;
9287 /* Send any "w" waited stuff */
9288 res
= ioctl(pri
->pvts
[chanpos
]->subs
[SUB_REAL
].dfd
, DAHDI_DIAL
, &pri
->pvts
[chanpos
]->dop
);
9290 ast_log(LOG_WARNING
, "Unable to initiate dialing on trunk channel %d: %s\n", pri
->pvts
[chanpos
]->channel
, strerror(errno
));
9291 pri
->pvts
[chanpos
]->dop
.dialstr
[0] = '\0';
9293 ast_log(LOG_DEBUG
, "Sent deferred digit string: %s\n", pri
->pvts
[chanpos
]->dop
.dialstr
);
9294 pri
->pvts
[chanpos
]->dop
.dialstr
[0] = '\0';
9295 } else if (pri
->pvts
[chanpos
]->confirmanswer
) {
9296 ast_log(LOG_DEBUG
, "Waiting on answer confirmation on channel %d!\n", pri
->pvts
[chanpos
]->channel
);
9298 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needanswer
=1;
9299 /* Enable echo cancellation if it's not on already */
9300 dahdi_enable_ec(pri
->pvts
[chanpos
]);
9303 #ifdef SUPPORT_USERUSER
9304 if (!ast_strlen_zero(e
->answer
.useruserinfo
)) {
9305 struct ast_channel
*owner
= pri
->pvts
[chanpos
]->owner
;
9306 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9307 pbx_builtin_setvar_helper(owner
, "USERUSERINFO", e
->answer
.useruserinfo
);
9308 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9312 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9316 case PRI_EVENT_HANGUP
:
9317 chanpos
= pri_find_principle(pri
, e
->hangup
.channel
);
9319 ast_log(LOG_WARNING
, "Hangup requested on unconfigured channel %d/%d span %d\n",
9320 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9322 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->hangup
.call
);
9324 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9325 if (!pri
->pvts
[chanpos
]->alreadyhungup
) {
9326 /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */
9327 pri
->pvts
[chanpos
]->alreadyhungup
= 1;
9328 if (pri
->pvts
[chanpos
]->realcall
)
9329 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
9330 else if (pri
->pvts
[chanpos
]->owner
) {
9331 /* Queue a BUSY instead of a hangup if our cause is appropriate */
9332 pri
->pvts
[chanpos
]->owner
->hangupcause
= e
->hangup
.cause
;
9333 if (pri
->pvts
[chanpos
]->owner
->_state
== AST_STATE_UP
)
9334 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9336 switch (e
->hangup
.cause
) {
9337 case PRI_CAUSE_USER_BUSY
:
9338 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needbusy
=1;
9340 case PRI_CAUSE_CALL_REJECTED
:
9341 case PRI_CAUSE_NETWORK_OUT_OF_ORDER
:
9342 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
:
9343 case PRI_CAUSE_SWITCH_CONGESTION
:
9344 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER
:
9345 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE
:
9346 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needcongestion
=1;
9349 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9353 if (option_verbose
> 2)
9354 ast_verbose(VERBOSE_PREFIX_3
"Channel %d/%d, span %d got hangup, cause %d\n",
9355 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
, e
->hangup
.cause
);
9357 pri_hangup(pri
->pri
, pri
->pvts
[chanpos
]->call
, e
->hangup
.cause
);
9358 pri
->pvts
[chanpos
]->call
= NULL
;
9360 if (e
->hangup
.cause
== PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
) {
9361 if (option_verbose
> 2)
9362 ast_verbose(VERBOSE_PREFIX_3
"Forcing restart of channel %d/%d on span %d since channel reported in use\n",
9363 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9364 pri_reset(pri
->pri
, PVT_TO_CHANNEL(pri
->pvts
[chanpos
]));
9365 pri
->pvts
[chanpos
]->resetting
= 1;
9367 if (e
->hangup
.aoc_units
> -1)
9368 if (option_verbose
> 2)
9369 ast_verbose(VERBOSE_PREFIX_3
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
9370 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
, (int)e
->hangup
.aoc_units
, (e
->hangup
.aoc_units
== 1) ? "" : "s");
9372 #ifdef SUPPORT_USERUSER
9373 if (pri
->pvts
[chanpos
]->owner
&& !ast_strlen_zero(e
->hangup
.useruserinfo
)) {
9374 struct ast_channel
*owner
= pri
->pvts
[chanpos
]->owner
;
9375 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9376 pbx_builtin_setvar_helper(owner
, "USERUSERINFO", e
->hangup
.useruserinfo
);
9377 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9381 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9383 ast_log(LOG_WARNING
, "Hangup on bad channel %d/%d on span %d\n",
9384 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9388 #ifndef PRI_EVENT_HANGUP_REQ
9389 #error please update libpri
9391 case PRI_EVENT_HANGUP_REQ
:
9392 chanpos
= pri_find_principle(pri
, e
->hangup
.channel
);
9394 ast_log(LOG_WARNING
, "Hangup REQ requested on unconfigured channel %d/%d span %d\n",
9395 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9397 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->hangup
.call
);
9399 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9400 if (pri
->pvts
[chanpos
]->realcall
)
9401 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
9402 else if (pri
->pvts
[chanpos
]->owner
) {
9403 pri
->pvts
[chanpos
]->owner
->hangupcause
= e
->hangup
.cause
;
9404 if (pri
->pvts
[chanpos
]->owner
->_state
== AST_STATE_UP
)
9405 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9407 switch (e
->hangup
.cause
) {
9408 case PRI_CAUSE_USER_BUSY
:
9409 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needbusy
=1;
9411 case PRI_CAUSE_CALL_REJECTED
:
9412 case PRI_CAUSE_NETWORK_OUT_OF_ORDER
:
9413 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
:
9414 case PRI_CAUSE_SWITCH_CONGESTION
:
9415 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER
:
9416 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE
:
9417 pri
->pvts
[chanpos
]->subs
[SUB_REAL
].needcongestion
=1;
9420 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9423 if (option_verbose
> 2)
9424 ast_verbose(VERBOSE_PREFIX_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
);
9425 if (e
->hangup
.aoc_units
> -1)
9426 if (option_verbose
> 2)
9427 ast_verbose(VERBOSE_PREFIX_3
"Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
9428 pri
->pvts
[chanpos
]->logicalspan
, pri
->pvts
[chanpos
]->prioffset
, pri
->span
, (int)e
->hangup
.aoc_units
, (e
->hangup
.aoc_units
== 1) ? "" : "s");
9430 pri_hangup(pri
->pri
, pri
->pvts
[chanpos
]->call
, e
->hangup
.cause
);
9431 pri
->pvts
[chanpos
]->call
= NULL
;
9433 if (e
->hangup
.cause
== PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
) {
9434 if (option_verbose
> 2)
9435 ast_verbose(VERBOSE_PREFIX_3
"Forcing restart of channel %d/%d span %d since channel reported in use\n",
9436 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9437 pri_reset(pri
->pri
, PVT_TO_CHANNEL(pri
->pvts
[chanpos
]));
9438 pri
->pvts
[chanpos
]->resetting
= 1;
9441 #ifdef SUPPORT_USERUSER
9442 if (!ast_strlen_zero(e
->hangup
.useruserinfo
)) {
9443 struct ast_channel
*owner
= pri
->pvts
[chanpos
]->owner
;
9444 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9445 pbx_builtin_setvar_helper(owner
, "USERUSERINFO", e
->hangup
.useruserinfo
);
9446 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9450 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9452 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
);
9456 case PRI_EVENT_HANGUP_ACK
:
9457 chanpos
= pri_find_principle(pri
, e
->hangup
.channel
);
9459 ast_log(LOG_WARNING
, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n",
9460 PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9462 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->hangup
.call
);
9464 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9465 pri
->pvts
[chanpos
]->call
= NULL
;
9466 pri
->pvts
[chanpos
]->resetting
= 0;
9467 if (pri
->pvts
[chanpos
]->owner
) {
9468 if (option_verbose
> 2)
9469 ast_verbose(VERBOSE_PREFIX_3
"Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e
->hangup
.channel
), PRI_CHANNEL(e
->hangup
.channel
), pri
->span
);
9472 #ifdef SUPPORT_USERUSER
9473 if (!ast_strlen_zero(e
->hangup
.useruserinfo
)) {
9474 struct ast_channel
*owner
= pri
->pvts
[chanpos
]->owner
;
9475 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9476 pbx_builtin_setvar_helper(owner
, "USERUSERINFO", e
->hangup
.useruserinfo
);
9477 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9481 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9485 case PRI_EVENT_CONFIG_ERR
:
9486 ast_log(LOG_WARNING
, "PRI Error on span %d: %s\n", pri
->trunkgroup
, e
->err
.err
);
9488 case PRI_EVENT_RESTART_ACK
:
9489 chanpos
= pri_find_principle(pri
, e
->restartack
.channel
);
9491 /* Sometime switches (e.g. I421 / British Telecom) don't give us the
9492 channel number, so we have to figure it out... This must be why
9493 everybody resets exactly a channel at a time. */
9494 for (x
= 0; x
< pri
->numchans
; x
++) {
9495 if (pri
->pvts
[x
] && pri
->pvts
[x
]->resetting
) {
9497 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9498 ast_log(LOG_DEBUG
, "Assuming restart ack is really for channel %d/%d span %d\n", pri
->pvts
[chanpos
]->logicalspan
,
9499 pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9500 if (pri
->pvts
[chanpos
]->realcall
)
9501 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
9502 else if (pri
->pvts
[chanpos
]->owner
) {
9503 ast_log(LOG_WARNING
, "Got restart ack on channel %d/%d with owner on span %d\n", pri
->pvts
[chanpos
]->logicalspan
,
9504 pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9505 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9507 pri
->pvts
[chanpos
]->resetting
= 0;
9508 if (option_verbose
> 2)
9509 ast_verbose(VERBOSE_PREFIX_3
"B-channel %d/%d successfully restarted on span %d\n", pri
->pvts
[chanpos
]->logicalspan
,
9510 pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9511 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9513 pri_check_restart(pri
);
9518 ast_log(LOG_WARNING
, "Restart ACK requested on strange channel %d/%d span %d\n",
9519 PRI_SPAN(e
->restartack
.channel
), PRI_CHANNEL(e
->restartack
.channel
), pri
->span
);
9522 if (pri
->pvts
[chanpos
]) {
9523 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9524 if (pri
->pvts
[chanpos
]->realcall
)
9525 pri_hangup_all(pri
->pvts
[chanpos
]->realcall
, pri
);
9526 else if (pri
->pvts
[chanpos
]->owner
) {
9527 ast_log(LOG_WARNING
, "Got restart ack on channel %d/%d span %d with owner\n",
9528 PRI_SPAN(e
->restartack
.channel
), PRI_CHANNEL(e
->restartack
.channel
), pri
->span
);
9529 pri
->pvts
[chanpos
]->owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
9531 pri
->pvts
[chanpos
]->resetting
= 0;
9532 if (option_verbose
> 2)
9533 ast_verbose(VERBOSE_PREFIX_3
"B-channel %d/%d successfully restarted on span %d\n", pri
->pvts
[chanpos
]->logicalspan
,
9534 pri
->pvts
[chanpos
]->prioffset
, pri
->span
);
9535 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9537 pri_check_restart(pri
);
9541 case PRI_EVENT_SETUP_ACK
:
9542 chanpos
= pri_find_principle(pri
, e
->setup_ack
.channel
);
9544 ast_log(LOG_WARNING
, "Received SETUP_ACKNOWLEDGE on unconfigured channel %d/%d span %d\n",
9545 PRI_SPAN(e
->setup_ack
.channel
), PRI_CHANNEL(e
->setup_ack
.channel
), pri
->span
);
9547 chanpos
= pri_fixup_principle(pri
, chanpos
, e
->setup_ack
.call
);
9549 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9550 pri
->pvts
[chanpos
]->setup_ack
= 1;
9551 /* Send any queued digits */
9552 for (x
= 0;x
< strlen(pri
->pvts
[chanpos
]->dialdest
); x
++) {
9553 ast_log(LOG_DEBUG
, "Sending pending digit '%c'\n", pri
->pvts
[chanpos
]->dialdest
[x
]);
9554 pri_information(pri
->pri
, pri
->pvts
[chanpos
]->call
,
9555 pri
->pvts
[chanpos
]->dialdest
[x
]);
9557 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9559 ast_log(LOG_WARNING
, "Unable to move channel %d!\n", e
->setup_ack
.channel
);
9562 case PRI_EVENT_NOTIFY
:
9563 chanpos
= pri_find_principle(pri
, e
->notify
.channel
);
9565 ast_log(LOG_WARNING
, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
9566 PRI_SPAN(e
->notify
.channel
), PRI_CHANNEL(e
->notify
.channel
), pri
->span
);
9568 struct ast_frame f
= { AST_FRAME_CONTROL
, };
9569 ast_mutex_lock(&pri
->pvts
[chanpos
]->lock
);
9570 switch (e
->notify
.info
) {
9571 case PRI_NOTIFY_REMOTE_HOLD
:
9572 f
.subclass
= AST_CONTROL_HOLD
;
9573 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
9575 case PRI_NOTIFY_REMOTE_RETRIEVAL
:
9576 f
.subclass
= AST_CONTROL_UNHOLD
;
9577 dahdi_queue_frame(pri
->pvts
[chanpos
], &f
, pri
);
9580 ast_mutex_unlock(&pri
->pvts
[chanpos
]->lock
);
9584 ast_log(LOG_DEBUG
, "Event: %d\n", e
->e
);
9587 ast_mutex_unlock(&pri
->lock
);
9593 static int start_pri(struct dahdi_pri
*pri
)
9596 struct dahdi_params p
;
9597 struct dahdi_bufferinfo bi
;
9598 struct dahdi_spaninfo si
;
9601 for (i
= 0; i
< NUM_DCHANS
; i
++) {
9602 if (!pri
->dchannels
[i
])
9605 pri
->fds
[i
] = open("/dev/zap/channel", O_RDWR
, 0600);
9607 pri
->fds
[i
] = open("/dev/dahdi/channel", O_RDWR
, 0600);
9609 x
= pri
->dchannels
[i
];
9610 if ((pri
->fds
[i
] < 0) || (ioctl(pri
->fds
[i
],DAHDI_SPECIFY
,&x
) == -1)) {
9611 ast_log(LOG_ERROR
, "Unable to open D-channel %d (%s)\n", x
, strerror(errno
));
9614 res
= ioctl(pri
->fds
[i
], DAHDI_GET_PARAMS
, &p
);
9616 dahdi_close(pri
->fds
[i
]);
9618 ast_log(LOG_ERROR
, "Unable to get parameters for D-channel %d (%s)\n", x
, strerror(errno
));
9621 if ((p
.sigtype
!= DAHDI_SIG_HDLCFCS
) && (p
.sigtype
!= DAHDI_SIG_HARDHDLC
)) {
9622 dahdi_close(pri
->fds
[i
]);
9624 ast_log(LOG_ERROR
, "D-channel %d is not in HDLC/FCS mode. See /etc/DAHDI.conf\n", x
);
9627 memset(&si
, 0, sizeof(si
));
9628 res
= ioctl(pri
->fds
[i
], DAHDI_SPANSTAT
, &si
);
9630 dahdi_close(pri
->fds
[i
]);
9632 ast_log(LOG_ERROR
, "Unable to get span state for D-channel %d (%s)\n", x
, strerror(errno
));
9635 pri
->dchanavail
[i
] |= DCHAN_NOTINALARM
;
9637 pri
->dchanavail
[i
] &= ~DCHAN_NOTINALARM
;
9638 bi
.txbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
9639 bi
.rxbufpolicy
= DAHDI_POLICY_IMMEDIATE
;
9642 if (ioctl(pri
->fds
[i
], DAHDI_SET_BUFINFO
, &bi
)) {
9643 ast_log(LOG_ERROR
, "Unable to set appropriate buffering on channel %d: %s\n", x
, strerror(errno
));
9644 dahdi_close(pri
->fds
[i
]);
9648 pri
->dchans
[i
] = pri_new(pri
->fds
[i
], pri
->nodetype
, pri
->switchtype
);
9649 /* Force overlap dial if we're doing GR-303! */
9650 if (pri
->switchtype
== PRI_SWITCH_GR303_TMC
)
9651 pri
->overlapdial
= 1;
9652 pri_set_overlapdial(pri
->dchans
[i
],pri
->overlapdial
);
9653 #ifdef HAVE_PRI_INBANDDISCONNECT
9654 pri_set_inbanddisconnect(pri
->dchans
[i
], pri
->inbanddisconnect
);
9656 /* Enslave to master if appropriate */
9658 pri_enslave(pri
->dchans
[0], pri
->dchans
[i
]);
9659 if (!pri
->dchans
[i
]) {
9660 dahdi_close(pri
->fds
[i
]);
9662 ast_log(LOG_ERROR
, "Unable to create PRI structure\n");
9665 pri_set_debug(pri
->dchans
[i
], DEFAULT_PRI_DEBUG
);
9666 pri_set_nsf(pri
->dchans
[i
], pri
->nsf
);
9667 #ifdef PRI_GETSET_TIMERS
9668 for (x
= 0; x
< PRI_MAX_TIMERS
; x
++) {
9669 if (pritimers
[x
] != 0)
9670 pri_set_timer(pri
->dchans
[i
], x
, pritimers
[x
]);
9674 /* Assume primary is the one we use */
9675 pri
->pri
= pri
->dchans
[0];
9677 if (ast_pthread_create_background(&pri
->master
, NULL
, pri_dchannel
, pri
)) {
9678 for (i
= 0; i
< NUM_DCHANS
; i
++) {
9679 if (!pri
->dchannels
[i
])
9681 dahdi_close(pri
->fds
[i
]);
9684 ast_log(LOG_ERROR
, "Unable to spawn D-channel: %s\n", strerror(errno
));
9690 static char *complete_span_helper(const char *line
, const char *word
, int pos
, int state
, int rpos
)
9698 for (which
= span
= 0; span
< NUM_SPANS
; span
++) {
9699 if (pris
[span
].pri
&& ++which
> state
) {
9700 asprintf(&ret
, "%d", span
+ 1); /* user indexes start from 1 */
9707 static char *complete_span_4(const char *line
, const char *word
, int pos
, int state
)
9709 return complete_span_helper(line
,word
,pos
,state
,3);
9712 static char *complete_span_5(const char *line
, const char *word
, int pos
, int state
)
9714 return complete_span_helper(line
,word
,pos
,state
,4);
9717 static int handle_pri_set_debug_file(int fd
, int argc
, char **argv
)
9721 if (!strncasecmp(argv
[1], "set", 3)) {
9723 return RESULT_SHOWUSAGE
;
9725 if (ast_strlen_zero(argv
[4]))
9726 return RESULT_SHOWUSAGE
;
9728 myfd
= open(argv
[4], O_CREAT
|O_WRONLY
, 0600);
9730 ast_cli(fd
, "Unable to open '%s' for writing\n", argv
[4]);
9731 return RESULT_SUCCESS
;
9734 ast_mutex_lock(&pridebugfdlock
);
9736 if (pridebugfd
>= 0)
9740 ast_copy_string(pridebugfilename
,argv
[4],sizeof(pridebugfilename
));
9742 ast_mutex_unlock(&pridebugfdlock
);
9744 ast_cli(fd
, "PRI debug output will be sent to '%s'\n", argv
[4]);
9746 /* Assume it is unset */
9747 ast_mutex_lock(&pridebugfdlock
);
9750 ast_cli(fd
, "PRI debug output to file disabled\n");
9751 ast_mutex_unlock(&pridebugfdlock
);
9754 return RESULT_SUCCESS
;
9757 #ifdef HAVE_PRI_VERSION
9758 static int handle_pri_version(int fd
, int agc
, char *argv
[]) {
9759 ast_cli(fd
, "libpri version: %s\n", pri_get_version());
9760 return RESULT_SUCCESS
;
9764 static int handle_pri_debug(int fd
, int argc
, char *argv
[])
9769 return RESULT_SHOWUSAGE
;
9771 span
= atoi(argv
[3]);
9772 if ((span
< 1) || (span
> NUM_SPANS
)) {
9773 ast_cli(fd
, "Invalid span %s. Should be a number %d to %d\n", argv
[3], 1, NUM_SPANS
);
9774 return RESULT_SUCCESS
;
9776 if (!pris
[span
-1].pri
) {
9777 ast_cli(fd
, "No PRI running on span %d\n", span
);
9778 return RESULT_SUCCESS
;
9780 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9781 if (pris
[span
-1].dchans
[x
])
9782 pri_set_debug(pris
[span
-1].dchans
[x
], PRI_DEBUG_APDU
|
9783 PRI_DEBUG_Q931_DUMP
| PRI_DEBUG_Q931_STATE
|
9784 PRI_DEBUG_Q921_STATE
);
9786 ast_cli(fd
, "Enabled debugging on span %d\n", span
);
9787 return RESULT_SUCCESS
;
9792 static int handle_pri_no_debug(int fd
, int argc
, char *argv
[])
9797 return RESULT_SHOWUSAGE
;
9798 span
= atoi(argv
[4]);
9799 if ((span
< 1) || (span
> NUM_SPANS
)) {
9800 ast_cli(fd
, "Invalid span %s. Should be a number %d to %d\n", argv
[4], 1, NUM_SPANS
);
9801 return RESULT_SUCCESS
;
9803 if (!pris
[span
-1].pri
) {
9804 ast_cli(fd
, "No PRI running on span %d\n", span
);
9805 return RESULT_SUCCESS
;
9807 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9808 if (pris
[span
-1].dchans
[x
])
9809 pri_set_debug(pris
[span
-1].dchans
[x
], 0);
9811 ast_cli(fd
, "Disabled debugging on span %d\n", span
);
9812 return RESULT_SUCCESS
;
9815 static int handle_pri_really_debug(int fd
, int argc
, char *argv
[])
9820 return RESULT_SHOWUSAGE
;
9821 span
= atoi(argv
[4]);
9822 if ((span
< 1) || (span
> NUM_SPANS
)) {
9823 ast_cli(fd
, "Invalid span %s. Should be a number %d to %d\n", argv
[4], 1, NUM_SPANS
);
9824 return RESULT_SUCCESS
;
9826 if (!pris
[span
-1].pri
) {
9827 ast_cli(fd
, "No PRI running on span %d\n", span
);
9828 return RESULT_SUCCESS
;
9830 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9831 if (pris
[span
-1].dchans
[x
])
9832 pri_set_debug(pris
[span
-1].dchans
[x
], PRI_DEBUG_APDU
|
9833 PRI_DEBUG_Q931_DUMP
| PRI_DEBUG_Q931_STATE
|
9834 PRI_DEBUG_Q921_RAW
| PRI_DEBUG_Q921_DUMP
| PRI_DEBUG_Q921_STATE
);
9836 ast_cli(fd
, "Enabled EXTENSIVE debugging on span %d\n", span
);
9837 return RESULT_SUCCESS
;
9840 static void build_status(char *s
, size_t len
, int status
, int active
)
9842 if (!s
|| len
< 1) {
9846 if (status
& DCHAN_PROVISIONED
)
9847 strncat(s
, "Provisioned, ", len
- strlen(s
) - 1);
9848 if (!(status
& DCHAN_NOTINALARM
))
9849 strncat(s
, "In Alarm, ", len
- strlen(s
) - 1);
9850 if (status
& DCHAN_UP
)
9851 strncat(s
, "Up", len
- strlen(s
) - 1);
9853 strncat(s
, "Down", len
- strlen(s
) - 1);
9855 strncat(s
, ", Active", len
- strlen(s
) - 1);
9857 strncat(s
, ", Standby", len
- strlen(s
) - 1);
9861 static int handle_pri_show_spans(int fd
, int argc
, char *argv
[])
9867 return RESULT_SHOWUSAGE
;
9869 for (span
= 0; span
< NUM_SPANS
; span
++) {
9870 if (pris
[span
].pri
) {
9871 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9872 if (pris
[span
].dchannels
[x
]) {
9873 build_status(status
, sizeof(status
), pris
[span
].dchanavail
[x
], pris
[span
].dchans
[x
] == pris
[span
].pri
);
9874 ast_cli(fd
, "PRI span %d/%d: %s\n", span
+ 1, x
, status
);
9879 return RESULT_SUCCESS
;
9882 static int handle_pri_show_span(int fd
, int argc
, char *argv
[])
9888 return RESULT_SHOWUSAGE
;
9889 span
= atoi(argv
[3]);
9890 if ((span
< 1) || (span
> NUM_SPANS
)) {
9891 ast_cli(fd
, "Invalid span '%s'. Should be a number from %d to %d\n", argv
[3], 1, NUM_SPANS
);
9892 return RESULT_SUCCESS
;
9894 if (!pris
[span
-1].pri
) {
9895 ast_cli(fd
, "No PRI running on span %d\n", span
);
9896 return RESULT_SUCCESS
;
9898 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9899 if (pris
[span
-1].dchannels
[x
]) {
9900 #ifdef PRI_DUMP_INFO_STR
9901 char *info_str
= NULL
;
9903 ast_cli(fd
, "%s D-channel: %d\n", pri_order(x
), pris
[span
-1].dchannels
[x
]);
9904 build_status(status
, sizeof(status
), pris
[span
-1].dchanavail
[x
], pris
[span
-1].dchans
[x
] == pris
[span
-1].pri
);
9905 ast_cli(fd
, "Status: %s\n", status
);
9906 #ifdef PRI_DUMP_INFO_STR
9907 info_str
= pri_dump_info_str(pris
[span
-1].pri
);
9909 ast_cli(fd
, "%s", info_str
);
9913 pri_dump_info(pris
[span
-1].pri
);
9918 return RESULT_SUCCESS
;
9921 static int handle_pri_show_debug(int fd
, int argc
, char *argv
[])
9928 for (span
= 0; span
< NUM_SPANS
; span
++) {
9929 if (pris
[span
].pri
) {
9930 for (x
= 0; x
< NUM_DCHANS
; x
++) {
9932 if (pris
[span
].dchans
[x
]) {
9933 debug
= pri_get_debug(pris
[span
].dchans
[x
]);
9934 ast_cli(fd
, "Span %d: Debug: %s\tIntense: %s\n", span
+1, (debug
&PRI_DEBUG_Q931_STATE
)? "Yes" : "No" ,(debug
&PRI_DEBUG_Q921_RAW
)? "Yes" : "No" );
9941 ast_mutex_lock(&pridebugfdlock
);
9942 if (pridebugfd
>= 0)
9943 ast_cli(fd
, "Logging PRI debug to file %s\n", pridebugfilename
);
9944 ast_mutex_unlock(&pridebugfdlock
);
9947 ast_cli(fd
, "No debug set or no PRI running\n");
9948 return RESULT_SUCCESS
;
9951 static const char pri_debug_help
[] =
9952 "Usage: pri debug span <span>\n"
9953 " Enables debugging on a given PRI span\n";
9955 static const char pri_no_debug_help
[] =
9956 "Usage: pri no debug span <span>\n"
9957 " Disables debugging on a given PRI span\n";
9959 static const char pri_really_debug_help
[] =
9960 "Usage: pri intensive debug span <span>\n"
9961 " Enables debugging down to the Q.921 level\n";
9963 static const char pri_show_span_help
[] =
9964 "Usage: pri show span <span>\n"
9965 " Displays PRI Information on a given PRI span\n";
9967 static const char pri_show_spans_help
[] =
9968 "Usage: pri show spans\n"
9969 " Displays PRI Information\n";
9971 static struct ast_cli_entry dahdi_pri_cli
[] = {
9972 { { "pri", "debug", "span", NULL
},
9973 handle_pri_debug
, "Enables PRI debugging on a span",
9974 pri_debug_help
, complete_span_4
},
9976 { { "pri", "no", "debug", "span", NULL
},
9977 handle_pri_no_debug
, "Disables PRI debugging on a span",
9978 pri_no_debug_help
, complete_span_5
},
9980 { { "pri", "intense", "debug", "span", NULL
},
9981 handle_pri_really_debug
, "Enables REALLY INTENSE PRI debugging",
9982 pri_really_debug_help
, complete_span_5
},
9984 { { "pri", "show", "spans", NULL
},
9985 handle_pri_show_spans
, "Displays PRI Information",
9986 pri_show_spans_help
},
9988 { { "pri", "show", "span", NULL
},
9989 handle_pri_show_span
, "Displays PRI Information",
9990 pri_show_span_help
, complete_span_4
},
9992 { { "pri", "show", "debug", NULL
},
9993 handle_pri_show_debug
, "Displays current PRI debug settings" },
9995 { { "pri", "set", "debug", "file", NULL
},
9996 handle_pri_set_debug_file
, "Sends PRI debug output to the specified file" },
9998 { { "pri", "unset", "debug", "file", NULL
},
9999 handle_pri_set_debug_file
, "Ends PRI debug output to file" },
10001 #ifdef HAVE_PRI_VERSION
10002 { { "pri", "show", "version", NULL
},
10003 handle_pri_version
, "Displays version of libpri" },
10007 #endif /* HAVE_PRI */
10009 static int dahdi_destroy_channel(int fd
, int argc
, char **argv
)
10014 return RESULT_SHOWUSAGE
;
10016 channel
= atoi(argv
[3]);
10018 return dahdi_destroy_channel_bynum(channel
);
10021 static void dahdi_softhangup_all(void)
10023 struct dahdi_pvt
*p
;
10025 ast_mutex_lock(&iflock
);
10026 for (p
= iflist
; p
; p
= p
->next
) {
10027 ast_mutex_lock(&p
->lock
);
10028 if (p
->owner
&& !p
->restartpending
) {
10029 if (ast_channel_trylock(p
->owner
)) {
10030 if (option_debug
> 2)
10031 ast_verbose("Avoiding deadlock\n");
10032 /* Avoid deadlock since you're not supposed to lock iflock or pvt before a channel */
10033 ast_mutex_unlock(&p
->lock
);
10034 ast_mutex_unlock(&iflock
);
10037 if (option_debug
> 2)
10038 ast_verbose("Softhanging up on %s\n", p
->owner
->name
);
10039 ast_softhangup_nolock(p
->owner
, AST_SOFTHANGUP_EXPLICIT
);
10040 p
->restartpending
= 1;
10041 num_restart_pending
++;
10042 ast_channel_unlock(p
->owner
);
10044 ast_mutex_unlock(&p
->lock
);
10046 ast_mutex_unlock(&iflock
);
10049 static int setup_dahdi(int reload
);
10050 static int dahdi_restart(void)
10052 int i
, j
, cancel_code
;
10053 struct dahdi_pvt
*p
;
10055 ast_mutex_lock(&restart_lock
);
10057 if (option_verbose
)
10058 ast_verbose("Destroying channels and reloading DAHDI configuration.\n");
10059 dahdi_softhangup_all();
10060 if (option_verbose
> 3)
10061 ast_verbose("Initial softhangup of all DAHDI channels complete.\n");
10063 #if defined(HAVE_PRI)
10064 for (i
= 0; i
< NUM_SPANS
; i
++) {
10065 if (pris
[i
].master
&& (pris
[i
].master
!= AST_PTHREADT_NULL
)) {
10066 cancel_code
= pthread_cancel(pris
[i
].master
);
10067 pthread_kill(pris
[i
].master
, SIGURG
);
10068 if (option_debug
> 3)
10069 ast_verbose("Waiting to join thread of span %d with pid=%p, cancel_code=%d\n", i
, (void *) pris
[i
].master
, cancel_code
);
10070 pthread_join(pris
[i
].master
, NULL
);
10071 if (option_debug
> 3)
10072 ast_verbose("Joined thread of span %d\n", i
);
10077 ast_mutex_lock(&monlock
);
10078 if (monitor_thread
&& (monitor_thread
!= AST_PTHREADT_STOP
) && (monitor_thread
!= AST_PTHREADT_NULL
)) {
10079 cancel_code
= pthread_cancel(monitor_thread
);
10080 pthread_kill(monitor_thread
, SIGURG
);
10081 if (option_debug
> 3)
10082 ast_verbose("Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (void *) monitor_thread
, cancel_code
);
10083 pthread_join(monitor_thread
, NULL
);
10084 if (option_debug
> 3)
10085 ast_verbose("Joined monitor thread\n");
10087 monitor_thread
= AST_PTHREADT_NULL
; /* prepare to restart thread in setup_dahdi once channels are reconfigured */
10089 ast_mutex_lock(&ss_thread_lock
);
10090 while (ss_thread_count
> 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
10091 int x
= DAHDI_FLASH
;
10092 if (option_debug
> 2)
10093 ast_verbose("Waiting on %d ss_thread(s) to finish\n", ss_thread_count
);
10095 for (p
= iflist
; p
; p
= p
->next
) {
10097 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 */
10099 ast_cond_wait(&ss_thread_complete
, &ss_thread_lock
);
10102 /* ensure any created channels before monitor threads were stopped are hungup */
10103 dahdi_softhangup_all();
10104 if (option_verbose
> 3)
10105 ast_verbose("Final softhangup of all DAHDI channels complete.\n");
10106 destroy_all_channels();
10108 ast_verbose("Channels destroyed. Now re-reading config. %d active channels remaining.\n", ast_active_channels());
10110 ast_mutex_unlock(&monlock
);
10113 for (i
= 0; i
< NUM_SPANS
; i
++) {
10114 for (j
= 0; j
< NUM_DCHANS
; j
++)
10115 dahdi_close(pris
[i
].fds
[j
]);
10118 memset(pris
, 0, sizeof(pris
));
10119 for (i
= 0; i
< NUM_SPANS
; i
++) {
10120 ast_mutex_init(&pris
[i
].lock
);
10121 pris
[i
].offset
= -1;
10122 pris
[i
].master
= AST_PTHREADT_NULL
;
10123 for (j
= 0; j
< NUM_DCHANS
; j
++)
10124 pris
[i
].fds
[j
] = -1;
10126 pri_set_error(dahdi_pri_error
);
10127 pri_set_message(dahdi_pri_message
);
10130 if (setup_dahdi(2) != 0) {
10131 ast_log(LOG_WARNING
, "Reload channels from dahdi config failed!\n");
10132 ast_mutex_unlock(&ss_thread_lock
);
10135 ast_mutex_unlock(&ss_thread_lock
);
10136 ast_mutex_unlock(&restart_lock
);
10140 static int dahdi_restart_cmd(int fd
, int argc
, char **argv
)
10143 return RESULT_SHOWUSAGE
;
10146 if (dahdi_restart() != 0)
10147 return RESULT_FAILURE
;
10148 return RESULT_SUCCESS
;
10151 static int dahdi_show_channels(int fd
, int argc
, char **argv
)
10153 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
10154 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s\n"
10155 struct dahdi_pvt
*tmp
= NULL
;
10156 char tmps
[20] = "";
10158 struct dahdi_pvt
*start
;
10161 struct dahdi_pri
*pri
= NULL
;
10170 if ((trunkgroup
= atoi(argv
[3])) < 1)
10171 return RESULT_SHOWUSAGE
;
10172 for (x
= 0; x
< NUM_SPANS
; x
++) {
10173 if (pris
[x
].trunkgroup
== trunkgroup
) {
10182 ast_cli(fd
, "No such trunk group %d\n", trunkgroup
);
10183 return RESULT_FAILURE
;
10188 return RESULT_SHOWUSAGE
;
10190 ast_mutex_lock(lock
);
10192 ast_cli(fd
, FORMAT2
, pri
? "CRV" : "Chan", "Extension", "Context", "Language", "MOH Interpret");
10194 ast_cli(fd
, FORMAT2
, "Chan", "Extension", "Context", "Language", "MOH Interpret");
10199 if (tmp
->channel
> 0) {
10200 snprintf(tmps
, sizeof(tmps
), "%d", tmp
->channel
);
10202 ast_copy_string(tmps
, "pseudo", sizeof(tmps
));
10203 ast_cli(fd
, FORMAT
, tmps
, tmp
->exten
, tmp
->context
, tmp
->language
, tmp
->mohinterpret
);
10206 ast_mutex_unlock(lock
);
10207 return RESULT_SUCCESS
;
10212 static int dahdi_show_channel(int fd
, int argc
, char **argv
)
10215 struct dahdi_pvt
*tmp
= NULL
;
10216 struct dahdi_confinfo ci
;
10217 struct dahdi_params ps
;
10220 struct dahdi_pvt
*start
;
10224 struct dahdi_pri
*pri
=NULL
;
10231 return RESULT_SHOWUSAGE
;
10233 if ((c
= strchr(argv
[3], ':'))) {
10234 if (sscanf(argv
[3], "%d:%d", &trunkgroup
, &channel
) != 2)
10235 return RESULT_SHOWUSAGE
;
10236 if ((trunkgroup
< 1) || (channel
< 1))
10237 return RESULT_SHOWUSAGE
;
10238 for (x
= 0; x
< NUM_SPANS
; x
++) {
10239 if (pris
[x
].trunkgroup
== trunkgroup
) {
10248 ast_cli(fd
, "No such trunk group %d\n", trunkgroup
);
10249 return RESULT_FAILURE
;
10253 channel
= atoi(argv
[3]);
10255 ast_mutex_lock(lock
);
10258 if (tmp
->channel
== channel
) {
10261 ast_cli(fd
, "Trunk/CRV: %d/%d\n", trunkgroup
, tmp
->channel
);
10264 ast_cli(fd
, "Channel: %d\n", tmp
->channel
);
10265 ast_cli(fd
, "File Descriptor: %d\n", tmp
->subs
[SUB_REAL
].dfd
);
10266 ast_cli(fd
, "Span: %d\n", tmp
->span
);
10267 ast_cli(fd
, "Extension: %s\n", tmp
->exten
);
10268 ast_cli(fd
, "Dialing: %s\n", tmp
->dialing
? "yes" : "no");
10269 ast_cli(fd
, "Context: %s\n", tmp
->context
);
10270 ast_cli(fd
, "Caller ID: %s\n", tmp
->cid_num
);
10271 ast_cli(fd
, "Calling TON: %d\n", tmp
->cid_ton
);
10272 ast_cli(fd
, "Caller ID name: %s\n", tmp
->cid_name
);
10273 ast_cli(fd
, "Destroy: %d\n", tmp
->destroy
);
10274 ast_cli(fd
, "InAlarm: %d\n", tmp
->inalarm
);
10275 ast_cli(fd
, "Signalling Type: %s\n", sig2str(tmp
->sig
));
10276 ast_cli(fd
, "Radio: %d\n", tmp
->radio
);
10277 ast_cli(fd
, "Owner: %s\n", tmp
->owner
? tmp
->owner
->name
: "<None>");
10278 ast_cli(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)" : "");
10279 ast_cli(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)" : "");
10280 ast_cli(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)" : "");
10281 ast_cli(fd
, "Confno: %d\n", tmp
->confno
);
10282 ast_cli(fd
, "Propagated Conference: %d\n", tmp
->propconfno
);
10283 ast_cli(fd
, "Real in conference: %d\n", tmp
->inconference
);
10284 ast_cli(fd
, "DSP: %s\n", tmp
->dsp
? "yes" : "no");
10285 ast_cli(fd
, "Relax DTMF: %s\n", tmp
->dtmfrelax
? "yes" : "no");
10286 ast_cli(fd
, "Dialing/CallwaitCAS: %d/%d\n", tmp
->dialing
, tmp
->callwaitcas
);
10287 ast_cli(fd
, "Default law: %s\n", tmp
->law
== DAHDI_LAW_MULAW
? "ulaw" : tmp
->law
== DAHDI_LAW_ALAW
? "alaw" : "unknown");
10288 ast_cli(fd
, "Fax Handled: %s\n", tmp
->faxhandled
? "yes" : "no");
10289 ast_cli(fd
, "Pulse phone: %s\n", tmp
->pulsedial
? "yes" : "no");
10290 ast_cli(fd
, "Echo Cancellation: %d taps%s, currently %s\n", tmp
->echocancel
, tmp
->echocanbridged
? "" : " unless TDM bridged", tmp
->echocanon
? "ON" : "OFF");
10292 ast_cli(fd
, "Master Channel: %d\n", tmp
->master
->channel
);
10293 for (x
= 0; x
< MAX_SLAVES
; x
++) {
10294 if (tmp
->slaves
[x
])
10295 ast_cli(fd
, "Slave Channel: %d\n", tmp
->slaves
[x
]->channel
);
10299 ast_cli(fd
, "PRI Flags: ");
10300 if (tmp
->resetting
)
10301 ast_cli(fd
, "Resetting ");
10303 ast_cli(fd
, "Call ");
10305 ast_cli(fd
, "Bearer ");
10307 if (tmp
->logicalspan
)
10308 ast_cli(fd
, "PRI Logical Span: %d\n", tmp
->logicalspan
);
10310 ast_cli(fd
, "PRI Logical Span: Implicit\n");
10314 memset(&ci
, 0, sizeof(ci
));
10315 ps
.channo
= tmp
->channel
;
10316 if (tmp
->subs
[SUB_REAL
].dfd
> -1) {
10317 if (!ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GETCONF
, &ci
)) {
10318 ast_cli(fd
, "Actual Confinfo: Num/%d, Mode/0x%04x\n", ci
.confno
, ci
.confmode
);
10320 #ifdef DAHDI_GETCONFMUTE
10321 if (!ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GETCONFMUTE
, &x
)) {
10322 ast_cli(fd
, "Actual Confmute: %s\n", x
? "Yes" : "No");
10325 if (ioctl(tmp
->subs
[SUB_REAL
].dfd
, DAHDI_GET_PARAMS
, &ps
) < 0) {
10326 ast_log(LOG_WARNING
, "Failed to get parameters on channel %d: %s\n", tmp
->channel
, strerror(errno
));
10328 ast_cli(fd
, "Hookstate (FXS only): %s\n", ps
.rxisoffhook
? "Offhook" : "Onhook");
10331 ast_mutex_unlock(lock
);
10332 return RESULT_SUCCESS
;
10337 ast_cli(fd
, "Unable to find given channel %d\n", channel
);
10338 ast_mutex_unlock(lock
);
10339 return RESULT_FAILURE
;
10342 static char dahdi_show_cadences_usage
[] =
10343 "Usage: dahdi show cadences\n"
10344 " Shows all cadences currently defined\n";
10346 static int handle_dahdi_show_cadences(int fd
, int argc
, char *argv
[])
10349 for (i
= 0; i
< num_cadence
; i
++) {
10351 char tmp
[16], tmp2
[64];
10352 snprintf(tmp
, sizeof(tmp
), "r%d: ", i
+ 1);
10353 term_color(output
, tmp
, COLOR_GREEN
, COLOR_BLACK
, sizeof(output
));
10355 for (j
= 0; j
< 16; j
++) {
10356 if (cadences
[i
].ringcadence
[j
] == 0)
10358 snprintf(tmp
, sizeof(tmp
), "%d", cadences
[i
].ringcadence
[j
]);
10359 if (cidrings
[i
] * 2 - 1 == j
)
10360 term_color(tmp2
, tmp
, COLOR_MAGENTA
, COLOR_BLACK
, sizeof(tmp2
) - 1);
10362 term_color(tmp2
, tmp
, COLOR_GREEN
, COLOR_BLACK
, sizeof(tmp2
) - 1);
10364 strncat(output
, ",", sizeof(output
) - strlen(output
) - 1);
10365 strncat(output
, tmp2
, sizeof(output
) - strlen(output
) - 1);
10367 ast_cli(fd
,"%s\n",output
);
10372 /* Based on irqmiss.c */
10373 static int dahdi_show_status(int fd
, int argc
, char *argv
[]) {
10374 #define FORMAT "%-40.40s %-10.10s %-10d %-10d %-10d\n"
10375 #define FORMAT2 "%-40.40s %-10.10s %-10.10s %-10.10s %-10.10s\n"
10382 struct dahdi_spaninfo s
;
10385 if ((ctl
= open("/dev/zap/ctl", O_RDWR
)) < 0) {
10386 ast_log(LOG_WARNING
, "Unable to open /dev/zap/ctl: %s\n", strerror(errno
));
10387 ast_cli(fd
, "No Zaptel interface found.\n");
10388 return RESULT_FAILURE
;
10391 if ((ctl
= open("/dev/dahdi/ctl", O_RDWR
)) < 0) {
10392 ast_log(LOG_WARNING
, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno
));
10393 ast_cli(fd
, "No DAHDI interface found.\n");
10394 return RESULT_FAILURE
;
10397 ast_cli(fd
, FORMAT2
, "Description", "Alarms", "IRQ", "bpviol", "CRC4");
10399 for (span
= 1; span
< DAHDI_MAX_SPANS
; ++span
) {
10401 res
= ioctl(ctl
, DAHDI_SPANSTAT
, &s
);
10406 if (s
.alarms
> 0) {
10407 if (s
.alarms
& DAHDI_ALARM_BLUE
)
10408 strcat(alarms
, "BLU/");
10409 if (s
.alarms
& DAHDI_ALARM_YELLOW
)
10410 strcat(alarms
, "YEL/");
10411 if (s
.alarms
& DAHDI_ALARM_RED
)
10412 strcat(alarms
, "RED/");
10413 if (s
.alarms
& DAHDI_ALARM_LOOPBACK
)
10414 strcat(alarms
, "LB/");
10415 if (s
.alarms
& DAHDI_ALARM_RECOVER
)
10416 strcat(alarms
, "REC/");
10417 if (s
.alarms
& DAHDI_ALARM_NOTOPEN
)
10418 strcat(alarms
, "NOP/");
10419 if (!strlen(alarms
))
10420 strcat(alarms
, "UUU/");
10421 if (strlen(alarms
)) {
10422 /* Strip trailing / */
10423 alarms
[strlen(alarms
) - 1] = '\0';
10427 strcpy(alarms
, "OK");
10429 strcpy(alarms
, "UNCONFIGURED");
10432 ast_cli(fd
, FORMAT
, s
.desc
, alarms
, s
.irqmisses
, s
.bpvcount
, s
.crc4count
);
10436 return RESULT_SUCCESS
;
10441 static char show_channels_usage
[] =
10442 "Usage: dahdi show channels\n"
10443 " Shows a list of available channels\n";
10445 static char show_channel_usage
[] =
10446 "Usage: dahdi show channel <chan num>\n"
10447 " Detailed information about a given channel\n";
10449 static char dahdi_show_status_usage
[] =
10450 "Usage: dahdi show status\n"
10451 " Shows a list of DAHDI cards with status\n";
10453 static char destroy_channel_usage
[] =
10454 "Usage: dahdi destroy channel <chan num>\n"
10455 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
10457 static char dahdi_restart_usage
[] =
10458 "Usage: dahdi restart\n"
10459 " Restarts the DAHDI channels: destroys them all and then\n"
10460 " re-reads them from chan_dahdi.conf.\n"
10461 " Note that this will STOP any running CALL on DAHDI channels.\n"
10464 static struct ast_cli_entry cli_zap_show_cadences_deprecated
= {
10465 { "zap", "show", "cadences", NULL
},
10466 handle_dahdi_show_cadences
, NULL
,
10469 static struct ast_cli_entry cli_zap_show_channels_deprecated
= {
10470 { "zap", "show", "channels", NULL
},
10471 dahdi_show_channels
, NULL
,
10474 static struct ast_cli_entry cli_zap_show_channel_deprecated
= {
10475 { "zap", "show", "channel", NULL
},
10476 dahdi_show_channel
, NULL
,
10479 static struct ast_cli_entry cli_zap_destroy_channel_deprecated
= {
10480 { "zap", "destroy", "channel", NULL
},
10481 dahdi_destroy_channel
, NULL
,
10484 static struct ast_cli_entry cli_zap_restart_deprecated
= {
10485 { "zap", "restart", NULL
},
10486 dahdi_restart_cmd
, NULL
,
10489 static struct ast_cli_entry cli_zap_show_status_deprecated
= {
10490 { "zap", "show", "status", NULL
},
10491 dahdi_show_status
, NULL
,
10494 static struct ast_cli_entry dahdi_cli
[] = {
10495 { { "dahdi", "show", "cadences", NULL
},
10496 handle_dahdi_show_cadences
, "List cadences",
10497 dahdi_show_cadences_usage
, NULL
, &cli_zap_show_cadences_deprecated
},
10499 { { "dahdi", "show", "channels", NULL
},
10500 dahdi_show_channels
, "Show active DAHDI channels",
10501 show_channels_usage
, NULL
, &cli_zap_show_channels_deprecated
},
10503 { { "dahdi", "show", "channel", NULL
},
10504 dahdi_show_channel
, "Show information on a channel",
10505 show_channel_usage
, NULL
, &cli_zap_show_channel_deprecated
},
10507 { { "dahdi", "destroy", "channel", NULL
},
10508 dahdi_destroy_channel
, "Destroy a channel",
10509 destroy_channel_usage
, NULL
, &cli_zap_destroy_channel_deprecated
},
10511 { { "dahdi", "restart", NULL
},
10512 dahdi_restart_cmd
, "Fully restart DAHDI channels",
10513 dahdi_restart_usage
, NULL
, &cli_zap_restart_deprecated
},
10515 { { "dahdi", "show", "status", NULL
},
10516 dahdi_show_status
, "Show all DAHDI cards status",
10517 dahdi_show_status_usage
, NULL
, &cli_zap_show_status_deprecated
},
10523 static int dahdi_fake_event(struct dahdi_pvt
*p
, int mode
)
10528 p
->fake_event
= DAHDI_EVENT_WINKFLASH
;
10531 p
->fake_event
= DAHDI_EVENT_ONHOOK
;
10534 ast_log(LOG_WARNING
, "I don't know how to handle transfer event with this: %d on channel %s\n",mode
, p
->owner
->name
);
10539 static struct dahdi_pvt
*find_channel(int channel
)
10541 struct dahdi_pvt
*p
= iflist
;
10543 if (p
->channel
== channel
) {
10551 #define local_astman_ack(s, m, msg, zap) do { if (!zap) astman_send_ack(s, m, "DAHDI" msg); else astman_send_ack(s, m, "Zap" msg); } while (0)
10552 #define local_astman_header(m, hdr, zap) astman_get_header(m, (!zap) ? "DAHDI" hdr : "Zap" hdr)
10554 static int __action_dnd(struct mansession
*s
, const struct message
*m
, int zap_mode
, int dnd
)
10556 struct dahdi_pvt
*p
= NULL
;
10557 const char *channel
= local_astman_header(m
, "Channel", zap_mode
);
10559 if (ast_strlen_zero(channel
)) {
10560 astman_send_error(s
, m
, "No channel specified");
10563 if (!(p
= find_channel(atoi(channel
)))) {
10564 astman_send_error(s
, m
, "No such channel");
10568 local_astman_ack(s
, m
, "DND", zap_mode
);
10573 static int zap_action_dndon(struct mansession
*s
, const struct message
*m
)
10575 return __action_dnd(s
, m
, 1, 1);
10578 static int dahdi_action_dndon(struct mansession
*s
, const struct message
*m
)
10580 return __action_dnd(s
, m
, 0, 1);
10583 static int zap_action_dndoff(struct mansession
*s
, const struct message
*m
)
10585 return __action_dnd(s
, m
, 1, 0);
10588 static int dahdi_action_dndoff(struct mansession
*s
, const struct message
*m
)
10590 return __action_dnd(s
, m
, 0, 0);
10593 static int __action_transfer(struct mansession
*s
, const struct message
*m
, int zap_mode
)
10595 struct dahdi_pvt
*p
= NULL
;
10596 const char *channel
= local_astman_header(m
, "Channel", zap_mode
);
10598 if (ast_strlen_zero(channel
)) {
10599 astman_send_error(s
, m
, "No channel specified");
10602 if (!(p
= find_channel(atoi(channel
)))) {
10603 astman_send_error(s
, m
, "No such channel");
10606 dahdi_fake_event(p
,TRANSFER
);
10607 local_astman_ack(s
, m
, "Transfer", zap_mode
);
10612 static int zap_action_transfer(struct mansession
*s
, const struct message
*m
)
10614 return __action_transfer(s
, m
, 1);
10617 static int dahdi_action_transfer(struct mansession
*s
, const struct message
*m
)
10619 return __action_transfer(s
, m
, 0);
10622 static int __action_transferhangup(struct mansession
*s
, const struct message
*m
, int zap_mode
)
10624 struct dahdi_pvt
*p
= NULL
;
10625 const char *channel
= local_astman_header(m
, "Channel", zap_mode
);
10627 if (ast_strlen_zero(channel
)) {
10628 astman_send_error(s
, m
, "No channel specified");
10631 if (!(p
= find_channel(atoi(channel
)))) {
10632 astman_send_error(s
, m
, "No such channel");
10635 dahdi_fake_event(p
, HANGUP
);
10636 local_astman_ack(s
, m
, "Hangup", zap_mode
);
10640 static int zap_action_transferhangup(struct mansession
*s
, const struct message
*m
)
10642 return __action_transferhangup(s
, m
, 1);
10645 static int dahdi_action_transferhangup(struct mansession
*s
, const struct message
*m
)
10647 return __action_transferhangup(s
, m
, 0);
10650 static int __action_dialoffhook(struct mansession
*s
, const struct message
*m
, int zap_mode
)
10652 struct dahdi_pvt
*p
= NULL
;
10653 const char *channel
= local_astman_header(m
, "Channel", zap_mode
);
10654 const char *number
= astman_get_header(m
, "Number");
10657 if (ast_strlen_zero(channel
)) {
10658 astman_send_error(s
, m
, "No channel specified");
10661 if (ast_strlen_zero(number
)) {
10662 astman_send_error(s
, m
, "No number specified");
10665 if (!(p
= find_channel(atoi(channel
)))) {
10666 astman_send_error(s
, m
, "No such channel");
10670 astman_send_error(s
, m
, "Channel does not have an owner");
10673 for (i
= 0; i
< strlen(number
); i
++) {
10674 struct ast_frame f
= { AST_FRAME_DTMF
, number
[i
] };
10676 dahdi_queue_frame(p
, &f
, NULL
);
10678 local_astman_ack(s
, m
, "DialOffHook", zap_mode
);
10683 static int zap_action_dialoffhook(struct mansession
*s
, const struct message
*m
)
10685 return __action_dialoffhook(s
, m
, 1);
10688 static int dahdi_action_dialoffhook(struct mansession
*s
, const struct message
*m
)
10690 return __action_dialoffhook(s
, m
, 0);
10693 static int __action_showchannels(struct mansession
*s
, const struct message
*m
, int zap_mode
)
10695 struct dahdi_pvt
*tmp
= NULL
;
10696 const char *id
= astman_get_header(m
, "ActionID");
10697 char idText
[256] = "";
10699 local_astman_ack(s
, m
, " channel status will follow", zap_mode
);
10700 if (!ast_strlen_zero(id
))
10701 snprintf(idText
, sizeof(idText
) - 1, "ActionID: %s\r\n", id
);
10703 ast_mutex_lock(&iflock
);
10707 if (tmp
->channel
> 0) {
10708 int alarm
= get_alarms(tmp
);
10710 "Event: %sShowChannels\r\n"
10712 "Signalling: %s\r\n"
10719 tmp
->channel
, sig2str(tmp
->sig
), tmp
->context
,
10720 tmp
->dnd
? "Enabled" : "Disabled",
10721 alarm2str(alarm
), idText
);
10727 ast_mutex_unlock(&iflock
);
10730 "Event: %sShowChannelsComplete\r\n"
10738 static int zap_action_showchannels(struct mansession
*s
, const struct message
*m
)
10740 return __action_showchannels(s
, m
, 1);
10743 static int dahdi_action_showchannels(struct mansession
*s
, const struct message
*m
)
10745 return __action_showchannels(s
, m
, 0);
10748 static int __action_restart(struct mansession
*s
, const struct message
*m
, int zap_mode
)
10750 if (dahdi_restart() != 0) {
10752 astman_send_error(s
, m
, "Failed to restart Zap");
10754 astman_send_error(s
, m
, "Failed to restart DAHDI");
10758 local_astman_ack(s
, m
, "Restart: Success", zap_mode
);
10762 static int zap_action_restart(struct mansession
*s
, const struct message
*m
)
10764 return __action_restart(s
, m
, 1);
10767 static int dahdi_action_restart(struct mansession
*s
, const struct message
*m
)
10769 return __action_restart(s
, m
, 0);
10772 #define local_astman_unregister(a) do { \
10773 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
10774 ast_manager_unregister("DAHDI" a); \
10776 ast_manager_unregister("Zap" a); \
10779 static int __unload_module(void)
10782 struct dahdi_pvt
*p
, *pl
;
10786 for (i
= 0; i
< NUM_SPANS
; i
++) {
10787 if (pris
[i
].master
!= AST_PTHREADT_NULL
)
10788 pthread_cancel(pris
[i
].master
);
10790 ast_cli_unregister_multiple(dahdi_pri_cli
, sizeof(dahdi_pri_cli
) / sizeof(struct ast_cli_entry
));
10792 if (*dahdi_chan_mode
== CHAN_DAHDI_PLUS_ZAP_MODE
) {
10793 ast_unregister_application(dahdi_send_keypad_facility_app
);
10795 ast_unregister_application(zap_send_keypad_facility_app
);
10797 ast_cli_unregister_multiple(dahdi_cli
, sizeof(dahdi_cli
) / sizeof(struct ast_cli_entry
));
10798 local_astman_unregister("DialOffHook");
10799 local_astman_unregister("Hangup");
10800 local_astman_unregister("Transfer");
10801 local_astman_unregister("DNDoff");
10802 local_astman_unregister("DNDon");
10803 local_astman_unregister("ShowChannels");
10804 local_astman_unregister("Restart");
10805 ast_channel_unregister(chan_tech
);
10806 ast_mutex_lock(&iflock
);
10807 /* Hangup all interfaces if they have an owner */
10811 ast_softhangup(p
->owner
, AST_SOFTHANGUP_APPUNLOAD
);
10814 ast_mutex_unlock(&iflock
);
10815 ast_mutex_lock(&monlock
);
10816 if (monitor_thread
&& (monitor_thread
!= AST_PTHREADT_STOP
) && (monitor_thread
!= AST_PTHREADT_NULL
)) {
10817 pthread_cancel(monitor_thread
);
10818 pthread_kill(monitor_thread
, SIGURG
);
10819 pthread_join(monitor_thread
, NULL
);
10821 monitor_thread
= AST_PTHREADT_STOP
;
10822 ast_mutex_unlock(&monlock
);
10824 ast_mutex_lock(&iflock
);
10825 /* Destroy all the interfaces and free their memory */
10828 /* Free any callerid */
10831 /* Close the DAHDI thingy */
10832 if (p
->subs
[SUB_REAL
].dfd
> -1)
10833 dahdi_close(p
->subs
[SUB_REAL
].dfd
);
10837 /* Free associated memory */
10839 destroy_dahdi_pvt(&pl
);
10840 ast_verbose(VERBOSE_PREFIX_3
"Unregistered channel %d\n", x
);
10844 ast_mutex_unlock(&iflock
);
10846 for (i
= 0; i
< NUM_SPANS
; i
++) {
10847 if (pris
[i
].master
&& (pris
[i
].master
!= AST_PTHREADT_NULL
))
10848 pthread_join(pris
[i
].master
, NULL
);
10849 for (j
= 0; j
< NUM_DCHANS
; j
++) {
10850 dahdi_close(pris
[i
].fds
[j
]);
10857 static int unload_module(void)
10861 for (y
= 0; y
< NUM_SPANS
; y
++)
10862 ast_mutex_destroy(&pris
[y
].lock
);
10864 return __unload_module();
10867 static int build_channels(struct dahdi_chan_conf
*conf
, int iscrv
, const char *value
, int reload
, int lineno
, int *found_pseudo
)
10870 int x
, start
, finish
;
10871 struct dahdi_pvt
*tmp
;
10873 struct dahdi_pri
*pri
;
10877 if ((reload
== 0) && (conf
->chan
.sig
< 0)) {
10878 ast_log(LOG_ERROR
, "Signalling must be specified before any channels are.\n");
10882 c
= ast_strdupa(value
);
10887 if (sscanf(c
, "%d:%n", &trunkgroup
, &y
) != 1) {
10888 ast_log(LOG_WARNING
, "CRV must begin with trunkgroup followed by a colon at line %d\n", lineno
);
10891 if (trunkgroup
< 1) {
10892 ast_log(LOG_WARNING
, "CRV trunk group must be a positive number at line %d\n", lineno
);
10896 for (y
= 0; y
< NUM_SPANS
; y
++) {
10897 if (pris
[y
].trunkgroup
== trunkgroup
) {
10903 ast_log(LOG_WARNING
, "No such trunk group %d at CRV declaration at line %d\n", trunkgroup
, lineno
);
10909 while ((chan
= strsep(&c
, ","))) {
10910 if (sscanf(chan
, "%d-%d", &start
, &finish
) == 2) {
10912 } else if (sscanf(chan
, "%d", &start
)) {
10915 } else if (!strcasecmp(chan
, "pseudo")) {
10916 finish
= start
= CHAN_PSEUDO
;
10920 ast_log(LOG_ERROR
, "Syntax error parsing '%s' at '%s'\n", value
, chan
);
10923 if (finish
< start
) {
10924 ast_log(LOG_WARNING
, "Sillyness: %d < %d\n", start
, finish
);
10930 for (x
= start
; x
<= finish
; x
++) {
10932 tmp
= mkintf(x
, conf
, pri
, reload
);
10934 tmp
= mkintf(x
, conf
, NULL
, reload
);
10938 if (option_verbose
> 2) {
10941 ast_verbose(VERBOSE_PREFIX_3
"%s CRV %d:%d, %s signalling\n", reload
? "Reconfigured" : "Registered", trunkgroup
, x
, sig2str(tmp
->sig
));
10944 ast_verbose(VERBOSE_PREFIX_3
"%s channel %d, %s signalling\n", reload
? "Reconfigured" : "Registered", x
, sig2str(tmp
->sig
));
10947 ast_log(LOG_ERROR
, "Unable to %s channel '%s'\n",
10948 (reload
== 1) ? "reconfigure" : "register", value
);
10957 /** The length of the parameters list of 'dahdichan'.
10958 * \todo Move definition of MAX_CHANLIST_LEN to a proper place. */
10959 #define MAX_CHANLIST_LEN 80
10960 static int process_dahdi(struct dahdi_chan_conf
*confp
, const char *cat
, struct ast_variable
*v
, int reload
, int skipchannels
)
10962 struct dahdi_pvt
*tmp
;
10963 char *ringc
; /* temporary string for parsing the dring number. */
10965 int found_pseudo
= 0;
10966 char dahdichan
[MAX_CHANLIST_LEN
] = {};
10968 for (; v
; v
= v
->next
) {
10969 if (!ast_jb_read_conf(&global_jbconf
, v
->name
, v
->value
))
10972 /* Create the interface list */
10973 if (!strcasecmp(v
->name
, "channel")
10975 || !strcasecmp(v
->name
, "crv")
10981 iscrv
= !strcasecmp(v
->name
, "crv");
10982 if (build_channels(confp
, iscrv
, v
->value
, reload
, v
->lineno
, &found_pseudo
))
10984 } else if (!strcasecmp(v
->name
, "zapchan") || !strcasecmp(v
->name
, "dahdichan")) {
10985 ast_copy_string(dahdichan
, v
->value
, sizeof(dahdichan
));
10986 if (v
->name
[0] == 'z' || v
->name
[0] == 'Z') {
10987 ast_log(LOG_WARNING
, "Option zapchan has been deprecated in favor of dahdichan (found in [%s])\n", cat
);
10989 } else if (!strcasecmp(v
->name
, "usedistinctiveringdetection")) {
10990 if (ast_true(v
->value
))
10991 confp
->chan
.usedistinctiveringdetection
= 1;
10992 } else if (!strcasecmp(v
->name
, "distinctiveringaftercid")) {
10993 if (ast_true(v
->value
))
10994 distinctiveringaftercid
= 1;
10995 } else if (!strcasecmp(v
->name
, "dring1context")) {
10996 ast_copy_string(drings
.ringContext
[0].contextData
, v
->value
, sizeof(drings
.ringContext
[0].contextData
));
10997 } else if (!strcasecmp(v
->name
, "dring2context")) {
10998 ast_copy_string(drings
.ringContext
[1].contextData
, v
->value
, sizeof(drings
.ringContext
[1].contextData
));
10999 } else if (!strcasecmp(v
->name
, "dring3context")) {
11000 ast_copy_string(drings
.ringContext
[2].contextData
, v
->value
, sizeof(drings
.ringContext
[2].contextData
));
11001 } else if (!strcasecmp(v
->name
, "dring1")) {
11003 sscanf(ringc
, "%d,%d,%d", &drings
.ringnum
[0].ring
[0], &drings
.ringnum
[0].ring
[1], &drings
.ringnum
[0].ring
[2]);
11004 } else if (!strcasecmp(v
->name
, "dring2")) {
11006 sscanf(ringc
, "%d,%d,%d", &drings
.ringnum
[1].ring
[0], &drings
.ringnum
[1].ring
[1], &drings
.ringnum
[1].ring
[2]);
11007 } else if (!strcasecmp(v
->name
, "dring3")) {
11009 sscanf(ringc
, "%d,%d,%d", &drings
.ringnum
[2].ring
[0], &drings
.ringnum
[2].ring
[1], &drings
.ringnum
[2].ring
[2]);
11010 } else if (!strcasecmp(v
->name
, "usecallerid")) {
11011 confp
->chan
.use_callerid
= ast_true(v
->value
);
11012 } else if (!strcasecmp(v
->name
, "cidsignalling")) {
11013 if (!strcasecmp(v
->value
, "bell"))
11014 confp
->chan
.cid_signalling
= CID_SIG_BELL
;
11015 else if (!strcasecmp(v
->value
, "v23"))
11016 confp
->chan
.cid_signalling
= CID_SIG_V23
;
11017 else if (!strcasecmp(v
->value
, "dtmf"))
11018 confp
->chan
.cid_signalling
= CID_SIG_DTMF
;
11019 else if (!strcasecmp(v
->value
, "smdi"))
11020 confp
->chan
.cid_signalling
= CID_SIG_SMDI
;
11021 else if (!strcasecmp(v
->value
, "v23_jp"))
11022 confp
->chan
.cid_signalling
= CID_SIG_V23_JP
;
11023 else if (ast_true(v
->value
))
11024 confp
->chan
.cid_signalling
= CID_SIG_BELL
;
11025 } else if (!strcasecmp(v
->name
, "cidstart")) {
11026 if (!strcasecmp(v
->value
, "ring"))
11027 confp
->chan
.cid_start
= CID_START_RING
;
11028 else if (!strcasecmp(v
->value
, "polarity"))
11029 confp
->chan
.cid_start
= CID_START_POLARITY
;
11030 else if (ast_true(v
->value
))
11031 confp
->chan
.cid_start
= CID_START_RING
;
11032 } else if (!strcasecmp(v
->name
, "threewaycalling")) {
11033 confp
->chan
.threewaycalling
= ast_true(v
->value
);
11034 } else if (!strcasecmp(v
->name
, "cancallforward")) {
11035 confp
->chan
.cancallforward
= ast_true(v
->value
);
11036 } else if (!strcasecmp(v
->name
, "relaxdtmf")) {
11037 if (ast_true(v
->value
))
11038 confp
->chan
.dtmfrelax
= DSP_DIGITMODE_RELAXDTMF
;
11040 confp
->chan
.dtmfrelax
= 0;
11041 } else if (!strcasecmp(v
->name
, "mailbox")) {
11042 ast_copy_string(confp
->chan
.mailbox
, v
->value
, sizeof(confp
->chan
.mailbox
));
11043 } else if (!strcasecmp(v
->name
, "hasvoicemail")) {
11044 if (ast_true(v
->value
) && ast_strlen_zero(confp
->chan
.mailbox
)) {
11045 ast_copy_string(confp
->chan
.mailbox
, cat
, sizeof(confp
->chan
.mailbox
));
11047 } else if (!strcasecmp(v
->name
, "adsi")) {
11048 confp
->chan
.adsi
= ast_true(v
->value
);
11049 } else if (!strcasecmp(v
->name
, "usesmdi")) {
11050 confp
->chan
.use_smdi
= ast_true(v
->value
);
11051 } else if (!strcasecmp(v
->name
, "smdiport")) {
11052 ast_copy_string(confp
->smdi_port
, v
->value
, sizeof(confp
->smdi_port
));
11053 } else if (!strcasecmp(v
->name
, "transfer")) {
11054 confp
->chan
.transfer
= ast_true(v
->value
);
11055 } else if (!strcasecmp(v
->name
, "canpark")) {
11056 confp
->chan
.canpark
= ast_true(v
->value
);
11057 } else if (!strcasecmp(v
->name
, "echocancelwhenbridged")) {
11058 confp
->chan
.echocanbridged
= ast_true(v
->value
);
11059 } else if (!strcasecmp(v
->name
, "busydetect")) {
11060 confp
->chan
.busydetect
= ast_true(v
->value
);
11061 } else if (!strcasecmp(v
->name
, "busycount")) {
11062 confp
->chan
.busycount
= atoi(v
->value
);
11063 } else if (!strcasecmp(v
->name
, "busypattern")) {
11064 if (sscanf(v
->value
, "%d,%d", &confp
->chan
.busy_tonelength
, &confp
->chan
.busy_quietlength
) != 2) {
11065 ast_log(LOG_ERROR
, "busypattern= expects busypattern=tonelength,quietlength\n");
11067 } else if (!strcasecmp(v
->name
, "callprogress")) {
11068 if (ast_true(v
->value
))
11069 confp
->chan
.callprogress
|= 1;
11071 confp
->chan
.callprogress
&= ~1;
11072 } else if (!strcasecmp(v
->name
, "faxdetect")) {
11073 if (!strcasecmp(v
->value
, "incoming")) {
11074 confp
->chan
.callprogress
|= 4;
11075 confp
->chan
.callprogress
&= ~2;
11076 } else if (!strcasecmp(v
->value
, "outgoing")) {
11077 confp
->chan
.callprogress
&= ~4;
11078 confp
->chan
.callprogress
|= 2;
11079 } else if (!strcasecmp(v
->value
, "both") || ast_true(v
->value
))
11080 confp
->chan
.callprogress
|= 6;
11082 confp
->chan
.callprogress
&= ~6;
11083 } else if (!strcasecmp(v
->name
, "echocancel")) {
11084 if (!ast_strlen_zero(v
->value
)) {
11085 y
= atoi(v
->value
);
11088 if ((y
== 32) || (y
== 64) || (y
== 128) || (y
== 256) || (y
== 512) || (y
== 1024))
11089 confp
->chan
.echocancel
= y
;
11091 confp
->chan
.echocancel
= ast_true(v
->value
);
11092 if (confp
->chan
.echocancel
)
11093 confp
->chan
.echocancel
=128;
11095 } else if (!strcasecmp(v
->name
, "echotraining")) {
11096 if (sscanf(v
->value
, "%d", &y
) == 1) {
11097 if ((y
< 10) || (y
> 4000)) {
11098 ast_log(LOG_WARNING
, "Echo training time must be within the range of 10 to 4000 ms at line %d\n", v
->lineno
);
11100 confp
->chan
.echotraining
= y
;
11102 } else if (ast_true(v
->value
)) {
11103 confp
->chan
.echotraining
= 400;
11105 confp
->chan
.echotraining
= 0;
11106 } else if (!strcasecmp(v
->name
, "hidecallerid")) {
11107 confp
->chan
.hidecallerid
= ast_true(v
->value
);
11108 } else if (!strcasecmp(v
->name
, "hidecalleridname")) {
11109 confp
->chan
.hidecalleridname
= ast_true(v
->value
);
11110 } else if (!strcasecmp(v
->name
, "pulsedial")) {
11111 confp
->chan
.pulse
= ast_true(v
->value
);
11112 } else if (!strcasecmp(v
->name
, "callreturn")) {
11113 confp
->chan
.callreturn
= ast_true(v
->value
);
11114 } else if (!strcasecmp(v
->name
, "callwaiting")) {
11115 confp
->chan
.callwaiting
= ast_true(v
->value
);
11116 } else if (!strcasecmp(v
->name
, "callwaitingcallerid")) {
11117 confp
->chan
.callwaitingcallerid
= ast_true(v
->value
);
11118 } else if (!strcasecmp(v
->name
, "context")) {
11119 ast_copy_string(confp
->chan
.context
, v
->value
, sizeof(confp
->chan
.context
));
11120 } else if (!strcasecmp(v
->name
, "language")) {
11121 ast_copy_string(confp
->chan
.language
, v
->value
, sizeof(confp
->chan
.language
));
11122 } else if (!strcasecmp(v
->name
, "progzone")) {
11123 ast_copy_string(progzone
, v
->value
, sizeof(progzone
));
11124 } else if (!strcasecmp(v
->name
, "mohinterpret")
11125 ||!strcasecmp(v
->name
, "musiconhold") || !strcasecmp(v
->name
, "musicclass")) {
11126 ast_copy_string(confp
->chan
.mohinterpret
, v
->value
, sizeof(confp
->chan
.mohinterpret
));
11127 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
11128 ast_copy_string(confp
->chan
.mohsuggest
, v
->value
, sizeof(confp
->chan
.mohsuggest
));
11129 } else if (!strcasecmp(v
->name
, "stripmsd")) {
11130 confp
->chan
.stripmsd
= atoi(v
->value
);
11131 } else if (!strcasecmp(v
->name
, "jitterbuffers")) {
11132 numbufs
= atoi(v
->value
);
11133 } else if (!strcasecmp(v
->name
, "group")) {
11134 confp
->chan
.group
= ast_get_group(v
->value
);
11135 } else if (!strcasecmp(v
->name
, "callgroup")) {
11136 confp
->chan
.callgroup
= ast_get_group(v
->value
);
11137 } else if (!strcasecmp(v
->name
, "pickupgroup")) {
11138 confp
->chan
.pickupgroup
= ast_get_group(v
->value
);
11139 } else if (!strcasecmp(v
->name
, "immediate")) {
11140 confp
->chan
.immediate
= ast_true(v
->value
);
11141 } else if (!strcasecmp(v
->name
, "transfertobusy")) {
11142 confp
->chan
.transfertobusy
= ast_true(v
->value
);
11143 } else if (!strcasecmp(v
->name
, "rxgain")) {
11144 if (sscanf(v
->value
, "%f", &confp
->chan
.rxgain
) != 1) {
11145 ast_log(LOG_WARNING
, "Invalid rxgain: %s\n", v
->value
);
11147 } else if (!strcasecmp(v
->name
, "txgain")) {
11148 if (sscanf(v
->value
, "%f", &confp
->chan
.txgain
) != 1) {
11149 ast_log(LOG_WARNING
, "Invalid txgain: %s\n", v
->value
);
11151 } else if (!strcasecmp(v
->name
, "tonezone")) {
11152 if (sscanf(v
->value
, "%d", &confp
->chan
.tonezone
) != 1) {
11153 ast_log(LOG_WARNING
, "Invalid tonezone: %s\n", v
->value
);
11155 } else if (!strcasecmp(v
->name
, "callerid")) {
11156 if (!strcasecmp(v
->value
, "asreceived")) {
11157 confp
->chan
.cid_num
[0] = '\0';
11158 confp
->chan
.cid_name
[0] = '\0';
11160 ast_callerid_split(v
->value
, confp
->chan
.cid_name
, sizeof(confp
->chan
.cid_name
), confp
->chan
.cid_num
, sizeof(confp
->chan
.cid_num
));
11162 } else if (!strcasecmp(v
->name
, "fullname")) {
11163 ast_copy_string(confp
->chan
.cid_name
, v
->value
, sizeof(confp
->chan
.cid_name
));
11164 } else if (!strcasecmp(v
->name
, "cid_number")) {
11165 ast_copy_string(confp
->chan
.cid_num
, v
->value
, sizeof(confp
->chan
.cid_num
));
11166 } else if (!strcasecmp(v
->name
, "useincomingcalleridondahditransfer") || !strcasecmp(v
->name
, "useincomingcalleridonzaptransfer")) {
11167 confp
->chan
.dahditrcallerid
= ast_true(v
->value
);
11168 if (strstr(v
->name
, "zap")) {
11169 ast_log(LOG_WARNING
, "Option useincomingcalleridonzaptransfer has been deprecated in favor of useincomingcalleridondahditransfer (in [%s]).\n", cat
);
11171 } else if (!strcasecmp(v
->name
, "restrictcid")) {
11172 confp
->chan
.restrictcid
= ast_true(v
->value
);
11173 } else if (!strcasecmp(v
->name
, "usecallingpres")) {
11174 confp
->chan
.use_callingpres
= ast_true(v
->value
);
11175 } else if (!strcasecmp(v
->name
, "accountcode")) {
11176 ast_copy_string(confp
->chan
.accountcode
, v
->value
, sizeof(confp
->chan
.accountcode
));
11177 } else if (!strcasecmp(v
->name
, "amaflags")) {
11178 y
= ast_cdr_amaflags2int(v
->value
);
11180 ast_log(LOG_WARNING
, "Invalid AMA flags: %s at line %d\n", v
->value
, v
->lineno
);
11182 confp
->chan
.amaflags
= y
;
11183 } else if (!strcasecmp(v
->name
, "polarityonanswerdelay")) {
11184 confp
->chan
.polarityonanswerdelay
= atoi(v
->value
);
11185 } else if (!strcasecmp(v
->name
, "answeronpolarityswitch")) {
11186 confp
->chan
.answeronpolarityswitch
= ast_true(v
->value
);
11187 } else if (!strcasecmp(v
->name
, "hanguponpolarityswitch")) {
11188 confp
->chan
.hanguponpolarityswitch
= ast_true(v
->value
);
11189 } else if (!strcasecmp(v
->name
, "sendcalleridafter")) {
11190 confp
->chan
.sendcalleridafter
= atoi(v
->value
);
11191 } else if (reload
!= 1){
11192 if (!strcasecmp(v
->name
, "signalling")) {
11193 confp
->chan
.outsigmod
= -1;
11194 if (!strcasecmp(v
->value
, "em")) {
11195 confp
->chan
.sig
= SIG_EM
;
11196 } else if (!strcasecmp(v
->value
, "em_e1")) {
11197 confp
->chan
.sig
= SIG_EM_E1
;
11198 } else if (!strcasecmp(v
->value
, "em_w")) {
11199 confp
->chan
.sig
= SIG_EMWINK
;
11200 confp
->chan
.radio
= 0;
11201 } else if (!strcasecmp(v
->value
, "fxs_ls")) {
11202 confp
->chan
.sig
= SIG_FXSLS
;
11203 confp
->chan
.radio
= 0;
11204 } else if (!strcasecmp(v
->value
, "fxs_gs")) {
11205 confp
->chan
.sig
= SIG_FXSGS
;
11206 confp
->chan
.radio
= 0;
11207 } else if (!strcasecmp(v
->value
, "fxs_ks")) {
11208 confp
->chan
.sig
= SIG_FXSKS
;
11209 confp
->chan
.radio
= 0;
11210 } else if (!strcasecmp(v
->value
, "fxo_ls")) {
11211 confp
->chan
.sig
= SIG_FXOLS
;
11212 confp
->chan
.radio
= 0;
11213 } else if (!strcasecmp(v
->value
, "fxo_gs")) {
11214 confp
->chan
.sig
= SIG_FXOGS
;
11215 confp
->chan
.radio
= 0;
11216 } else if (!strcasecmp(v
->value
, "fxo_ks")) {
11217 confp
->chan
.sig
= SIG_FXOKS
;
11218 confp
->chan
.radio
= 0;
11219 } else if (!strcasecmp(v
->value
, "fxs_rx")) {
11220 confp
->chan
.sig
= SIG_FXSKS
;
11221 confp
->chan
.radio
= 1;
11222 } else if (!strcasecmp(v
->value
, "fxo_rx")) {
11223 confp
->chan
.sig
= SIG_FXOLS
;
11224 confp
->chan
.radio
= 1;
11225 } else if (!strcasecmp(v
->value
, "fxs_tx")) {
11226 confp
->chan
.sig
= SIG_FXSLS
;
11227 confp
->chan
.radio
= 1;
11228 } else if (!strcasecmp(v
->value
, "fxo_tx")) {
11229 confp
->chan
.sig
= SIG_FXOGS
;
11230 confp
->chan
.radio
= 1;
11231 } else if (!strcasecmp(v
->value
, "em_rx")) {
11232 confp
->chan
.sig
= SIG_EM
;
11233 confp
->chan
.radio
= 1;
11234 } else if (!strcasecmp(v
->value
, "em_tx")) {
11235 confp
->chan
.sig
= SIG_EM
;
11236 confp
->chan
.radio
= 1;
11237 } else if (!strcasecmp(v
->value
, "em_rxtx")) {
11238 confp
->chan
.sig
= SIG_EM
;
11239 confp
->chan
.radio
= 2;
11240 } else if (!strcasecmp(v
->value
, "em_txrx")) {
11241 confp
->chan
.sig
= SIG_EM
;
11242 confp
->chan
.radio
= 2;
11243 } else if (!strcasecmp(v
->value
, "sf")) {
11244 confp
->chan
.sig
= SIG_SF
;
11245 confp
->chan
.radio
= 0;
11246 } else if (!strcasecmp(v
->value
, "sf_w")) {
11247 confp
->chan
.sig
= SIG_SFWINK
;
11248 confp
->chan
.radio
= 0;
11249 } else if (!strcasecmp(v
->value
, "sf_featd")) {
11250 confp
->chan
.sig
= SIG_FEATD
;
11251 confp
->chan
.radio
= 0;
11252 } else if (!strcasecmp(v
->value
, "sf_featdmf")) {
11253 confp
->chan
.sig
= SIG_FEATDMF
;
11254 confp
->chan
.radio
= 0;
11255 } else if (!strcasecmp(v
->value
, "sf_featb")) {
11256 confp
->chan
.sig
= SIG_SF_FEATB
;
11257 confp
->chan
.radio
= 0;
11258 } else if (!strcasecmp(v
->value
, "sf")) {
11259 confp
->chan
.sig
= SIG_SF
;
11260 confp
->chan
.radio
= 0;
11261 } else if (!strcasecmp(v
->value
, "sf_rx")) {
11262 confp
->chan
.sig
= SIG_SF
;
11263 confp
->chan
.radio
= 1;
11264 } else if (!strcasecmp(v
->value
, "sf_tx")) {
11265 confp
->chan
.sig
= SIG_SF
;
11266 confp
->chan
.radio
= 1;
11267 } else if (!strcasecmp(v
->value
, "sf_rxtx")) {
11268 confp
->chan
.sig
= SIG_SF
;
11269 confp
->chan
.radio
= 2;
11270 } else if (!strcasecmp(v
->value
, "sf_txrx")) {
11271 confp
->chan
.sig
= SIG_SF
;
11272 confp
->chan
.radio
= 2;
11273 } else if (!strcasecmp(v
->value
, "featd")) {
11274 confp
->chan
.sig
= SIG_FEATD
;
11275 confp
->chan
.radio
= 0;
11276 } else if (!strcasecmp(v
->value
, "featdmf")) {
11277 confp
->chan
.sig
= SIG_FEATDMF
;
11278 confp
->chan
.radio
= 0;
11279 } else if (!strcasecmp(v
->value
, "featdmf_ta")) {
11280 confp
->chan
.sig
= SIG_FEATDMF_TA
;
11281 confp
->chan
.radio
= 0;
11282 } else if (!strcasecmp(v
->value
, "e911")) {
11283 confp
->chan
.sig
= SIG_E911
;
11284 confp
->chan
.radio
= 0;
11285 } else if (!strcasecmp(v
->value
, "fgccama")) {
11286 confp
->chan
.sig
= SIG_FGC_CAMA
;
11287 confp
->chan
.radio
= 0;
11288 } else if (!strcasecmp(v
->value
, "fgccamamf")) {
11289 confp
->chan
.sig
= SIG_FGC_CAMAMF
;
11290 confp
->chan
.radio
= 0;
11291 } else if (!strcasecmp(v
->value
, "featb")) {
11292 confp
->chan
.sig
= SIG_FEATB
;
11293 confp
->chan
.radio
= 0;
11295 } else if (!strcasecmp(v
->value
, "pri_net")) {
11296 confp
->chan
.radio
= 0;
11297 confp
->chan
.sig
= SIG_PRI
;
11298 confp
->pri
.nodetype
= PRI_NETWORK
;
11299 } else if (!strcasecmp(v
->value
, "pri_cpe")) {
11300 confp
->chan
.sig
= SIG_PRI
;
11301 confp
->chan
.radio
= 0;
11302 confp
->pri
.nodetype
= PRI_CPE
;
11303 } else if (!strcasecmp(v
->value
, "gr303fxoks_net")) {
11304 confp
->chan
.sig
= SIG_GR303FXOKS
;
11305 confp
->chan
.radio
= 0;
11306 confp
->pri
.nodetype
= PRI_NETWORK
;
11307 } else if (!strcasecmp(v
->value
, "gr303fxsks_cpe")) {
11308 confp
->chan
.sig
= SIG_GR303FXSKS
;
11309 confp
->chan
.radio
= 0;
11310 confp
->pri
.nodetype
= PRI_CPE
;
11313 ast_log(LOG_ERROR
, "Unknown signalling method '%s'\n", v
->value
);
11315 } else if (!strcasecmp(v
->name
, "outsignalling")) {
11316 if (!strcasecmp(v
->value
, "em")) {
11317 confp
->chan
.outsigmod
= SIG_EM
;
11318 } else if (!strcasecmp(v
->value
, "em_e1")) {
11319 confp
->chan
.outsigmod
= SIG_EM_E1
;
11320 } else if (!strcasecmp(v
->value
, "em_w")) {
11321 confp
->chan
.outsigmod
= SIG_EMWINK
;
11322 } else if (!strcasecmp(v
->value
, "sf")) {
11323 confp
->chan
.outsigmod
= SIG_SF
;
11324 } else if (!strcasecmp(v
->value
, "sf_w")) {
11325 confp
->chan
.outsigmod
= SIG_SFWINK
;
11326 } else if (!strcasecmp(v
->value
, "sf_featd")) {
11327 confp
->chan
.outsigmod
= SIG_FEATD
;
11328 } else if (!strcasecmp(v
->value
, "sf_featdmf")) {
11329 confp
->chan
.outsigmod
= SIG_FEATDMF
;
11330 } else if (!strcasecmp(v
->value
, "sf_featb")) {
11331 confp
->chan
.outsigmod
= SIG_SF_FEATB
;
11332 } else if (!strcasecmp(v
->value
, "sf")) {
11333 confp
->chan
.outsigmod
= SIG_SF
;
11334 } else if (!strcasecmp(v
->value
, "featd")) {
11335 confp
->chan
.outsigmod
= SIG_FEATD
;
11336 } else if (!strcasecmp(v
->value
, "featdmf")) {
11337 confp
->chan
.outsigmod
= SIG_FEATDMF
;
11338 } else if (!strcasecmp(v
->value
, "featdmf_ta")) {
11339 confp
->chan
.outsigmod
= SIG_FEATDMF_TA
;
11340 } else if (!strcasecmp(v
->value
, "e911")) {
11341 confp
->chan
.outsigmod
= SIG_E911
;
11342 } else if (!strcasecmp(v
->value
, "fgccama")) {
11343 confp
->chan
.outsigmod
= SIG_FGC_CAMA
;
11344 } else if (!strcasecmp(v
->value
, "fgccamamf")) {
11345 confp
->chan
.outsigmod
= SIG_FGC_CAMAMF
;
11346 } else if (!strcasecmp(v
->value
, "featb")) {
11347 confp
->chan
.outsigmod
= SIG_FEATB
;
11349 ast_log(LOG_ERROR
, "Unknown signalling method '%s'\n", v
->value
);
11352 } else if (!strcasecmp(v
->name
, "pridialplan")) {
11353 if (!strcasecmp(v
->value
, "national")) {
11354 confp
->pri
.dialplan
= PRI_NATIONAL_ISDN
+ 1;
11355 } else if (!strcasecmp(v
->value
, "unknown")) {
11356 confp
->pri
.dialplan
= PRI_UNKNOWN
+ 1;
11357 } else if (!strcasecmp(v
->value
, "private")) {
11358 confp
->pri
.dialplan
= PRI_PRIVATE
+ 1;
11359 } else if (!strcasecmp(v
->value
, "international")) {
11360 confp
->pri
.dialplan
= PRI_INTERNATIONAL_ISDN
+ 1;
11361 } else if (!strcasecmp(v
->value
, "local")) {
11362 confp
->pri
.dialplan
= PRI_LOCAL_ISDN
+ 1;
11363 } else if (!strcasecmp(v
->value
, "dynamic")) {
11364 confp
->pri
.dialplan
= -1;
11366 ast_log(LOG_WARNING
, "Unknown PRI dialplan '%s' at line %d.\n", v
->value
, v
->lineno
);
11368 } else if (!strcasecmp(v
->name
, "prilocaldialplan")) {
11369 if (!strcasecmp(v
->value
, "national")) {
11370 confp
->pri
.localdialplan
= PRI_NATIONAL_ISDN
+ 1;
11371 } else if (!strcasecmp(v
->value
, "unknown")) {
11372 confp
->pri
.localdialplan
= PRI_UNKNOWN
+ 1;
11373 } else if (!strcasecmp(v
->value
, "private")) {
11374 confp
->pri
.localdialplan
= PRI_PRIVATE
+ 1;
11375 } else if (!strcasecmp(v
->value
, "international")) {
11376 confp
->pri
.localdialplan
= PRI_INTERNATIONAL_ISDN
+ 1;
11377 } else if (!strcasecmp(v
->value
, "local")) {
11378 confp
->pri
.localdialplan
= PRI_LOCAL_ISDN
+ 1;
11379 } else if (!strcasecmp(v
->value
, "dynamic")) {
11380 confp
->pri
.localdialplan
= -1;
11382 ast_log(LOG_WARNING
, "Unknown PRI dialplan '%s' at line %d.\n", v
->value
, v
->lineno
);
11384 } else if (!strcasecmp(v
->name
, "switchtype")) {
11385 if (!strcasecmp(v
->value
, "national"))
11386 confp
->pri
.switchtype
= PRI_SWITCH_NI2
;
11387 else if (!strcasecmp(v
->value
, "ni1"))
11388 confp
->pri
.switchtype
= PRI_SWITCH_NI1
;
11389 else if (!strcasecmp(v
->value
, "dms100"))
11390 confp
->pri
.switchtype
= PRI_SWITCH_DMS100
;
11391 else if (!strcasecmp(v
->value
, "4ess"))
11392 confp
->pri
.switchtype
= PRI_SWITCH_ATT4ESS
;
11393 else if (!strcasecmp(v
->value
, "5ess"))
11394 confp
->pri
.switchtype
= PRI_SWITCH_LUCENT5E
;
11395 else if (!strcasecmp(v
->value
, "euroisdn"))
11396 confp
->pri
.switchtype
= PRI_SWITCH_EUROISDN_E1
;
11397 else if (!strcasecmp(v
->value
, "qsig"))
11398 confp
->pri
.switchtype
= PRI_SWITCH_QSIG
;
11400 ast_log(LOG_ERROR
, "Unknown switchtype '%s'\n", v
->value
);
11403 } else if (!strcasecmp(v
->name
, "nsf")) {
11404 if (!strcasecmp(v
->value
, "sdn"))
11405 confp
->pri
.nsf
= PRI_NSF_SDN
;
11406 else if (!strcasecmp(v
->value
, "megacom"))
11407 confp
->pri
.nsf
= PRI_NSF_MEGACOM
;
11408 else if (!strcasecmp(v
->value
, "tollfreemegacom"))
11409 confp
->pri
.nsf
= PRI_NSF_TOLL_FREE_MEGACOM
;
11410 else if (!strcasecmp(v
->value
, "accunet"))
11411 confp
->pri
.nsf
= PRI_NSF_ACCUNET
;
11412 else if (!strcasecmp(v
->value
, "none"))
11413 confp
->pri
.nsf
= PRI_NSF_NONE
;
11415 ast_log(LOG_WARNING
, "Unknown network-specific facility '%s'\n", v
->value
);
11416 confp
->pri
.nsf
= PRI_NSF_NONE
;
11418 } else if (!strcasecmp(v
->name
, "priindication")) {
11419 if (!strcasecmp(v
->value
, "outofband"))
11420 confp
->chan
.priindication_oob
= 1;
11421 else if (!strcasecmp(v
->value
, "inband"))
11422 confp
->chan
.priindication_oob
= 0;
11424 ast_log(LOG_WARNING
, "'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d\n",
11425 v
->value
, v
->lineno
);
11426 } else if (!strcasecmp(v
->name
, "priexclusive")) {
11427 confp
->chan
.priexclusive
= ast_true(v
->value
);
11428 } else if (!strcasecmp(v
->name
, "internationalprefix")) {
11429 ast_copy_string(confp
->pri
.internationalprefix
, v
->value
, sizeof(confp
->pri
.internationalprefix
));
11430 } else if (!strcasecmp(v
->name
, "nationalprefix")) {
11431 ast_copy_string(confp
->pri
.nationalprefix
, v
->value
, sizeof(confp
->pri
.nationalprefix
));
11432 } else if (!strcasecmp(v
->name
, "localprefix")) {
11433 ast_copy_string(confp
->pri
.localprefix
, v
->value
, sizeof(confp
->pri
.localprefix
));
11434 } else if (!strcasecmp(v
->name
, "privateprefix")) {
11435 ast_copy_string(confp
->pri
.privateprefix
, v
->value
, sizeof(confp
->pri
.privateprefix
));
11436 } else if (!strcasecmp(v
->name
, "unknownprefix")) {
11437 ast_copy_string(confp
->pri
.unknownprefix
, v
->value
, sizeof(confp
->pri
.unknownprefix
));
11438 } else if (!strcasecmp(v
->name
, "resetinterval")) {
11439 if (!strcasecmp(v
->value
, "never"))
11440 confp
->pri
.resetinterval
= -1;
11441 else if (atoi(v
->value
) >= 60)
11442 confp
->pri
.resetinterval
= atoi(v
->value
);
11444 ast_log(LOG_WARNING
, "'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d\n",
11445 v
->value
, v
->lineno
);
11446 } else if (!strcasecmp(v
->name
, "minunused")) {
11447 confp
->pri
.minunused
= atoi(v
->value
);
11448 } else if (!strcasecmp(v
->name
, "minidle")) {
11449 confp
->pri
.minidle
= atoi(v
->value
);
11450 } else if (!strcasecmp(v
->name
, "idleext")) {
11451 ast_copy_string(confp
->pri
.idleext
, v
->value
, sizeof(confp
->pri
.idleext
));
11452 } else if (!strcasecmp(v
->name
, "idledial")) {
11453 ast_copy_string(confp
->pri
.idledial
, v
->value
, sizeof(confp
->pri
.idledial
));
11454 } else if (!strcasecmp(v
->name
, "overlapdial")) {
11455 confp
->pri
.overlapdial
= ast_true(v
->value
);
11456 #ifdef HAVE_PRI_INBANDDISCONNECT
11457 } else if (!strcasecmp(v
->name
, "inbanddisconnect")) {
11458 confp
->pri
.inbanddisconnect
= ast_true(v
->value
);
11460 } else if (!strcasecmp(v
->name
, "pritimer")) {
11461 #ifdef PRI_GETSET_TIMERS
11463 int timer
, timeridx
;
11465 timerc
= strsep(&c
, ",");
11469 ast_log(LOG_WARNING
, "'%s' is not a valid value for an ISDN timer\n", timerc
);
11471 if ((timeridx
= pri_timer2idx(timerc
)) >= 0)
11472 pritimers
[timeridx
] = timer
;
11474 ast_log(LOG_WARNING
, "'%s' is not a valid ISDN timer\n", timerc
);
11477 ast_log(LOG_WARNING
, "'%s' is not a valid ISDN timer configuration string\n", v
->value
);
11479 } else if (!strcasecmp(v
->name
, "facilityenable")) {
11480 confp
->pri
.facilityenable
= ast_true(v
->value
);
11481 #endif /* PRI_GETSET_TIMERS */
11482 #endif /* HAVE_PRI */
11483 } else if (!strcasecmp(v
->name
, "cadence")) {
11484 /* setup to scan our argument */
11485 int element_count
, c
[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
11487 struct dahdi_ring_cadence new_cadence
;
11488 int cid_location
= -1;
11489 int firstcadencepos
= 0;
11490 char original_args
[80];
11491 int cadence_is_ok
= 1;
11493 ast_copy_string(original_args
, v
->value
, sizeof(original_args
));
11494 /* 16 cadences allowed (8 pairs) */
11495 element_count
= sscanf(v
->value
, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", &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]);
11497 /* Cadence must be even (on/off) */
11498 if (element_count
% 2 == 1) {
11499 ast_log(LOG_ERROR
, "Must be a silence duration for each ring duration: %s\n",original_args
);
11503 /* Ring cadences cannot be negative */
11504 for (i
= 0; i
< element_count
; i
++) {
11506 ast_log(LOG_ERROR
, "Ring or silence duration cannot be zero: %s\n", original_args
);
11509 } else if (c
[i
] < 0) {
11511 /* Silence duration, negative possibly okay */
11512 if (cid_location
== -1) {
11516 ast_log(LOG_ERROR
, "CID location specified twice: %s\n",original_args
);
11521 if (firstcadencepos
== 0) {
11522 firstcadencepos
= i
; /* only recorded to avoid duplicate specification */
11523 /* duration will be passed negative to the DAHDI driver */
11525 ast_log(LOG_ERROR
, "First cadence position specified twice: %s\n",original_args
);
11533 /* Substitute our scanned cadence */
11534 for (i
= 0; i
< 16; i
++) {
11535 new_cadence
.ringcadence
[i
] = c
[i
];
11538 if (cadence_is_ok
) {
11539 /* ---we scanned it without getting annoyed; now some sanity checks--- */
11540 if (element_count
< 2) {
11541 ast_log(LOG_ERROR
, "Minimum cadence is ring,pause: %s\n", original_args
);
11543 if (cid_location
== -1) {
11544 /* user didn't say; default to first pause */
11547 /* convert element_index to cidrings value */
11548 cid_location
= (cid_location
+ 1) / 2;
11550 /* ---we like their cadence; try to install it--- */
11551 if (!user_has_defined_cadences
++)
11552 /* this is the first user-defined cadence; clear the default user cadences */
11554 if ((num_cadence
+1) >= NUM_CADENCE_MAX
)
11555 ast_log(LOG_ERROR
, "Already %d cadences; can't add another: %s\n", NUM_CADENCE_MAX
, original_args
);
11557 cadences
[num_cadence
] = new_cadence
;
11558 cidrings
[num_cadence
++] = cid_location
;
11559 if (option_verbose
> 2)
11560 ast_verbose(VERBOSE_PREFIX_3
"cadence 'r%d' added: %s\n",num_cadence
,original_args
);
11564 } else if (!strcasecmp(v
->name
, "ringtimeout")) {
11565 ringt_base
= (atoi(v
->value
) * 8) / READ_SIZE
;
11566 } else if (!strcasecmp(v
->name
, "prewink")) {
11567 confp
->timing
.prewinktime
= atoi(v
->value
);
11568 } else if (!strcasecmp(v
->name
, "preflash")) {
11569 confp
->timing
.preflashtime
= atoi(v
->value
);
11570 } else if (!strcasecmp(v
->name
, "wink")) {
11571 confp
->timing
.winktime
= atoi(v
->value
);
11572 } else if (!strcasecmp(v
->name
, "flash")) {
11573 confp
->timing
.flashtime
= atoi(v
->value
);
11574 } else if (!strcasecmp(v
->name
, "start")) {
11575 confp
->timing
.starttime
= atoi(v
->value
);
11576 } else if (!strcasecmp(v
->name
, "rxwink")) {
11577 confp
->timing
.rxwinktime
= atoi(v
->value
);
11578 } else if (!strcasecmp(v
->name
, "rxflash")) {
11579 confp
->timing
.rxflashtime
= atoi(v
->value
);
11580 } else if (!strcasecmp(v
->name
, "debounce")) {
11581 confp
->timing
.debouncetime
= atoi(v
->value
);
11582 } else if (!strcasecmp(v
->name
, "toneduration")) {
11586 struct dahdi_dialparams dps
;
11589 ctlfd
= open("/dev/zap/ctl", O_RDWR
);
11591 ctlfd
= open("/dev/dahdi/ctl", O_RDWR
);
11595 ast_log(LOG_ERROR
, "Unable to open /dev/dahdi/ctl to set toneduration\n");
11599 toneduration
= atoi(v
->value
);
11600 if (toneduration
> -1) {
11601 memset(&dps
, 0, sizeof(dps
));
11603 dps
.dtmf_tonelen
= dps
.mfv1_tonelen
= toneduration
;
11604 res
= ioctl(ctlfd
, DAHDI_SET_DIALPARAMS
, &dps
);
11606 ast_log(LOG_ERROR
, "Invalid tone duration: %d ms: %s\n", toneduration
, strerror(errno
));
11611 } else if (!strcasecmp(v
->name
, "defaultcic")) {
11612 ast_copy_string(defaultcic
, v
->value
, sizeof(defaultcic
));
11613 } else if (!strcasecmp(v
->name
, "defaultozz")) {
11614 ast_copy_string(defaultozz
, v
->value
, sizeof(defaultozz
));
11616 } else if (!skipchannels
)
11617 ast_log(LOG_WARNING
, "Ignoring %s\n", v
->name
);
11619 if (dahdichan
[0]) {
11620 /* The user has set 'dahdichan' */
11621 /*< \todo pass proper line number instead of 0 */
11622 if (build_channels(confp
, 0, dahdichan
, reload
, 0, &found_pseudo
)) {
11626 /*< \todo why check for the pseudo in the per-channel section.
11627 * Any actual use for manual setup of the pseudo channel? */
11628 if (!found_pseudo
&& reload
== 0) {
11629 /* Make sure pseudo isn't a member of any groups if
11630 we're automatically making it. */
11632 confp
->chan
.group
= 0;
11633 confp
->chan
.callgroup
= 0;
11634 confp
->chan
.pickupgroup
= 0;
11636 tmp
= mkintf(CHAN_PSEUDO
, confp
, NULL
, reload
);
11639 if (option_verbose
> 2)
11640 ast_verbose(VERBOSE_PREFIX_3
"Automatically generated pseudo channel\n");
11642 ast_log(LOG_WARNING
, "Unable to register pseudo channel!\n");
11648 static int setup_dahdi(int reload
)
11650 struct ast_config
*cfg
;
11651 struct ast_variable
*v
;
11652 struct dahdi_chan_conf conf
= dahdi_chan_conf_default();
11661 int dchannels
[NUM_DCHANS
];
11665 int load_from_zapata_conf
= 1;
11667 int load_from_zapata_conf
= (dahdi_chan_mode
== CHAN_ZAP_MODE
);
11670 if (load_from_zapata_conf
) {
11671 if (!(cfg
= ast_config_load("zapata.conf"))) {
11672 ast_log(LOG_ERROR
, "Unable to load zapata.conf\n");
11676 if (!(cfg
= ast_config_load("chan_dahdi.conf"))) {
11677 ast_log(LOG_ERROR
, "Unable to load chan_dahdi.conf\n");
11682 /* It's a little silly to lock it, but we mind as well just to be sure */
11683 ast_mutex_lock(&iflock
);
11686 /* Process trunkgroups first */
11687 v
= ast_variable_browse(cfg
, "trunkgroups");
11689 if (!strcasecmp(v
->name
, "trunkgroup")) {
11690 trunkgroup
= atoi(v
->value
);
11691 if (trunkgroup
> 0) {
11692 if ((c
= strchr(v
->value
, ','))) {
11694 memset(dchannels
, 0, sizeof(dchannels
));
11695 while (c
&& (i
< NUM_DCHANS
)) {
11696 dchannels
[i
] = atoi(c
+ 1);
11697 if (dchannels
[i
] < 0) {
11698 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
);
11701 c
= strchr(c
+ 1, ',');
11704 if (pri_create_trunkgroup(trunkgroup
, dchannels
)) {
11705 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
);
11706 } else if (option_verbose
> 1)
11707 ast_verbose(VERBOSE_PREFIX_2
"Created trunk group %d with Primary D-channel %d and %d backup%s\n", trunkgroup
, dchannels
[0], i
- 1, (i
== 1) ? "" : "s");
11709 ast_log(LOG_WARNING
, "Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup
, v
->lineno
);
11711 ast_log(LOG_WARNING
, "Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup
, v
->lineno
);
11713 ast_log(LOG_WARNING
, "Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v
->lineno
);
11714 } else if (!strcasecmp(v
->name
, "spanmap")) {
11715 spanno
= atoi(v
->value
);
11717 if ((c
= strchr(v
->value
, ','))) {
11718 trunkgroup
= atoi(c
+ 1);
11719 if (trunkgroup
> 0) {
11720 if ((c
= strchr(c
+ 1, ',')))
11721 logicalspan
= atoi(c
+ 1);
11724 if (logicalspan
>= 0) {
11725 if (pri_create_spanmap(spanno
- 1, trunkgroup
, logicalspan
)) {
11726 ast_log(LOG_WARNING
, "Failed to map span %d to trunk group %d (logical span %d)\n", spanno
, trunkgroup
, logicalspan
);
11727 } else if (option_verbose
> 1)
11728 ast_verbose(VERBOSE_PREFIX_2
"Mapped span %d to trunk group %d (logical span %d)\n", spanno
, trunkgroup
, logicalspan
);
11730 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
);
11732 ast_log(LOG_WARNING
, "Trunk group must be a postive number at line %d of chan_dahdi.conf\n", v
->lineno
);
11734 ast_log(LOG_WARNING
, "Missing trunk group for span map at line %d of chan_dahdi.conf\n", v
->lineno
);
11736 ast_log(LOG_WARNING
, "Span number must be a postive integer at line %d of chan_dahdi.conf\n", v
->lineno
);
11738 ast_log(LOG_NOTICE
, "Ignoring unknown keyword '%s' in trunkgroups\n", v
->name
);
11745 /* Copy the default jb config over global_jbconf */
11746 memcpy(&global_jbconf
, &default_jbconf
, sizeof(struct ast_jb_conf
));
11748 v
= ast_variable_browse(cfg
, "channels");
11749 res
= process_dahdi(&conf
, "", v
, reload
, 0);
11750 ast_mutex_unlock(&iflock
);
11751 ast_config_destroy(cfg
);
11754 cfg
= ast_config_load("users.conf");
11758 process_dahdi(&conf
, "", ast_variable_browse(cfg
, "general"), 1, 1);
11759 for (cat
= ast_category_browse(cfg
, NULL
); cat
; cat
= ast_category_browse(cfg
, cat
)) {
11760 if (!strcasecmp(cat
, "general"))
11762 chans
= ast_variable_retrieve(cfg
, cat
, "dahdichan");
11763 if (!ast_strlen_zero(chans
)) {
11764 struct dahdi_chan_conf sect_conf
;
11765 memcpy(§_conf
, &conf
, sizeof(sect_conf
));
11767 process_dahdi(§_conf
, cat
, ast_variable_browse(cfg
, cat
), reload
, 0);
11770 ast_config_destroy(cfg
);
11774 for (x
= 0; x
< NUM_SPANS
; x
++) {
11775 if (pris
[x
].pvts
[0]) {
11776 if (start_pri(pris
+ x
)) {
11777 ast_log(LOG_ERROR
, "Unable to start D-channel on span %d\n", x
+ 1);
11779 } else if (option_verbose
> 1)
11780 ast_verbose(VERBOSE_PREFIX_2
"Starting D-Channel on span %d\n", x
+ 1);
11785 /* And start the monitor for the first time */
11790 #define local_astman_register(a, b, c, d) do { \
11791 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { \
11792 ast_manager_register("DAHDI" a, b, dahdi_ ## c, d); \
11794 ast_manager_register("Zap" a, b, zap_ ## c, d); \
11797 static int load_module(void)
11803 memset(pris
, 0, sizeof(pris
));
11804 for (y
= 0; y
< NUM_SPANS
; y
++) {
11805 ast_mutex_init(&pris
[y
].lock
);
11806 pris
[y
].offset
= -1;
11807 pris
[y
].master
= AST_PTHREADT_NULL
;
11808 for (i
= 0; i
< NUM_DCHANS
; i
++)
11809 pris
[y
].fds
[i
] = -1;
11811 pri_set_error(dahdi_pri_error
);
11812 pri_set_message(dahdi_pri_message
);
11813 if (*dahdi_chan_mode
== CHAN_DAHDI_PLUS_ZAP_MODE
) {
11814 ast_register_application(dahdi_send_keypad_facility_app
, dahdi_send_keypad_facility_exec
,
11815 dahdi_send_keypad_facility_synopsis
, dahdi_send_keypad_facility_descrip
);
11817 ast_register_application(zap_send_keypad_facility_app
, zap_send_keypad_facility_exec
,
11818 zap_send_keypad_facility_synopsis
, zap_send_keypad_facility_descrip
);
11820 if ((res
= setup_dahdi(0))) {
11821 return AST_MODULE_LOAD_DECLINE
;
11823 if (*dahdi_chan_mode
== CHAN_DAHDI_PLUS_ZAP_MODE
) {
11824 chan_tech
= &dahdi_tech
;
11826 chan_tech
= &zap_tech
;
11828 if (ast_channel_register(chan_tech
)) {
11829 ast_log(LOG_ERROR
, "Unable to register channel class '%s'\n", chan_tech
->type
);
11834 ast_string_field_init(&inuse
, 16);
11835 ast_string_field_set(&inuse
, name
, "GR-303InUse");
11836 ast_cli_register_multiple(dahdi_pri_cli
, sizeof(dahdi_pri_cli
) / sizeof(struct ast_cli_entry
));
11838 ast_cli_register_multiple(dahdi_cli
, sizeof(dahdi_cli
) / sizeof(struct ast_cli_entry
));
11840 memset(round_robin
, 0, sizeof(round_robin
));
11841 local_astman_register("Transfer", 0, action_transfer
, "Transfer Channel");
11842 local_astman_register("Hangup", 0, action_transferhangup
, "Hangup Channel");
11843 local_astman_register("DialOffHook", 0, action_dialoffhook
, "Dial over channel while offhook");
11844 local_astman_register("DNDon", 0, action_dndon
, "Toggle channel Do Not Disturb status ON");
11845 local_astman_register("DNDoff", 0, action_dndoff
, "Toggle channel Do Not Disturb status OFF");
11846 local_astman_register("ShowChannels", 0, action_showchannels
, "Show status channels");
11847 local_astman_register("Restart", 0, action_restart
, "Fully Restart channels (terminates calls)");
11852 static int dahdi_sendtext(struct ast_channel
*c
, const char *text
)
11854 #define END_SILENCE_LEN 400
11855 #define HEADER_MS 50
11856 #define TRAILER_MS 5
11857 #define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
11858 #define ASCII_BYTES_PER_CHAR 80
11860 unsigned char *buf
,*mybuf
;
11861 struct dahdi_pvt
*p
= c
->tech_pvt
;
11862 struct pollfd fds
[1];
11863 int size
,res
,fd
,len
,x
;
11865 /* Initial carrier (imaginary) */
11871 index
= dahdi_get_index(c
, p
, 0);
11873 ast_log(LOG_WARNING
, "Huh? I don't exist?\n");
11876 if (!text
[0]) return(0); /* if nothing to send, dont */
11877 if ((!p
->tdd
) && (!p
->mate
)) return(0); /* if not in TDD mode, just return */
11879 buf
= ast_malloc(((strlen(text
) + 1) * ASCII_BYTES_PER_CHAR
) + END_SILENCE_LEN
+ HEADER_LEN
);
11881 buf
= ast_malloc(((strlen(text
) + 1) * TDD_BYTES_PER_CHAR
) + END_SILENCE_LEN
);
11886 int codec
= AST_LAW(p
);
11887 for (x
= 0; x
< HEADER_MS
; x
++) { /* 50 ms of Mark */
11890 /* Put actual message */
11891 for (x
= 0; text
[x
]; x
++) {
11894 for (x
= 0; x
< TRAILER_MS
; x
++) { /* 5 ms of Mark */
11900 len
= tdd_generate(p
->tdd
, buf
, text
);
11902 ast_log(LOG_ERROR
, "TDD generate (len %d) failed!!\n", (int)strlen(text
));
11907 memset(buf
+ len
, 0x7f, END_SILENCE_LEN
);
11908 len
+= END_SILENCE_LEN
;
11909 fd
= p
->subs
[index
].dfd
;
11911 if (ast_check_hangup(c
)) {
11916 if (size
> READ_SIZE
)
11919 fds
[0].events
= POLLOUT
| POLLPRI
;
11920 fds
[0].revents
= 0;
11921 res
= poll(fds
, 1, -1);
11923 ast_log(LOG_DEBUG
, "poll (for write) ret. 0 on channel %d\n", p
->channel
);
11926 /* if got exception */
11927 if (fds
[0].revents
& POLLPRI
) {
11931 if (!(fds
[0].revents
& POLLOUT
)) {
11932 ast_log(LOG_DEBUG
, "write fd not ready on channel %d\n", p
->channel
);
11935 res
= write(fd
, buf
, size
);
11942 ast_log(LOG_DEBUG
, "Write returned %d (%s) on channel %d\n", res
, strerror(errno
), p
->channel
);
11953 static int reload(void)
11957 res
= setup_dahdi(1);
11959 ast_log(LOG_WARNING
, "Reload of chan_dahdi.so is unsuccessful!\n");
11965 /* This is a workaround so that menuselect displays a proper description
11966 * AST_MODULE_INFO(, , "DAHDI Telephony"
11970 #define tdesc "DAHDI Telephony w/PRI"
11972 #define tdesc "DAHDI Telephony"
11975 AST_MODULE_INFO(ASTERISK_GPL_KEY
, AST_MODFLAG_DEFAULT
, tdesc
,
11976 .load
= load_module
,
11977 .unload
= unload_module
,