2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2008, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
29 <depend>chan_local</depend>
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38 #include <sys/signal.h>
40 #include <netinet/in.h>
42 #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
43 #include "asterisk/lock.h"
44 #include "asterisk/file.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/module.h"
48 #include "asterisk/translate.h"
49 #include "asterisk/say.h"
50 #include "asterisk/config.h"
51 #include "asterisk/features.h"
52 #include "asterisk/musiconhold.h"
53 #include "asterisk/callerid.h"
54 #include "asterisk/utils.h"
55 #include "asterisk/app.h"
56 #include "asterisk/causes.h"
57 #include "asterisk/rtp_engine.h"
58 #include "asterisk/cdr.h"
59 #include "asterisk/manager.h"
60 #include "asterisk/privacy.h"
61 #include "asterisk/stringfields.h"
62 #include "asterisk/global_datastores.h"
63 #include "asterisk/dsp.h"
66 <application name="Dial" language="en_US">
68 Attempt to connect to another device or endpoint and bridge the call.
71 <parameter name="Technology/Resource" required="true" argsep="&">
72 <argument name="Technology/Resource" required="true">
73 <para>Specification of the device(s) to dial. These must be in the format of
74 <literal>Technology/Resource</literal>, where <replaceable>Technology</replaceable>
75 represents a particular channel driver, and <replaceable>Resource</replaceable>
76 represents a resource available to that particular channel driver.</para>
78 <argument name="Technology2/Resource2" required="false" multiple="true">
79 <para>Optional extra devices to dial in parallel</para>
80 <para>If you need more then one enter them as
81 Technology2/Resource2&Technology3/Resourse3&.....</para>
84 <parameter name="timeout" required="false">
85 <para>Specifies the number of seconds we attempt to dial the specified devices</para>
86 <para>If not specified, this defaults to 136 years.</para>
88 <parameter name="options" required="false">
91 <argument name="x" required="true">
92 <para>The file to play to the called party</para>
94 <para>Play an announcement to the called party, where <replaceable>x</replaceable> is the prompt to be played</para>
97 <para>Reset the call detail record (CDR) for this call.</para>
100 <para>If the Dial() application cancels this call, always set the flag to tell the channel
101 driver that the call is answered elsewhere.</para>
104 <para>Allow the calling user to dial a 1 digit extension while waiting for
105 a call to be answered. Exit to that extension if it exists in the
106 current context, or the context defined in the <variable>EXITCONTEXT</variable> variable,
109 <option name="D" argsep=":">
110 <argument name="called" />
111 <argument name="calling" />
112 <argument name="progress" />
113 <para>Send the specified DTMF strings <emphasis>after</emphasis> the called
114 party has answered, but before the call gets bridged. The
115 <replaceable>called</replaceable> DTMF string is sent to the called party, and the
116 <replaceable>calling</replaceable> DTMF string is sent to the calling party. Both arguments
117 can be used alone. If <replaceable>progress</replaceable> is specified, its DTMF is sent
118 immediately after receiving a PROGRESS message.</para>
121 <para>Execute the <literal>h</literal> extension for peer after the call ends</para>
124 <para>Force the callerid of the <emphasis>calling</emphasis> channel to be set as the
125 extension associated with the channel using a dialplan <literal>hint</literal>.
126 For example, some PSTNs do not allow CallerID to be set to anything
127 other than the number assigned to the caller.</para>
129 <option name="F" argsep="^">
130 <argument name="context" required="false" />
131 <argument name="exten" required="false" />
132 <argument name="priority" required="true" />
133 <para>When the caller hangs up, transfer the called party
134 to the specified destination and continue execution at that location.</para>
137 <para>Proceed with dialplan execution at the next priority in the current extension if the
138 source channel hangs up.</para>
141 <para>Proceed with dialplan execution at the next priority in the current extension if the
142 destination channel hangs up.</para>
144 <option name="G" argsep="^">
145 <argument name="context" required="false" />
146 <argument name="exten" required="false" />
147 <argument name="priority" required="true" />
148 <para>If the call is answered, transfer the calling party to
149 the specified <replaceable>priority</replaceable> and the called party to the specified
150 <replaceable>priority</replaceable> plus one.</para>
152 <para>You cannot use any additional action post answer options in conjunction with this option.</para>
156 <para>Allow the called party to hang up by sending the <literal>*</literal> DTMF digit.</para>
159 <para>Allow the calling party to hang up by hitting the <literal>*</literal> DTMF digit.</para>
162 <para>Asterisk will ignore any forwarding requests it may receive on this dial attempt.</para>
165 <para>Asterisk will ignore any connected line update requests or redirecting party update
166 requests it may receiveon this dial attempt.</para>
169 <para>Allow the called party to enable parking of the call by sending
170 the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
173 <para>Allow the calling party to enable parking of the call by sending
174 the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
176 <option name="L" argsep=":">
177 <argument name="x" required="true">
178 <para>Maximum call time, in milliseconds</para>
181 <para>Warning time, in milliseconds</para>
184 <para>Repeat time, in milliseconds</para>
186 <para>Limit the call to <replaceable>x</replaceable> milliseconds. Play a warning when <replaceable>y</replaceable> milliseconds are
187 left. Repeat the warning every <replaceable>z</replaceable> milliseconds until time expires.</para>
188 <para>This option is affected by the following variables:</para>
190 <variable name="LIMIT_PLAYAUDIO_CALLER">
191 <value name="yes" default="true" />
193 <para>If set, this variable causes Asterisk to play the prompts to the caller.</para>
195 <variable name="LIMIT_PLAYAUDIO_CALLEE">
197 <value name="no" default="true"/>
198 <para>If set, this variable causes Asterisk to play the prompts to the callee.</para>
200 <variable name="LIMIT_TIMEOUT_FILE">
201 <value name="filename"/>
202 <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the timeout is reached.
203 If not set, the time remaining will be announced.</para>
205 <variable name="LIMIT_CONNECT_FILE">
206 <value name="filename"/>
207 <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the call begins.
208 If not set, the time remaining will be announced.</para>
210 <variable name="LIMIT_WARNING_FILE">
211 <value name="filename"/>
212 <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play as
213 a warning when time <replaceable>x</replaceable> is reached. If not set, the time remaining will be announced.</para>
218 <argument name="class" required="false"/>
219 <para>Provide hold music to the calling party until a requested
220 channel answers. A specific music on hold <replaceable>class</replaceable>
221 (as defined in <filename>musiconhold.conf</filename>) can be specified.</para>
223 <option name="M" argsep="^">
224 <argument name="macro" required="true">
225 <para>Name of the macro that should be executed.</para>
227 <argument name="arg" multiple="true">
228 <para>Macro arguments</para>
230 <para>Execute the specified <replaceable>macro</replaceable> for the <emphasis>called</emphasis> channel
231 before connecting to the calling channel. Arguments can be specified to the Macro
232 using <literal>^</literal> as a delimiter. The macro can set the variable
233 <variable>MACRO_RESULT</variable> to specify the following actions after the macro is
234 finished executing:</para>
236 <variable name="MACRO_RESULT">
237 <para>If set, this action will be taken after the macro finished executing.</para>
239 Hangup both legs of the call
241 <value name="CONGESTION">
242 Behave as if line congestion was encountered
245 Behave as if a busy signal was encountered
247 <value name="CONTINUE">
248 Hangup the called party and allow the calling party to continue dialplan execution at the next priority
250 <!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
251 <value name="GOTO:<context>^<exten>^<priority>">
252 Transfer the call to the specified destination.
257 <para>You cannot use any additional action post answer options in conjunction
258 with this option. Also, pbx services are not run on the peer (called) channel,
259 so you will not be able to set timeouts via the TIMEOUT() function in this macro.</para>
261 <warning><para>Be aware of the limitations that macros have, specifically with regards to use of
262 the <literal>WaitExten</literal> application. For more information, see the documentation for
263 Macro()</para></warning>
266 <para>This option is a modifier for the call screening/privacy mode. (See the
267 <literal>p</literal> and <literal>P</literal> options.) It specifies
268 that no introductions are to be saved in the <directory>priv-callerintros</directory>
272 <para>This option is a modifier for the call screening/privacy mode. It specifies
273 that if Caller*ID is present, do not screen the call.</para>
276 <para>Specify that the Caller*ID that was present on the <emphasis>calling</emphasis> channel
277 be set as the Caller*ID on the <emphasis>called</emphasis> channel. This was the
278 behavior of Asterisk 1.0 and earlier.</para>
281 <argument name="mode">
282 <para>With <replaceable>mode</replaceable> either not specified or set to <literal>1</literal>,
283 the originator hanging up will cause the phone to ring back immediately.</para>
284 <para>With <replaceable>mode</replaceable> set to <literal>2</literal>, when the operator
285 flashes the trunk, it will ring their phone back.</para>
287 <para>Enables <emphasis>operator services</emphasis> mode. This option only
288 works when bridging a DAHDI channel to another DAHDI channel
289 only. if specified on non-DAHDI interfaces, it will be ignored.
290 When the destination answers (presumably an operator services
291 station), the originator no longer has control of their line.
292 They may hang up, but the switch will not release their line
293 until the destination party (the operator) hangs up.</para>
296 <para>This option enables screening mode. This is basically Privacy mode
297 without memory.</para>
300 <argument name="x" />
301 <para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
302 it is provided. The current extension is used if a database family/key is not specified.</para>
305 <para>Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
306 party until the called channel has answered.</para>
309 <argument name="x" required="true" />
310 <para>Hang up the call <replaceable>x</replaceable> seconds <emphasis>after</emphasis> the called party has
311 answered the call.</para>
314 <para>Allow the called party to transfer the calling party by sending the
315 DTMF sequence defined in <filename>features.conf</filename>.</para>
318 <para>Allow the calling party to transfer the called party by sending the
319 DTMF sequence defined in <filename>features.conf</filename>.</para>
321 <option name="U" argsep="^">
322 <argument name="x" required="true">
323 <para>Name of the subroutine to execute via Gosub</para>
325 <argument name="arg" multiple="true" required="false">
326 <para>Arguments for the Gosub routine</para>
328 <para>Execute via Gosub the routine <replaceable>x</replaceable> for the <emphasis>called</emphasis> channel before connecting
329 to the calling channel. Arguments can be specified to the Gosub
330 using <literal>^</literal> as a delimiter. The Gosub routine can set the variable
331 <variable>GOSUB_RESULT</variable> to specify the following actions after the Gosub returns.</para>
333 <variable name="GOSUB_RESULT">
335 Hangup both legs of the call.
337 <value name="CONGESTION">
338 Behave as if line congestion was encountered.
341 Behave as if a busy signal was encountered.
343 <value name="CONTINUE">
344 Hangup the called party and allow the calling party
345 to continue dialplan execution at the next priority.
347 <!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
348 <value name="GOTO:<context>^<exten>^<priority>">
349 Transfer the call to the specified priority. Optionally, an extension, or
350 extension and priority can be specified.
355 <para>You cannot use any additional action post answer options in conjunction
356 with this option. Also, pbx services are not run on the peer (called) channel,
357 so you will not be able to set timeouts via the TIMEOUT() function in this routine.</para>
361 <para>Allow the called party to enable recording of the call by sending
362 the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
365 <para>Allow the calling party to enable recording of the call by sending
366 the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
369 <para>Allow the called party to enable recording of the call by sending
370 the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
373 <para>Allow the calling party to enable recording of the call by sending
374 the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
377 <para>On a call forward, cancel any dial timeout which has been set for this call.</para>
381 <parameter name="URL">
382 <para>The optional URL will be sent to the called party if the channel driver supports it.</para>
386 <para>This application will place calls to one or more specified channels. As soon
387 as one of the requested channels answers, the originating channel will be
388 answered, if it has not already been answered. These two channels will then
389 be active in a bridged call. All other channels that were requested will then
392 <para>Unless there is a timeout specified, the Dial application will wait
393 indefinitely until one of the called channels answers, the user hangs up, or
394 if all of the called channels are busy or unavailable. Dialplan executing will
395 continue if no requested channels can be called, or if the timeout expires.
396 This application will report normal termination if the originating channel
397 hangs up, or if the call is bridged and either of the parties in the bridge
398 ends the call.</para>
399 <para>If the <variable>OUTBOUND_GROUP</variable> variable is set, all peer channels created by this
400 application will be put into that group (as in Set(GROUP()=...).
401 If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
402 application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,
403 however, the variable will be unset after use.</para>
405 <para>This application sets the following channel variables:</para>
407 <variable name="DIALEDTIME">
408 <para>This is the time from dialing a channel until when it is disconnected.</para>
410 <variable name="ANSWEREDTIME">
411 <para>This is the amount of time for actual call.</para>
413 <variable name="DIALSTATUS">
414 <para>This is the status of the call</para>
415 <value name="CHANUNAVAIL" />
416 <value name="CONGESTION" />
417 <value name="NOANSWER" />
418 <value name="BUSY" />
419 <value name="ANSWER" />
420 <value name="CANCEL" />
421 <value name="DONTCALL">
422 For the Privacy and Screening Modes.
423 Will be set if the called party chooses to send the calling party to the 'Go Away' script.
425 <value name="TORTURE">
426 For the Privacy and Screening Modes.
427 Will be set if the called party chooses to send the calling party to the 'torture' script.
429 <value name="INVALIDARGS" />
434 <application name="RetryDial" language="en_US">
436 Place a call, retrying on failure allowing an optional exit extension.
439 <parameter name="announce" required="true">
440 <para>Filename of sound that will be played when no channel can be reached</para>
442 <parameter name="sleep" required="true">
443 <para>Number of seconds to wait after a dial attempt failed before a new attempt is made</para>
445 <parameter name="retries" required="true">
446 <para>Number of retries</para>
447 <para>When this is reached flow will continue at the next priority in the dialplan</para>
449 <parameter name="dialargs" required="true">
450 <para>Same format as arguments provided to the Dial application</para>
454 <para>This application will attempt to place a call using the normal Dial application.
455 If no channel can be reached, the <replaceable>announce</replaceable> file will be played.
456 Then, it will wait <replaceable>sleep</replaceable> number of seconds before retrying the call.
457 After <replaceable>retries</replaceable> number of attempts, the calling channel will continue at the next priority in the dialplan.
458 If the <replaceable>retries</replaceable> setting is set to 0, this application will retry endlessly.
459 While waiting to retry a call, a 1 digit extension may be dialed. If that
460 extension exists in either the context defined in <variable>EXITCONTEXT</variable> or the current
461 one, The call will jump to that extension immediately.
462 The <replaceable>dialargs</replaceable> are specified in the same format that arguments are provided
463 to the Dial application.</para>
468 static char *app = "Dial";
469 static char *rapp = "RetryDial";
472 OPT_ANNOUNCE = (1 << 0),
473 OPT_RESETCDR = (1 << 1),
474 OPT_DTMF_EXIT = (1 << 2),
475 OPT_SENDDTMF = (1 << 3),
476 OPT_FORCECLID = (1 << 4),
477 OPT_GO_ON = (1 << 5),
478 OPT_CALLEE_HANGUP = (1 << 6),
479 OPT_CALLER_HANGUP = (1 << 7),
480 OPT_ORIGINAL_CLID = (1 << 8),
481 OPT_DURATION_LIMIT = (1 << 9),
482 OPT_MUSICBACK = (1 << 10),
483 OPT_CALLEE_MACRO = (1 << 11),
484 OPT_SCREEN_NOINTRO = (1 << 12),
485 OPT_SCREEN_NOCALLERID = (1 << 13),
486 OPT_IGNORE_CONNECTEDLINE = (1 << 14),
487 OPT_SCREENING = (1 << 15),
488 OPT_PRIVACY = (1 << 16),
489 OPT_RINGBACK = (1 << 17),
490 OPT_DURATION_STOP = (1 << 18),
491 OPT_CALLEE_TRANSFER = (1 << 19),
492 OPT_CALLER_TRANSFER = (1 << 20),
493 OPT_CALLEE_MONITOR = (1 << 21),
494 OPT_CALLER_MONITOR = (1 << 22),
495 OPT_GOTO = (1 << 23),
496 OPT_OPERMODE = (1 << 24),
497 OPT_CALLEE_PARK = (1 << 25),
498 OPT_CALLER_PARK = (1 << 26),
499 OPT_IGNORE_FORWARDING = (1 << 27),
500 OPT_CALLEE_GOSUB = (1 << 28),
501 OPT_CALLEE_MIXMONITOR = (1 << 29),
502 OPT_CALLER_MIXMONITOR = (1 << 30),
505 #define DIAL_STILLGOING (1 << 31)
506 #define DIAL_NOFORWARDHTML ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
507 #define DIAL_NOCONNECTEDLINE ((uint64_t)1 << 33)
508 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 34)
509 #define OPT_PEER_H ((uint64_t)1 << 35)
510 #define OPT_CALLEE_GO_ON ((uint64_t)1 << 36)
511 #define OPT_CANCEL_TIMEOUT ((uint64_t)1 << 37)
514 OPT_ARG_ANNOUNCE = 0,
517 OPT_ARG_DURATION_LIMIT,
519 OPT_ARG_CALLEE_MACRO,
520 OPT_ARG_CALLEE_GOSUB,
521 OPT_ARG_CALLEE_GO_ON,
523 OPT_ARG_DURATION_STOP,
525 /* note: this entry _MUST_ be the last one in the enum */
529 AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
530 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
531 AST_APP_OPTION('C', OPT_RESETCDR),
532 AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
533 AST_APP_OPTION('d', OPT_DTMF_EXIT),
534 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
535 AST_APP_OPTION('e', OPT_PEER_H),
536 AST_APP_OPTION('f', OPT_FORCECLID),
537 AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
538 AST_APP_OPTION('g', OPT_GO_ON),
539 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
540 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
541 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
542 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
543 AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
544 AST_APP_OPTION('k', OPT_CALLEE_PARK),
545 AST_APP_OPTION('K', OPT_CALLER_PARK),
546 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
547 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
548 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
549 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
550 AST_APP_OPTION('N', OPT_SCREEN_NOCALLERID),
551 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
552 AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
553 AST_APP_OPTION('p', OPT_SCREENING),
554 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
555 AST_APP_OPTION('r', OPT_RINGBACK),
556 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
557 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
558 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
559 AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
560 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
561 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
562 AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
563 AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
564 AST_APP_OPTION('z', OPT_CANCEL_TIMEOUT),
567 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
568 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
569 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK) && \
570 !chan->audiohooks && !peer->audiohooks)
573 * The list of active channels
576 struct chanlist *next;
577 struct ast_channel *chan;
579 struct ast_party_connected_line connected;
582 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
584 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
586 /* Hang up a tree of stuff */
589 /* Hangup any existing lines we have open */
590 if (outgoing->chan && (outgoing->chan != exception)) {
591 if (answered_elsewhere) {
592 /* The flag is used for local channel inheritance and stuff */
593 ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
594 /* This is for the channel drivers */
595 outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
597 ast_party_connected_line_free(&outgoing->connected);
598 ast_hangup(outgoing->chan);
601 outgoing = outgoing->next;
606 #define AST_MAX_WATCHERS 256
609 * argument to handle_cause() and other functions.
612 struct ast_channel *chan;
618 static void handle_cause(int cause, struct cause_args *num)
620 struct ast_cdr *cdr = num->chan->cdr;
629 case AST_CAUSE_CONGESTION:
635 case AST_CAUSE_NO_ROUTE_DESTINATION:
636 case AST_CAUSE_UNREGISTERED:
642 case AST_CAUSE_NO_ANSWER:
644 ast_cdr_noanswer(cdr);
647 case AST_CAUSE_NORMAL_CLEARING:
656 /* free the buffer if allocated, and set the pointer to the second arg */
657 #define S_REPLACE(s, new_val) \
664 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
666 char rexten[2] = { exten, '\0' };
669 if (!ast_goto_if_exists(chan, context, rexten, pri))
672 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
674 else if (!ast_strlen_zero(chan->macrocontext)) {
675 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
682 /* do not call with chan lock held */
683 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
688 ast_channel_lock(chan);
689 context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
690 exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
691 ast_channel_unlock(chan);
693 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
696 static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
698 manager_event(EVENT_FLAG_CALL, "Dial",
699 "SubEvent: Begin\r\n"
701 "Destination: %s\r\n"
702 "CallerIDNum: %s\r\n"
703 "CallerIDName: %s\r\n"
705 "DestUniqueID: %s\r\n"
706 "Dialstring: %s\r\n",
707 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
708 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
709 dst->uniqueid, dialstring ? dialstring : "");
712 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
714 manager_event(EVENT_FLAG_CALL, "Dial",
718 "DialStatus: %s\r\n",
719 src->name, src->uniqueid, dialstatus);
723 * helper function for wait_for_answer()
725 * XXX this code is highly suspicious, as it essentially overwrites
726 * the outgoing channel without properly deleting it.
728 static void do_forward(struct chanlist *o,
729 struct cause_args *num, struct ast_flags64 *peerflags, int single, int *to)
732 struct ast_channel *original = o->chan;
733 struct ast_channel *c = o->chan; /* the winner */
734 struct ast_channel *in = num->chan; /* the input channel */
735 struct ast_party_redirecting *apr = &o->chan->redirecting;
736 struct ast_party_connected_line *apc = &o->chan->connected;
741 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
742 if ((stuff = strchr(tmpchan, '/'))) {
746 const char *forward_context;
748 forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
749 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
750 ast_channel_unlock(c);
754 /* Before processing channel, go ahead and check for forwarding */
755 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
756 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
757 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
758 ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
760 cause = AST_CAUSE_BUSY;
762 /* Setup parameters */
763 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
766 ast_channel_make_compatible(o->chan, in);
767 ast_channel_inherit_variables(in, o->chan);
768 ast_channel_datastore_inherit(in, o->chan);
770 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
773 ast_clear_flag64(o, DIAL_STILLGOING);
774 handle_cause(cause, num);
775 ast_hangup(original);
778 ast_rtp_instance_early_bridge_make_compatible(c, in);
781 c->cdrflags = in->cdrflags;
783 ast_channel_set_redirecting(c, apr);
785 while (ast_channel_trylock(in)) {
786 CHANNEL_DEADLOCK_AVOIDANCE(c);
788 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(original->cid.cid_rdnis, S_OR(in->macroexten, in->exten))));
790 c->cid.cid_tns = in->cid.cid_tns;
792 if (ast_test_flag64(o, OPT_FORCECLID)) {
793 S_REPLACE(c->cid.cid_num, ast_strdupa(S_OR(in->macroexten, in->exten)));
794 S_REPLACE(c->cid.cid_name, NULL);
795 ast_string_field_set(c, accountcode, c->accountcode);
797 ast_party_caller_copy(&c->cid, &in->cid);
798 ast_string_field_set(c, accountcode, in->accountcode);
800 ast_party_connected_line_copy(&c->connected, apc);
802 S_REPLACE(in->cid.cid_rdnis, ast_strdup(c->cid.cid_rdnis));
803 ast_channel_update_redirecting(in, apr);
805 ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
806 if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
810 ast_channel_unlock(in);
811 ast_channel_unlock(c);
813 if (ast_call(c, tmpchan, 0)) {
814 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
815 ast_clear_flag64(o, DIAL_STILLGOING);
816 ast_hangup(original);
822 while (ast_channel_trylock(in)) {
823 CHANNEL_DEADLOCK_AVOIDANCE(c);
825 senddialevent(in, c, stuff);
826 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
827 char cidname[AST_MAX_EXTENSION] = "";
828 const char *tmpexten;
829 tmpexten = ast_strdupa(S_OR(in->macroexten, in->exten));
830 ast_channel_unlock(in);
831 ast_channel_unlock(c);
832 ast_set_callerid(c, tmpexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
834 ast_channel_unlock(in);
835 ast_channel_unlock(c);
837 /* Hangup the original channel now, in case we needed it */
838 ast_hangup(original);
841 ast_indicate(in, -1);
846 /* argument used for some functions. */
847 struct privacy_args {
851 char privintro[1024];
855 static struct ast_channel *wait_for_answer(struct ast_channel *in,
856 struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
857 struct privacy_args *pa,
858 const struct cause_args *num_in, int *result, char *dtmf_progress)
860 struct cause_args num = *num_in;
861 int prestart = num.busy + num.congestion + num.nochan;
863 struct ast_channel *peer = NULL;
864 /* single is set if only one destination is enabled */
865 int single = outgoing && !outgoing->next;
867 struct chanlist *epollo;
869 struct ast_party_connected_line connected_caller;
870 struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
872 ast_party_connected_line_init(&connected_caller);
874 /* Turn off hold music, etc */
875 if (!ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK))
876 ast_deactivate_generator(in);
878 /* If we are calling a single channel, make them compatible for in-band tone purpose */
879 ast_channel_make_compatible(outgoing->chan, in);
881 if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_NOCONNECTEDLINE)) {
882 ast_channel_lock(outgoing->chan);
883 ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
884 ast_channel_unlock(outgoing->chan);
885 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
886 ast_channel_update_connected_line(in, &connected_caller);
887 ast_party_connected_line_free(&connected_caller);
892 for (epollo = outgoing; epollo; epollo = epollo->next)
893 ast_poll_channel_add(in, epollo->chan);
896 while (*to && !peer) {
898 int pos = 0; /* how many channels do we handle */
899 int numlines = prestart;
900 struct ast_channel *winner;
901 struct ast_channel *watchers[AST_MAX_WATCHERS];
903 watchers[pos++] = in;
904 for (o = outgoing; o; o = o->next) {
905 /* Keep track of important channels */
906 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
907 watchers[pos++] = o->chan;
910 if (pos == 1) { /* only the input channel is available */
911 if (numlines == (num.busy + num.congestion + num.nochan)) {
912 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
914 strcpy(pa->status, "BUSY");
915 else if (num.congestion)
916 strcpy(pa->status, "CONGESTION");
918 strcpy(pa->status, "CHANUNAVAIL");
920 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
925 winner = ast_waitfor_n(watchers, pos, to);
926 for (o = outgoing; o; o = o->next) {
928 struct ast_channel *c = o->chan;
932 if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
934 ast_verb(3, "%s answered %s\n", c->name, in->name);
935 if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
936 if (o->connected.id.number) {
937 ast_channel_update_connected_line(in, &o->connected);
938 } else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
940 ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
941 ast_channel_unlock(c);
942 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
943 ast_channel_update_connected_line(in, &connected_caller);
944 ast_party_connected_line_free(&connected_caller);
948 ast_copy_flags64(peerflags, o,
949 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
950 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
951 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
952 OPT_CALLEE_PARK | OPT_CALLER_PARK |
953 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
955 ast_string_field_set(c, dialcontext, "");
956 ast_copy_string(c->exten, "", sizeof(c->exten));
962 /* here, o->chan == c == winner */
963 if (!ast_strlen_zero(c->call_forward)) {
964 do_forward(o, &num, peerflags, single, to);
967 f = ast_read(winner);
969 in->hangupcause = c->hangupcause;
971 ast_poll_channel_del(in, c);
975 ast_clear_flag64(o, DIAL_STILLGOING);
976 handle_cause(in->hangupcause, &num);
979 if (f->frametype == AST_FRAME_CONTROL) {
980 switch(f->subclass) {
981 case AST_CONTROL_ANSWER:
982 /* This is our guy if someone answered. */
984 ast_verb(3, "%s answered %s\n", c->name, in->name);
985 if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
986 if (o->connected.id.number) {
987 ast_channel_update_connected_line(in, &o->connected);
988 } else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
990 ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
991 ast_channel_unlock(c);
992 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
993 ast_channel_update_connected_line(in, &connected_caller);
994 ast_party_connected_line_free(&connected_caller);
999 peer->cdr->answer = ast_tvnow();
1000 peer->cdr->disposition = AST_CDR_ANSWERED;
1002 ast_copy_flags64(peerflags, o,
1003 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1004 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1005 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1006 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1007 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1008 DIAL_NOFORWARDHTML);
1009 ast_string_field_set(c, dialcontext, "");
1010 ast_copy_string(c->exten, "", sizeof(c->exten));
1011 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
1012 /* Setup early bridge if appropriate */
1013 ast_channel_early_bridge(in, peer);
1015 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
1016 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1017 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1019 case AST_CONTROL_BUSY:
1020 ast_verb(3, "%s is busy\n", c->name);
1021 in->hangupcause = c->hangupcause;
1024 ast_clear_flag64(o, DIAL_STILLGOING);
1025 handle_cause(AST_CAUSE_BUSY, &num);
1027 case AST_CONTROL_CONGESTION:
1028 ast_verb(3, "%s is circuit-busy\n", c->name);
1029 in->hangupcause = c->hangupcause;
1032 ast_clear_flag64(o, DIAL_STILLGOING);
1033 handle_cause(AST_CAUSE_CONGESTION, &num);
1035 case AST_CONTROL_RINGING:
1036 ast_verb(3, "%s is ringing\n", c->name);
1037 /* Setup early media if appropriate */
1038 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1039 ast_channel_early_bridge(in, c);
1040 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
1041 ast_indicate(in, AST_CONTROL_RINGING);
1045 case AST_CONTROL_PROGRESS:
1046 ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
1047 /* Setup early media if appropriate */
1048 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1049 ast_channel_early_bridge(in, c);
1050 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1051 ast_indicate(in, AST_CONTROL_PROGRESS);
1052 if(!ast_strlen_zero(dtmf_progress)) {
1053 ast_verb(3, "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n", dtmf_progress);
1054 ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1057 case AST_CONTROL_VIDUPDATE:
1058 ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
1059 ast_indicate(in, AST_CONTROL_VIDUPDATE);
1061 case AST_CONTROL_SRCUPDATE:
1062 ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
1063 ast_indicate(in, AST_CONTROL_SRCUPDATE);
1065 case AST_CONTROL_CONNECTED_LINE:
1066 if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1067 ast_verb(3, "Connected line update to %s prevented.\n", in->name);
1068 } else if (!single) {
1069 struct ast_party_connected_line connected;
1070 ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", c->name, in->name);
1071 ast_party_connected_line_set_init(&connected, &o->connected);
1072 ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
1073 ast_party_connected_line_set(&o->connected, &connected);
1074 ast_party_connected_line_free(&connected);
1076 ast_verb(3, "%s connected line has changed, passing it to %s\n", c->name, in->name);
1077 ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
1080 case AST_CONTROL_REDIRECTING:
1081 if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1082 ast_verb(3, "Redirecting update to %s prevented.\n", in->name);
1084 ast_verb(3, "%s redirecting info has changed, passing it to %s\n", c->name, in->name);
1085 ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
1088 case AST_CONTROL_PROCEEDING:
1089 ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
1090 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1091 ast_channel_early_bridge(in, c);
1092 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1093 ast_indicate(in, AST_CONTROL_PROCEEDING);
1095 case AST_CONTROL_HOLD:
1096 ast_verb(3, "Call on %s placed on hold\n", c->name);
1097 ast_indicate(in, AST_CONTROL_HOLD);
1099 case AST_CONTROL_UNHOLD:
1100 ast_verb(3, "Call on %s left from hold\n", c->name);
1101 ast_indicate(in, AST_CONTROL_UNHOLD);
1103 case AST_CONTROL_OFFHOOK:
1104 case AST_CONTROL_FLASH:
1105 /* Ignore going off hook and flash */
1108 if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
1109 ast_verb(3, "%s stopped sounds\n", c->name);
1110 ast_indicate(in, -1);
1111 pa->sentringing = 0;
1115 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
1117 } else if (single) {
1118 switch (f->frametype) {
1119 case AST_FRAME_VOICE:
1120 case AST_FRAME_IMAGE:
1121 case AST_FRAME_TEXT:
1122 if (ast_write(in, f)) {
1123 ast_log(LOG_WARNING, "Unable to write frame\n");
1126 case AST_FRAME_HTML:
1127 if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass, f->data.ptr, f->datalen) == -1) {
1128 ast_log(LOG_WARNING, "Unable to send URL\n");
1138 struct ast_frame *f = ast_read(in);
1140 if (f && (f->frametype != AST_FRAME_VOICE))
1141 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1142 else if (!f || (f->frametype != AST_FRAME_VOICE))
1143 printf("Hangup received on %s\n", in->name);
1145 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
1148 strcpy(pa->status, "CANCEL");
1149 ast_cdr_noanswer(in->cdr);
1151 if (f->data.uint32) {
1152 in->hangupcause = f->data.uint32;
1159 /* now f is guaranteed non-NULL */
1160 if (f->frametype == AST_FRAME_DTMF) {
1161 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1162 const char *context;
1163 ast_channel_lock(in);
1164 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1165 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
1166 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
1168 ast_cdr_noanswer(in->cdr);
1169 *result = f->subclass;
1170 strcpy(pa->status, "CANCEL");
1172 ast_channel_unlock(in);
1175 ast_channel_unlock(in);
1178 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1179 detect_disconnect(in, f->subclass, featurecode)) {
1180 ast_verb(3, "User requested call disconnect.\n");
1182 strcpy(pa->status, "CANCEL");
1183 ast_cdr_noanswer(in->cdr);
1189 /* Forward HTML stuff */
1190 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
1191 if (ast_channel_sendhtml(outgoing->chan, f->subclass, f->data.ptr, f->datalen) == -1)
1192 ast_log(LOG_WARNING, "Unable to send URL\n");
1194 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
1195 if (ast_write(outgoing->chan, f))
1196 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
1198 if (single && (f->frametype == AST_FRAME_CONTROL) &&
1199 ((f->subclass == AST_CONTROL_HOLD) ||
1200 (f->subclass == AST_CONTROL_UNHOLD) ||
1201 (f->subclass == AST_CONTROL_VIDUPDATE) ||
1202 (f->subclass == AST_CONTROL_SRCUPDATE) ||
1203 (f->subclass == AST_CONTROL_CONNECTED_LINE) ||
1204 (f->subclass == AST_CONTROL_REDIRECTING))) {
1205 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
1206 ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
1211 ast_verb(3, "Nobody picked up in %d ms\n", orig);
1212 if (!*to || ast_check_hangup(in))
1213 ast_cdr_noanswer(in->cdr);
1217 for (epollo = outgoing; epollo; epollo = epollo->next) {
1219 ast_poll_channel_del(in, epollo->chan);
1226 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
1228 struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
1229 struct ast_call_feature feature = { 0, };
1232 ast_str_append(&featurecode, 1, "%c", code);
1234 res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
1236 if (res != AST_FEATURE_RETURN_STOREDIGITS) {
1237 ast_str_reset(featurecode);
1239 if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
1246 static void replace_macro_delimiter(char *s)
1253 /* returns true if there is a valid privacy reply */
1254 static int valid_priv_reply(struct ast_flags64 *opts, int res)
1258 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1260 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1265 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
1266 char *parse, struct timeval *calldurationlimit)
1268 char *stringp = ast_strdupa(parse);
1269 char *limit_str, *warning_str, *warnfreq_str;
1271 int play_to_caller = 0, play_to_callee = 0;
1274 limit_str = strsep(&stringp, ":");
1275 warning_str = strsep(&stringp, ":");
1276 warnfreq_str = strsep(&stringp, ":");
1278 config->timelimit = atol(limit_str);
1280 config->play_warning = atol(warning_str);
1282 config->warning_freq = atol(warnfreq_str);
1284 if (!config->timelimit) {
1285 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
1286 config->timelimit = config->play_warning = config->warning_freq = 0;
1287 config->warning_sound = NULL;
1288 return -1; /* error */
1289 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
1290 int w = config->warning_freq;
1292 /* If the first warning is requested _after_ the entire call would end,
1293 and no warning frequency is requested, then turn off the warning. If
1294 a warning frequency is requested, reduce the 'first warning' time by
1295 that frequency until it falls within the call's total time limit.
1297 timelim->| delta |<-playwarning
1298 0__________________|_________________|
1301 so the number of intervals to cut is 1+(delta-1)/w
1305 config->play_warning = 0;
1307 config->play_warning -= w * ( 1 + (delta-1)/w );
1308 if (config->play_warning < 1)
1309 config->play_warning = config->warning_freq = 0;
1313 ast_channel_lock(chan);
1315 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
1317 play_to_caller = var ? ast_true(var) : 1;
1319 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
1320 play_to_callee = var ? ast_true(var) : 0;
1322 if (!play_to_caller && !play_to_callee)
1325 var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
1326 config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
1328 /* The code looking at config wants a NULL, not just "", to decide
1329 * that the message should not be played, so we replace "" with NULL.
1330 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
1334 var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
1335 config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
1337 var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
1338 config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
1340 ast_channel_unlock(chan);
1342 /* undo effect of S(x) in case they are both used */
1343 calldurationlimit->tv_sec = 0;
1344 calldurationlimit->tv_usec = 0;
1346 /* more efficient to do it like S(x) does since no advanced opts */
1347 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
1348 calldurationlimit->tv_sec = config->timelimit / 1000;
1349 calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
1350 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
1351 calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
1352 config->timelimit = play_to_caller = play_to_callee =
1353 config->play_warning = config->warning_freq = 0;
1355 ast_verb(3, "Limit Data for this call:\n");
1356 ast_verb(4, "timelimit = %ld\n", config->timelimit);
1357 ast_verb(4, "play_warning = %ld\n", config->play_warning);
1358 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
1359 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
1360 ast_verb(4, "warning_freq = %ld\n", config->warning_freq);
1361 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
1362 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
1363 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
1366 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
1368 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
1372 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
1373 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
1379 /* Get the user's intro, store it in priv-callerintros/$CID,
1380 unless it is already there-- this should be done before the
1381 call is actually dialed */
1383 /* all ring indications and moh for the caller has been halted as soon as the
1384 target extension was picked up. We are going to have to kill some
1385 time and make the caller believe the peer hasn't picked up yet */
1387 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1388 char *original_moh = ast_strdupa(chan->musicclass);
1389 ast_indicate(chan, -1);
1390 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1391 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1392 ast_string_field_set(chan, musicclass, original_moh);
1393 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1394 ast_indicate(chan, AST_CONTROL_RINGING);
1398 /* Start autoservice on the other chan ?? */
1399 res2 = ast_autoservice_start(chan);
1400 /* Now Stream the File */
1401 for (loopcount = 0; loopcount < 3; loopcount++) {
1402 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1404 if (!res2) /* on timeout, play the message again */
1405 res2 = ast_play_and_wait(peer, "priv-callpending");
1406 if (!valid_priv_reply(opts, res2))
1408 /* priv-callpending script:
1409 "I have a caller waiting, who introduces themselves as:"
1412 res2 = ast_play_and_wait(peer, pa->privintro);
1413 if (!valid_priv_reply(opts, res2))
1415 /* now get input from the called party, as to their choice */
1417 /* XXX can we have both, or they are mutually exclusive ? */
1418 if (ast_test_flag64(opts, OPT_PRIVACY))
1419 res2 = ast_play_and_wait(peer, "priv-callee-options");
1420 if (ast_test_flag64(opts, OPT_SCREENING))
1421 res2 = ast_play_and_wait(peer, "screen-callee-options");
1423 /*! \page DialPrivacy Dial Privacy scripts
1424 \par priv-callee-options script:
1425 "Dial 1 if you wish this caller to reach you directly in the future,
1426 and immediately connect to their incoming call
1427 Dial 2 if you wish to send this caller to voicemail now and
1429 Dial 3 to send this caller to the torture menus, now and forevermore.
1430 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1431 Dial 5 to allow this caller to come straight thru to you in the future,
1432 but right now, just this once, send them to voicemail."
1433 \par screen-callee-options script:
1434 "Dial 1 if you wish to immediately connect to the incoming call
1435 Dial 2 if you wish to send this caller to voicemail.
1436 Dial 3 to send this caller to the torture menus.
1437 Dial 4 to send this caller to a simple "go away" menu.
1439 if (valid_priv_reply(opts, res2))
1441 /* invalid option */
1442 res2 = ast_play_and_wait(peer, "vm-sorry");
1445 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
1447 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1448 ast_indicate(chan, -1);
1449 pa->sentringing = 0;
1451 ast_autoservice_stop(chan);
1452 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1453 /* map keypresses to various things, the index is res2 - '1' */
1454 static const char * const _val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1455 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1457 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
1458 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1459 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1465 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1468 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1471 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1474 /* XXX should we set status to DENY ? */
1475 if (ast_test_flag64(opts, OPT_PRIVACY))
1477 /* if not privacy, then 5 is the same as "default" case */
1478 default: /* bad input or -1 if failure to start autoservice */
1479 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1480 /* well, there seems basically two choices. Just patch the caller thru immediately,
1481 or,... put 'em thru to voicemail. */
1482 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1483 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1484 /* XXX should we set status to DENY ? */
1485 /* XXX what about the privacy flags ? */
1489 if (res2 == '1') { /* the only case where we actually connect */
1490 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1491 just clog things up, and it's not useful information, not being tied to a CID */
1492 if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
1493 ast_filedelete(pa->privintro, NULL);
1494 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1495 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1497 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1499 return 0; /* the good exit path */
1501 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1506 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1507 static int setup_privacy_args(struct privacy_args *pa,
1508 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
1513 int silencethreshold;
1515 if (!ast_strlen_zero(chan->cid.cid_num)) {
1516 l = ast_strdupa(chan->cid.cid_num);
1517 ast_shrink_phone_number(l);
1518 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1519 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
1520 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1522 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1523 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1528 tnam = ast_strdupa(chan->name);
1529 /* clean the channel name so slashes don't try to end up in disk file name */
1530 for (tn2 = tnam; *tn2; tn2++) {
1531 if (*tn2 == '/') /* any other chars to be afraid of? */
1534 ast_verb(3, "Privacy-- callerid is empty\n");
1536 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1538 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1541 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
1543 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
1544 /* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
1545 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1546 pa->privdb_val = AST_PRIVACY_ALLOW;
1547 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
1548 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1551 if (pa->privdb_val == AST_PRIVACY_DENY) {
1552 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1553 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1555 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
1556 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1557 return 0; /* Is this right? */
1558 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
1559 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1560 return 0; /* is this right??? */
1561 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
1562 /* Get the user's intro, store it in priv-callerintros/$CID,
1563 unless it is already there-- this should be done before the
1564 call is actually dialed */
1566 /* make sure the priv-callerintros dir actually exists */
1567 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1568 if ((res = ast_mkdir(pa->privintro, 0755))) {
1569 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1573 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1574 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1575 /* the DELUX version of this code would allow this caller the
1576 option to hear and retape their previously recorded intro.
1579 int duration; /* for feedback from play_and_wait */
1580 /* the file doesn't exist yet. Let the caller submit his
1581 vocal intro for posterity */
1582 /* priv-recordintro script:
1584 "At the tone, please say your name:"
1587 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
1589 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1590 /* don't think we'll need a lock removed, we took care of
1591 conflicts by naming the pa.privintro file */
1593 /* Delete the file regardless since they hung up during recording */
1594 ast_filedelete(pa->privintro, NULL);
1595 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1596 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1598 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1601 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1602 ast_waitstream(chan, "");
1605 return 1; /* success */
1608 static void end_bridge_callback(void *data)
1612 struct ast_channel *chan = data;
1620 ast_channel_lock(chan);
1621 if (chan->cdr->answer.tv_sec) {
1622 snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
1623 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
1626 if (chan->cdr->start.tv_sec) {
1627 snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
1628 pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
1630 ast_channel_unlock(chan);
1633 static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
1634 bconfig->end_bridge_callback_data = originator;
1637 static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
1639 int res = -1; /* default: error */
1640 char *rest, *cur; /* scan the list of destinations */
1641 struct chanlist *outgoing = NULL; /* list of destinations */
1642 struct ast_channel *peer;
1643 int to; /* timeout */
1644 struct cause_args num = { chan, 0, 0, 0 };
1647 char cidname[AST_MAX_EXTENSION] = "";
1649 struct ast_bridge_config config = { { 0, } };
1650 struct timeval calldurationlimit = { 0, };
1651 char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
1652 struct privacy_args pa = {
1655 .status = "INVALIDARGS",
1657 int sentringing = 0, moh = 0;
1658 const char *outbound_group = NULL;
1662 AST_DECLARE_APP_ARGS(args,
1664 AST_APP_ARG(timeout);
1665 AST_APP_ARG(options);
1668 struct ast_flags64 opts = { 0, };
1669 char *opt_args[OPT_ARG_ARRAY_SIZE];
1670 struct ast_datastore *datastore = NULL;
1671 int fulldial = 0, num_dialed = 0;
1673 /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
1674 pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
1675 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
1676 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
1677 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
1678 pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
1680 if (ast_strlen_zero(data)) {
1681 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1682 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1686 parse = ast_strdupa(data);
1688 AST_STANDARD_APP_ARGS(args, parse);
1690 if (!ast_strlen_zero(args.options) &&
1691 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
1692 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1696 if (ast_strlen_zero(args.peers)) {
1697 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1698 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1702 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
1703 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1704 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
1707 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1708 calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1709 if (!calldurationlimit.tv_sec) {
1710 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1711 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1714 ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
1717 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1718 dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
1719 dtmfcalled = strsep(&dtmf_progress, ":");
1720 dtmfcalling = strsep(&dtmf_progress, ":");
1723 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1724 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1728 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
1729 ast_cdr_reset(chan->cdr, NULL);
1730 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1731 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1733 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
1734 res = setup_privacy_args(&pa, &opts, opt_args, chan);
1737 res = -1; /* reset default */
1740 if (ast_test_flag64(&opts, OPT_DTMF_EXIT) || ast_test_flag64(&opts, OPT_CALLER_HANGUP)) {
1741 __ast_answer(chan, 0, 0);
1747 /* If a channel group has been specified, get it for use when we create peer channels */
1749 ast_channel_lock(chan);
1750 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1751 outbound_group = ast_strdupa(outbound_group);
1752 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1753 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
1754 outbound_group = ast_strdupa(outbound_group);
1756 ast_channel_unlock(chan);
1757 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE | OPT_CANCEL_TIMEOUT);
1759 /* loop through the list of dial destinations */
1761 while ((cur = strsep(&rest, "&")) ) {
1762 struct chanlist *tmp;
1763 struct ast_channel *tc; /* channel for this destination */
1764 /* Get a technology/[device:]number pair */
1766 char *interface = ast_strdupa(number);
1767 char *tech = strsep(&number, "/");
1768 /* find if we already dialed this interface */
1769 struct ast_dialed_interface *di;
1770 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1773 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1776 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1779 ast_copy_flags64(tmp, &opts,
1780 OPT_CANCEL_ELSEWHERE |
1781 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1782 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1783 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1784 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1785 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1786 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1787 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
1789 ast_copy_string(numsubst, number, sizeof(numsubst));
1790 /* Request the peer */
1792 ast_channel_lock(chan);
1793 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1794 /* If the incoming channel has previously had connected line information
1795 * set on it (perhaps through the CONNECTED_LINE dialplan function) then
1796 * seed the calllist's connected line information with this previously
1799 if (chan->connected.id.number) {
1800 ast_party_connected_line_copy(&tmp->connected, &chan->connected);
1802 ast_channel_unlock(chan);
1805 dialed_interfaces = datastore->data;
1807 if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
1808 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1813 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1815 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1820 datastore->data = dialed_interfaces;
1821 AST_LIST_HEAD_INIT(dialed_interfaces);
1823 ast_channel_lock(chan);
1824 ast_channel_datastore_add(chan, datastore);
1825 ast_channel_unlock(chan);
1828 AST_LIST_LOCK(dialed_interfaces);
1829 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1830 if (!strcasecmp(di->interface, interface)) {
1831 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1836 AST_LIST_UNLOCK(dialed_interfaces);
1844 /* It is always ok to dial a Local interface. We only keep track of
1845 * which "real" interfaces have been dialed. The Local channel will
1846 * inherit this list so that if it ends up dialing a real interface,
1847 * it won't call one that has already been called. */
1848 if (strcasecmp(tech, "Local")) {
1849 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1850 AST_LIST_UNLOCK(dialed_interfaces);
1854 strcpy(di->interface, interface);
1856 AST_LIST_LOCK(dialed_interfaces);
1857 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1858 AST_LIST_UNLOCK(dialed_interfaces);
1861 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
1863 /* If we can't, just go on to the next call */
1864 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1865 tech, cause, ast_cause2str(cause));
1866 handle_cause(cause, &num);
1867 if (!rest) /* we are on the last destination */
1868 chan->hangupcause = cause;
1872 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1874 ast_channel_lock(tc);
1875 while (ast_channel_trylock(chan)) {
1876 CHANNEL_DEADLOCK_AVOIDANCE(tc);
1878 /* Setup outgoing SDP to match incoming one */
1879 if (!outgoing && !rest) {
1880 ast_rtp_instance_early_bridge_make_compatible(tc, chan);
1883 /* Inherit specially named variables from parent channel */
1884 ast_channel_inherit_variables(chan, tc);
1885 ast_channel_datastore_inherit(chan, tc);
1887 tc->appl = "AppDial";
1888 tc->data = "(Outgoing Line)";
1889 memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
1891 /* If the new channel has no callerid, try to guess what it should be */
1892 if (ast_strlen_zero(tc->cid.cid_num)) {
1893 if (!ast_strlen_zero(chan->connected.id.number)) {
1894 ast_set_callerid(tc, chan->connected.id.number, chan->connected.id.name, chan->connected.ani);
1895 } else if (!ast_strlen_zero(chan->cid.cid_dnid)) {
1896 ast_set_callerid(tc, chan->cid.cid_dnid, NULL, NULL);
1897 } else if (!ast_strlen_zero(S_OR(chan->macroexten, chan->exten))) {
1898 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), NULL, NULL);
1900 ast_set_flag64(tmp, DIAL_NOCONNECTEDLINE);
1903 ast_connected_line_copy_from_caller(&tc->connected, &chan->cid);
1905 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
1906 ast_party_redirecting_copy(&tc->redirecting, &chan->redirecting);
1908 tc->cid.cid_tns = chan->cid.cid_tns;
1910 ast_string_field_set(tc, accountcode, chan->accountcode);
1911 tc->cdrflags = chan->cdrflags;
1912 if (ast_strlen_zero(tc->musicclass))
1913 ast_string_field_set(tc, musicclass, chan->musicclass);
1915 /* Pass ADSI CPE and transfer capability */
1916 tc->adsicpe = chan->adsicpe;
1917 tc->transfercapability = chan->transfercapability;
1919 /* If we have an outbound group, set this peer channel to it */
1921 ast_app_group_set_channel(tc, outbound_group);
1922 /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
1923 if (ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE))
1924 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
1926 /* Check if we're forced by configuration */
1927 if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
1928 ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
1931 /* Inherit context and extension */
1932 ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
1933 if (!ast_strlen_zero(chan->macroexten))
1934 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
1936 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
1938 ast_channel_unlock(tc);
1939 res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
1941 /* Save the info in cdr's that we called them */
1943 ast_cdr_setdestchan(chan->cdr, tc->name);
1945 /* check the results of ast_call */
1947 /* Again, keep going even if there's an error */
1948 ast_debug(1, "ast call on peer returned %d\n", res);
1949 ast_verb(3, "Couldn't call %s\n", numsubst);
1950 if (tc->hangupcause) {
1951 chan->hangupcause = tc->hangupcause;
1953 ast_channel_unlock(chan);
1959 const char *tmpexten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
1960 senddialevent(chan, tc, numsubst);
1961 ast_verb(3, "Called %s\n", numsubst);
1962 ast_channel_unlock(chan);
1963 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
1964 ast_set_callerid(tc, tmpexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
1967 /* Put them in the list of outgoing thingies... We're ready now.
1968 XXX If we're forcibly removed, these outgoing calls won't get
1970 ast_set_flag64(tmp, DIAL_STILLGOING);
1972 tmp->next = outgoing;
1974 /* If this line is up, don't try anybody else */
1975 if (outgoing->chan->_state == AST_STATE_UP)
1979 if (ast_strlen_zero(args.timeout)) {
1982 to = atoi(args.timeout);
1986 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
1992 strcpy(pa.status, "CHANUNAVAIL");
1993 if (fulldial == num_dialed) {
1998 /* Our status will at least be NOANSWER */
1999 strcpy(pa.status, "NOANSWER");
2000 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
2002 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
2003 char *original_moh = ast_strdupa(chan->musicclass);
2004 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
2005 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
2006 ast_string_field_set(chan, musicclass, original_moh);
2008 ast_moh_start(chan, NULL, NULL);
2010 ast_indicate(chan, AST_CONTROL_PROGRESS);
2011 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
2012 ast_indicate(chan, AST_CONTROL_RINGING);
2017 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result, dtmf_progress);
2019 /* The ast_channel_datastore_remove() function could fail here if the
2020 * datastore was moved to another channel during a masquerade. If this is
2021 * the case, don't free the datastore here because later, when the channel
2022 * to which the datastore was moved hangs up, it will attempt to free this
2023 * datastore again, causing a crash
2025 if (!ast_channel_datastore_remove(chan, datastore))
2026 ast_datastore_free(datastore);
2030 } else if (to) { /* Musta gotten hung up */
2032 } else { /* Nobody answered, next please? */
2036 /* SIP, in particular, sends back this error code to indicate an
2037 * overlap dialled number needs more digits. */
2038 if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
2039 res = AST_PBX_INCOMPLETE;
2042 /* almost done, although the 'else' block is 400 lines */
2046 strcpy(pa.status, "ANSWER");
2047 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2048 /* Ah ha! Someone answered within the desired timeframe. Of course after this
2049 we will always return with -1 so that it is hung up properly after the
2051 hanguptree(outgoing, peer, 1);
2053 /* If appropriate, log that we have a destination channel */
2055 ast_cdr_setdestchan(chan->cdr, peer->name);
2057 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
2059 ast_channel_lock(peer);
2060 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
2063 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
2064 ast_channel_unlock(peer);
2066 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
2067 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
2068 ast_channel_sendurl( peer, args.url );
2070 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
2071 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
2076 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
2080 /* Start autoservice on the other chan */
2081 res = ast_autoservice_start(chan);
2082 /* Now Stream the File */
2084 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
2086 digit = ast_waitstream(peer, AST_DIGIT_ANY);
2088 /* Ok, done. stop autoservice */
2089 res = ast_autoservice_stop(chan);
2090 if (digit > 0 && !res)
2091 res = ast_senddigit(chan, digit, 0);
2097 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
2098 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
2099 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
2100 /* peer goes to the same context and extension as chan, so just copy info from chan*/
2101 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
2102 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
2103 peer->priority = chan->priority + 2;
2104 ast_pbx_start(peer);
2105 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
2112 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
2113 struct ast_app *theapp;
2114 const char *macro_result;
2116 res = ast_autoservice_start(chan);
2118 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2122 theapp = pbx_findapp("Macro");
2124 if (theapp && !res) { /* XXX why check res here ? */
2125 /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
2126 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
2127 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
2129 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
2130 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
2131 ast_debug(1, "Macro exited with status %d\n", res);
2134 ast_log(LOG_ERROR, "Could not find application Macro\n");
2138 if (ast_autoservice_stop(chan) < 0) {
2139 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2143 ast_channel_lock(peer);
2145 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
2146 char *macro_transfer_dest;
2148 if (!strcasecmp(macro_result, "BUSY")) {
2149 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
2150 ast_set_flag64(peerflags, OPT_GO_ON);
2152 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
2153 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
2154 ast_set_flag64(peerflags, OPT_GO_ON);
2156 } else if (!strcasecmp(macro_result, "CONTINUE")) {
2157 /* hangup peer and keep chan alive assuming the macro has changed
2158 the context / exten / priority or perhaps
2159 the next priority in the current exten is desired.
2161 ast_set_flag64(peerflags, OPT_GO_ON);
2163 } else if (!strcasecmp(macro_result, "ABORT")) {
2164 /* Hangup both ends unless the caller has the g flag */
2166 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
2168 /* perform a transfer to a new extension */
2169 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
2170 replace_macro_delimiter(macro_transfer_dest);
2171 if (!ast_parseable_goto(chan, macro_transfer_dest))
2172 ast_set_flag64(peerflags, OPT_GO_ON);
2177 ast_channel_unlock(peer);
2180 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
2181 struct ast_app *theapp;
2182 const char *gosub_result;
2183 char *gosub_args, *gosub_argstart;
2186 res9 = ast_autoservice_start(chan);
2188 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2192 theapp = pbx_findapp("Gosub");
2194 if (theapp && !res9) {
2195 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
2197 /* Set where we came from */
2198 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
2199 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
2202 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
2203 if (gosub_argstart) {
2204 *gosub_argstart = 0;
2205 if (asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1) < 0) {
2206 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
2209 *gosub_argstart = ',';
2211 if (asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]) < 0) {
2212 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
2218 res9 = pbx_exec(peer, theapp, gosub_args);
2220 struct ast_pbx_args args;
2221 /* A struct initializer fails to compile for this case ... */
2222 memset(&args, 0, sizeof(args));
2223 args.no_hangup_chan = 1;
2224 ast_pbx_run_args(peer, &args);
2226 ast_free(gosub_args);
2227 ast_debug(1, "Gosub exited with status %d\n", res9);
2229 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
2233 ast_log(LOG_ERROR, "Could not find application Gosub\n");
2237 if (ast_autoservice_stop(chan) < 0) {
2238 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2242 ast_channel_lock(peer);
2244 if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
2245 char *gosub_transfer_dest;
2247 if (!strcasecmp(gosub_result, "BUSY")) {
2248 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
2249 ast_set_flag64(peerflags, OPT_GO_ON);
2251 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
2252 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
2253 ast_set_flag64(peerflags, OPT_GO_ON);
2255 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
2256 /* hangup peer and keep chan alive assuming the macro has changed
2257 the context / exten / priority or perhaps
2258 the next priority in the current exten is desired.
2260 ast_set_flag64(peerflags, OPT_GO_ON);
2262 } else if (!strcasecmp(gosub_result, "ABORT")) {
2263 /* Hangup both ends unless the caller has the g flag */
2265 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
2267 /* perform a transfer to a new extension */
2268 if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
2269 replace_macro_delimiter(gosub_transfer_dest);
2270 if (!ast_parseable_goto(chan, gosub_transfer_dest))
2271 ast_set_flag64(peerflags, OPT_GO_ON);
2276 ast_channel_unlock(peer);
2280 if (!ast_tvzero(calldurationlimit)) {
2281 struct timeval whentohangup = calldurationlimit;
2282 peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
2284 if (!ast_strlen_zero(dtmfcalled)) {
2285 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
2286 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
2288 if (!ast_strlen_zero(dtmfcalling)) {
2289 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
2290 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
2294 if (res) { /* some error */
2297 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
2298 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
2299 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
2300 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
2301 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
2302 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
2303 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
2304 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
2305 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
2306 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
2307 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
2308 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
2309 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
2310 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
2311 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
2312 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
2313 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
2314 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
2315 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
2316 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
2317 if (ast_test_flag64(peerflags, OPT_GO_ON))
2318 ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
2320 config.end_bridge_callback = end_bridge_callback;
2321 config.end_bridge_callback_data = chan;
2322 config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
2327 } else if (sentringing) {
2329 ast_indicate(chan, -1);
2331 /* Be sure no generators are left on it */
2332 ast_deactivate_generator(chan);
2333 /* Make sure channels are compatible */
2334 res = ast_channel_make_compatible(chan, peer);
2336 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
2342 struct oprmode oprmode;
2344 oprmode.peer = peer;
2345 oprmode.mode = opermode;
2347 ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
2349 res = ast_bridge_call(chan, peer, &config);
2352 strcpy(peer->context, chan->context);
2354 if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
2359 strcpy(peer->exten, "h");
2361 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
2362 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
2364 while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
2367 if (found && res9) {
2368 /* Something bad happened, or a hangup has been requested. */
2369 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
2370 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
2372 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
2374 if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON)) {
2375 if(!ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
2376 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
2377 ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
2380 res = ast_goto_if_exists(peer, chan->context, chan->exten, (chan->priority) + 1);
2381 if (res == AST_PBX_GOTO_FAILED) {
2386 ast_pbx_start(peer);
2388 if (!ast_check_hangup(chan))
2389 chan->hangupcause = peer->hangupcause;
2397 } else if (sentringing) {
2399 ast_indicate(chan, -1);
2401 ast_channel_early_bridge(chan, NULL);
2402 hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
2403 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
2404 senddialendevent(chan, pa.status);
2405 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
2407 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
2408 if (!ast_tvzero(calldurationlimit))
2409 memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
2414 if (config.warning_sound) {
2415 ast_free((char *)config.warning_sound);
2417 if (config.end_sound) {
2418 ast_free((char *)config.end_sound);
2420 if (config.start_sound) {
2421 ast_free((char *)config.start_sound);
2426 static int dial_exec(struct ast_channel *chan, const char *data)
2428 struct ast_flags64 peerflags;
2430 memset(&peerflags, 0, sizeof(peerflags));
2432 return dial_exec_full(chan, data, &peerflags, NULL);
2435 static int retrydial_exec(struct ast_channel *chan, const char *data)
2438 const char *context = NULL;
2439 int sleepms = 0, loops = 0, res = -1;
2440 struct ast_flags64 peerflags = { 0, };
2441 AST_DECLARE_APP_ARGS(args,
2442 AST_APP_ARG(announce);
2444 AST_APP_ARG(retries);
2445 AST_APP_ARG(dialdata);
2448 if (ast_strlen_zero(data)) {
2449 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
2453 parse = ast_strdupa(data);
2454 AST_STANDARD_APP_ARGS(args, parse);
2456 if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
2459 if (!ast_strlen_zero(args.retries)) {
2460 loops = atoi(args.retries);
2463 if (!args.dialdata) {
2464 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
2472 loops = -1; /* run forever */
2474 ast_channel_lock(chan);
2475 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
2476 context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
2477 ast_channel_unlock(chan);
2483 chan->data = "Retrying";
2484 if (ast_test_flag(chan, AST_FLAG_MOH))
2487 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
2492 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
2493 if (!ast_strlen_zero(args.announce)) {
2494 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
2495 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
2496 ast_waitstream(chan, AST_DIGIT_ANY);
2498 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
2500 if (!res && sleepms) {
2501 if (!ast_test_flag(chan, AST_FLAG_MOH))
2502 ast_moh_start(chan, NULL, NULL);
2503 res = ast_waitfordigit(chan, sleepms);
2506 if (!ast_strlen_zero(args.announce)) {
2507 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
2508 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
2509 res = ast_waitstream(chan, "");
2511 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
2514 if (!ast_test_flag(chan, AST_FLAG_MOH))
2515 ast_moh_start(chan, NULL, NULL);
2517 res = ast_waitfordigit(chan, sleepms);
2522 if (res < 0 || res == AST_PBX_INCOMPLETE) {
2524 } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
2525 if (onedigit_goto(chan, context, (char) res, 1)) {
2537 if (ast_test_flag(chan, AST_FLAG_MOH))
2543 static int unload_module(void)
2546 struct ast_context *con;
2548 res = ast_unregister_application(app);
2549 res |= ast_unregister_application(rapp);
2551 if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
2552 ast_context_remove_extension2(con, "s", 1, NULL, 0);
2553 ast_context_destroy(con, "app_dial"); /* leave nothing behind */
2559 static int load_module(void)
2562 struct ast_context *con;
2564 con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
2566 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
2568 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
2570 res = ast_register_application_xml(app, dial_exec);
2571 res |= ast_register_application_xml(rapp, retrydial_exec);
2576 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");