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 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$")
44 #include <sys/signal.h>
46 #include <netinet/in.h>
48 #include "asterisk/lock.h"
49 #include "asterisk/file.h"
50 #include "asterisk/logger.h"
51 #include "asterisk/channel.h"
52 #include "asterisk/pbx.h"
53 #include "asterisk/options.h"
54 #include "asterisk/module.h"
55 #include "asterisk/translate.h"
56 #include "asterisk/say.h"
57 #include "asterisk/config.h"
58 #include "asterisk/features.h"
59 #include "asterisk/musiconhold.h"
60 #include "asterisk/callerid.h"
61 #include "asterisk/utils.h"
62 #include "asterisk/app.h"
63 #include "asterisk/causes.h"
64 #include "asterisk/rtp.h"
65 #include "asterisk/cdr.h"
66 #include "asterisk/manager.h"
67 #include "asterisk/privacy.h"
68 #include "asterisk/stringfields.h"
69 #include "asterisk/global_datastores.h"
71 static char *app
= "Dial";
73 static char *synopsis
= "Place a call and connect to the current channel";
75 static char *descrip
=
76 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
77 "This application will place calls to one or more specified channels. As soon\n"
78 "as one of the requested channels answers, the originating channel will be\n"
79 "answered, if it has not already been answered. These two channels will then\n"
80 "be active in a bridged call. All other channels that were requested will then\n"
82 " Unless there is a timeout specified, the Dial application will wait\n"
83 "indefinitely until one of the called channels answers, the user hangs up, or\n"
84 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
85 "continue if no requested channels can be called, or if the timeout expires.\n\n"
86 " This application sets the following channel variables upon completion:\n"
87 " DIALEDTIME - This is the time from dialing a channel until when it\n"
89 " ANSWEREDTIME - This is the amount of time for actual call.\n"
90 " DIALSTATUS - This is the status of the call:\n"
91 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
92 " DONTCALL | TORTURE | INVALIDARGS\n"
93 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
94 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
95 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
96 "wants to send the caller to the 'torture' script.\n"
97 " This application will report normal termination if the originating channel\n"
98 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
100 " The optional URL will be sent to the called party if the channel supports it.\n"
101 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
102 "application will be put into that group (as in Set(GROUP()=...).\n"
103 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
104 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
105 "however, the variable will be unset after use.\n\n"
107 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
108 " C - Reset the CDR for this call.\n"
109 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
110 " a call to be answered. Exit to that extension if it exists in the\n"
111 " current context, or the context defined in the EXITCONTEXT variable,\n"
113 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
114 " party has answered, but before the call gets bridged. The 'called'\n"
115 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
116 " string is sent to the calling party. Both parameters can be used\n"
118 " f - Force the callerid of the *calling* channel to be set as the\n"
119 " extension associated with the channel using a dialplan 'hint'.\n"
120 " For example, some PSTNs do not allow CallerID to be set to anything\n"
121 " other than the number assigned to the caller.\n"
122 " g - Proceed with dialplan execution at the current extension if the\n"
123 " destination channel hangs up.\n"
124 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
125 " the specified priority and the called party to the specified priority+1.\n"
126 " Optionally, an extension, or extension and context may be specified. \n"
127 " Otherwise, the current extension is used. You cannot use any additional\n"
128 " action post answer options in conjunction with this option.\n"
129 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
130 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
131 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
133 " j - Jump to priority n+101 if all of the requested channels were busy.\n"
134 " k - Allow the called party to enable parking of the call by sending\n"
135 " the DTMF sequence defined for call parking in features.conf.\n"
136 " K - Allow the calling party to enable parking of the call by sending\n"
137 " the DTMF sequence defined for call parking in features.conf.\n"
138 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
139 " left. Repeat the warning every 'z' ms. The following special\n"
140 " variables can be used with this option:\n"
141 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
142 " Play sounds to the caller.\n"
143 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
144 " Play sounds to the callee.\n"
145 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
146 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
147 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
148 " The default is to say the time remaining.\n"
149 " m([class]) - Provide hold music to the calling party until a requested\n"
150 " channel answers. A specific MusicOnHold class can be\n"
152 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
153 " to the calling channel. Arguments can be specified to the Macro\n"
154 " using '^' as a delimeter. The Macro can set the variable\n"
155 " MACRO_RESULT to specify the following actions after the Macro is\n"
156 " finished executing.\n"
157 " * ABORT Hangup both legs of the call.\n"
158 " * CONGESTION Behave as if line congestion was encountered.\n"
159 " * BUSY Behave as if a busy signal was encountered. This will also\n"
160 " have the application jump to priority n+101 if the\n"
161 " 'j' option is set.\n"
162 " * CONTINUE Hangup the called party and allow the calling party\n"
163 " to continue dialplan execution at the next priority.\n"
164 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
165 " specified priority. Optionally, an extension, or\n"
166 " extension and priority can be specified.\n"
167 " You cannot use any additional action post answer options in conjunction\n"
168 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
169 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
170 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
171 " that no introductions are to be saved in the priv-callerintros\n"
173 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
174 " that if callerID is present, do not screen the call.\n"
175 " o - Specify that the CallerID that was present on the *calling* channel\n"
176 " be set as the CallerID on the *called* channel. This was the\n"
177 " behavior of Asterisk 1.0 and earlier.\n"
178 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
179 " only, if specified on non-Zaptel interface, it will be ignored).\n"
180 " When the destination answers (presumably an operator services\n"
181 " station), the originator no longer has control of their line.\n"
182 " They may hang up, but the switch will not release their line\n"
183 " until the destination party hangs up (the operator). Specified\n"
184 " without an arg, or with 1 as an arg, the originator hanging up\n"
185 " will cause the phone to ring back immediately. With a 2 specified,\n"
186 " when the \"operator\" flashes the trunk, it will ring their phone\n"
188 " p - This option enables screening mode. This is basically Privacy mode\n"
190 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
191 " it is provided. The current extension is used if a database\n"
192 " family/key is not specified.\n"
193 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
194 " party until the called channel has answered.\n"
195 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
196 " answered the call.\n"
197 " t - Allow the called party to transfer the calling party by sending the\n"
198 " DTMF sequence defined in features.conf.\n"
199 " T - Allow the calling party to transfer the called party by sending the\n"
200 " DTMF sequence defined in features.conf.\n"
201 " w - Allow the called party to enable recording of the call by sending\n"
202 " the DTMF sequence defined for one-touch recording in features.conf.\n"
203 " W - Allow the calling party to enable recording of the call by sending\n"
204 " the DTMF sequence defined for one-touch recording in features.conf.\n";
206 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
207 static char *rapp
= "RetryDial";
208 static char *rsynopsis
= "Place a call, retrying on failure allowing optional exit extension.";
209 static char *rdescrip
=
210 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
211 "place a call using the normal Dial application. If no channel can be reached,\n"
212 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
213 "seconds before retrying the call. After 'retries' number of attempts, the\n"
214 "calling channel will continue at the next priority in the dialplan. If the\n"
215 "'retries' setting is set to 0, this application will retry endlessly.\n"
216 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
217 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
218 "one, The call will jump to that extension immediately.\n"
219 " The 'dialargs' are specified in the same format that arguments are provided\n"
220 "to the Dial application.\n";
223 OPT_ANNOUNCE
= (1 << 0),
224 OPT_RESETCDR
= (1 << 1),
225 OPT_DTMF_EXIT
= (1 << 2),
226 OPT_SENDDTMF
= (1 << 3),
227 OPT_FORCECLID
= (1 << 4),
228 OPT_GO_ON
= (1 << 5),
229 OPT_CALLEE_HANGUP
= (1 << 6),
230 OPT_CALLER_HANGUP
= (1 << 7),
231 OPT_PRIORITY_JUMP
= (1 << 8),
232 OPT_DURATION_LIMIT
= (1 << 9),
233 OPT_MUSICBACK
= (1 << 10),
234 OPT_CALLEE_MACRO
= (1 << 11),
235 OPT_SCREEN_NOINTRO
= (1 << 12),
236 OPT_SCREEN_NOCLID
= (1 << 13),
237 OPT_ORIGINAL_CLID
= (1 << 14),
238 OPT_SCREENING
= (1 << 15),
239 OPT_PRIVACY
= (1 << 16),
240 OPT_RINGBACK
= (1 << 17),
241 OPT_DURATION_STOP
= (1 << 18),
242 OPT_CALLEE_TRANSFER
= (1 << 19),
243 OPT_CALLER_TRANSFER
= (1 << 20),
244 OPT_CALLEE_MONITOR
= (1 << 21),
245 OPT_CALLER_MONITOR
= (1 << 22),
246 OPT_GOTO
= (1 << 23),
247 OPT_OPERMODE
= (1 << 24),
248 OPT_CALLEE_PARK
= (1 << 25),
249 OPT_CALLER_PARK
= (1 << 26),
250 OPT_IGNORE_FORWARDING
= (1 << 27),
251 } dial_exec_option_flags
;
253 #define DIAL_STILLGOING (1 << 30)
254 #define DIAL_NOFORWARDHTML (1 << 31)
257 OPT_ARG_ANNOUNCE
= 0,
260 OPT_ARG_DURATION_LIMIT
,
262 OPT_ARG_CALLEE_MACRO
,
264 OPT_ARG_DURATION_STOP
,
266 /* note: this entry _MUST_ be the last one in the enum */
268 } dial_exec_option_args
;
270 AST_APP_OPTIONS(dial_exec_options
, {
271 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE
, OPT_ARG_ANNOUNCE
),
272 AST_APP_OPTION('C', OPT_RESETCDR
),
273 AST_APP_OPTION('d', OPT_DTMF_EXIT
),
274 AST_APP_OPTION_ARG('D', OPT_SENDDTMF
, OPT_ARG_SENDDTMF
),
275 AST_APP_OPTION('f', OPT_FORCECLID
),
276 AST_APP_OPTION('g', OPT_GO_ON
),
277 AST_APP_OPTION_ARG('G', OPT_GOTO
, OPT_ARG_GOTO
),
278 AST_APP_OPTION('h', OPT_CALLEE_HANGUP
),
279 AST_APP_OPTION('H', OPT_CALLER_HANGUP
),
280 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING
),
281 AST_APP_OPTION('j', OPT_PRIORITY_JUMP
),
282 AST_APP_OPTION('k', OPT_CALLEE_PARK
),
283 AST_APP_OPTION('K', OPT_CALLER_PARK
),
284 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT
, OPT_ARG_DURATION_LIMIT
),
285 AST_APP_OPTION_ARG('m', OPT_MUSICBACK
, OPT_ARG_MUSICBACK
),
286 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO
, OPT_ARG_CALLEE_MACRO
),
287 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO
),
288 AST_APP_OPTION('N', OPT_SCREEN_NOCLID
),
289 AST_APP_OPTION('o', OPT_ORIGINAL_CLID
),
290 AST_APP_OPTION_ARG('O', OPT_OPERMODE
,OPT_ARG_OPERMODE
),
291 AST_APP_OPTION('p', OPT_SCREENING
),
292 AST_APP_OPTION_ARG('P', OPT_PRIVACY
, OPT_ARG_PRIVACY
),
293 AST_APP_OPTION('r', OPT_RINGBACK
),
294 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP
, OPT_ARG_DURATION_STOP
),
295 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER
),
296 AST_APP_OPTION('T', OPT_CALLER_TRANSFER
),
297 AST_APP_OPTION('w', OPT_CALLEE_MONITOR
),
298 AST_APP_OPTION('W', OPT_CALLER_MONITOR
),
301 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag(flags, OPT_CALLEE_HANGUP | \
302 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
303 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK) && \
304 !chan->audiohooks && !peer->audiohooks)
306 /* We define a custom "local user" structure because we
307 use it not only for keeping track of what is in use but
308 also for keeping track of who we're dialing. */
310 struct dial_localuser
{
311 struct ast_channel
*chan
;
313 struct dial_localuser
*next
;
317 static void hanguptree(struct dial_localuser
*outgoing
, struct ast_channel
*exception
)
319 /* Hang up a tree of stuff */
320 struct dial_localuser
*oo
;
322 /* Hangup any existing lines we have open */
323 if (outgoing
->chan
&& (outgoing
->chan
!= exception
))
324 ast_hangup(outgoing
->chan
);
326 outgoing
=outgoing
->next
;
331 #define AST_MAX_WATCHERS 256
333 #define HANDLE_CAUSE(cause, chan) do { \
335 case AST_CAUSE_BUSY: \
337 ast_cdr_busy(chan->cdr); \
340 case AST_CAUSE_CONGESTION: \
342 ast_cdr_failed(chan->cdr); \
345 case AST_CAUSE_NO_ROUTE_DESTINATION: \
346 case AST_CAUSE_UNREGISTERED: \
348 ast_cdr_failed(chan->cdr); \
351 case AST_CAUSE_NORMAL_CLEARING: \
360 static int onedigit_goto(struct ast_channel
*chan
, const char *context
, char exten
, int pri
)
362 char rexten
[2] = { exten
, '\0' };
365 if (!ast_goto_if_exists(chan
, context
, rexten
, pri
))
368 if (!ast_goto_if_exists(chan
, chan
->context
, rexten
, pri
))
370 else if (!ast_strlen_zero(chan
->macrocontext
)) {
371 if (!ast_goto_if_exists(chan
, chan
->macrocontext
, rexten
, pri
))
379 static const char *get_cid_name(char *name
, int namelen
, struct ast_channel
*chan
)
381 const char *context
= S_OR(chan
->macrocontext
, chan
->context
);
382 const char *exten
= S_OR(chan
->macroexten
, chan
->exten
);
384 return ast_get_hint(NULL
, 0, name
, namelen
, chan
, context
, exten
) ? name
: "";
387 static void senddialevent(struct ast_channel
*src
, struct ast_channel
*dst
)
389 /* XXX do we need also CallerIDnum ? */
390 manager_event(EVENT_FLAG_CALL
, "Dial",
392 "Destination: %s\r\n"
394 "CallerIDName: %s\r\n"
395 "SrcUniqueID: %s\r\n"
396 "DestUniqueID: %s\r\n",
397 src
->name
, dst
->name
, S_OR(src
->cid
.cid_num
, "<unknown>"),
398 S_OR(src
->cid
.cid_name
, "<unknown>"), src
->uniqueid
,
402 static struct ast_channel
*wait_for_answer(struct ast_channel
*in
, struct dial_localuser
*outgoing
, int *to
, struct ast_flags
*peerflags
, int *sentringing
, char *status
, size_t statussize
, int busystart
, int nochanstart
, int congestionstart
, int priority_jump
, int *result
)
404 int numbusy
= busystart
;
405 int numcongestion
= congestionstart
;
406 int numnochan
= nochanstart
;
407 int prestart
= busystart
+ congestionstart
+ nochanstart
;
409 struct ast_channel
*peer
= NULL
;
410 /* single is set if only one destination is enabled */
411 int single
= outgoing
&& !outgoing
->next
&& !ast_test_flag(outgoing
, OPT_MUSICBACK
| OPT_RINGBACK
);
414 /* Turn off hold music, etc */
415 ast_deactivate_generator(in
);
416 /* If we are calling a single channel, make them compatible for in-band tone purpose */
417 ast_channel_make_compatible(outgoing
->chan
, in
);
421 while (*to
&& !peer
) {
422 struct dial_localuser
*o
;
423 int pos
= 0; /* how many channels do we handle */
424 int numlines
= prestart
;
425 struct ast_channel
*winner
;
426 struct ast_channel
*watchers
[AST_MAX_WATCHERS
];
428 watchers
[pos
++] = in
;
429 for (o
= outgoing
; o
; o
= o
->next
) {
430 /* Keep track of important channels */
431 if (ast_test_flag(o
, DIAL_STILLGOING
) && o
->chan
)
432 watchers
[pos
++] = o
->chan
;
435 if (pos
== 1) { /* only the input channel is available */
436 if (numlines
== (numbusy
+ numcongestion
+ numnochan
)) {
437 if (option_verbose
> 2)
438 ast_verbose( VERBOSE_PREFIX_2
"Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines
, numbusy
, numcongestion
, numnochan
);
440 strcpy(status
, "BUSY");
441 else if (numcongestion
)
442 strcpy(status
, "CONGESTION");
444 strcpy(status
, "CHANUNAVAIL");
445 if (ast_opt_priority_jumping
|| priority_jump
)
446 ast_goto_if_exists(in
, in
->context
, in
->exten
, in
->priority
+ 101);
448 if (option_verbose
> 2)
449 ast_verbose(VERBOSE_PREFIX_3
"No one is available to answer at this time (%d:%d/%d/%d)\n", numlines
, numbusy
, numcongestion
, numnochan
);
454 winner
= ast_waitfor_n(watchers
, pos
, to
);
455 for (o
= outgoing
; o
; o
= o
->next
) {
457 struct ast_channel
*c
= o
->chan
;
461 if (ast_test_flag(o
, DIAL_STILLGOING
) && c
->_state
== AST_STATE_UP
) {
463 if (option_verbose
> 2)
464 ast_verbose(VERBOSE_PREFIX_3
"%s answered %s\n", c
->name
, in
->name
);
466 ast_copy_flags(peerflags
, o
,
467 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
468 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
469 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
470 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
472 ast_copy_string(c
->dialcontext
, "", sizeof(c
->dialcontext
));
473 ast_copy_string(c
->exten
, "", sizeof(c
->exten
));
479 if (!ast_strlen_zero(c
->call_forward
)) {
485 ast_copy_string(tmpchan
, c
->call_forward
, sizeof(tmpchan
));
486 if ((stuff
= strchr(tmpchan
, '/'))) {
490 const char *forward_context
= pbx_builtin_getvar_helper(c
, "FORWARD_CONTEXT");
491 snprintf(tmpchan
, sizeof(tmpchan
), "%s@%s", c
->call_forward
, forward_context
? forward_context
: c
->context
);
495 /* Before processing channel, go ahead and check for forwarding */
496 if (option_verbose
> 2)
497 ast_verbose(VERBOSE_PREFIX_3
"Now forwarding %s to '%s/%s' (thanks to %s)\n", in
->name
, tech
, stuff
, c
->name
);
498 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
499 if (ast_test_flag(peerflags
, OPT_IGNORE_FORWARDING
)) {
500 if (option_verbose
> 2)
501 ast_verbose(VERBOSE_PREFIX_3
"Forwarding %s to '%s/%s' prevented.\n", in
->name
, tech
, stuff
);
503 cause
= AST_CAUSE_BUSY
;
505 /* Setup parameters */
506 if ((c
= o
->chan
= ast_request(tech
, in
->nativeformats
, stuff
, &cause
))) {
508 ast_channel_make_compatible(o
->chan
, in
);
509 ast_channel_inherit_variables(in
, o
->chan
);
510 ast_channel_datastore_inherit(in
, o
->chan
);
512 ast_log(LOG_NOTICE
, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech
, stuff
, cause
);
515 ast_clear_flag(o
, DIAL_STILLGOING
);
516 HANDLE_CAUSE(cause
, in
);
518 ast_rtp_make_compatible(c
, in
, single
);
520 free(c
->cid
.cid_num
);
521 c
->cid
.cid_num
= NULL
;
523 free(c
->cid
.cid_name
);
524 c
->cid
.cid_name
= NULL
;
526 if (ast_test_flag(o
, OPT_FORCECLID
)) {
527 c
->cid
.cid_num
= ast_strdup(S_OR(in
->macroexten
, in
->exten
));
528 ast_string_field_set(c
, accountcode
, winner
->accountcode
);
529 c
->cdrflags
= winner
->cdrflags
;
531 c
->cid
.cid_num
= ast_strdup(in
->cid
.cid_num
);
532 c
->cid
.cid_name
= ast_strdup(in
->cid
.cid_name
);
533 ast_string_field_set(c
, accountcode
, in
->accountcode
);
534 c
->cdrflags
= in
->cdrflags
;
537 if (in
->cid
.cid_ani
) {
539 free(c
->cid
.cid_ani
);
540 c
->cid
.cid_ani
= ast_strdup(in
->cid
.cid_ani
);
542 if (c
->cid
.cid_rdnis
)
543 free(c
->cid
.cid_rdnis
);
544 c
->cid
.cid_rdnis
= ast_strdup(S_OR(in
->macroexten
, in
->exten
));
545 if (ast_call(c
, tmpchan
, 0)) {
546 ast_log(LOG_NOTICE
, "Failed to dial on local channel for call forward to '%s'\n", tmpchan
);
547 ast_clear_flag(o
, DIAL_STILLGOING
);
552 senddialevent(in
, c
);
553 /* After calling, set callerid to extension */
554 if (!ast_test_flag(peerflags
, OPT_ORIGINAL_CLID
)) {
555 char cidname
[AST_MAX_EXTENSION
] = "";
556 ast_set_callerid(c
, S_OR(in
->macroexten
, in
->exten
), get_cid_name(cidname
, sizeof(cidname
), in
), NULL
);
560 /* Hangup the original channel now, in case we needed it */
564 f
= ast_read(winner
);
566 in
->hangupcause
= c
->hangupcause
;
569 ast_clear_flag(o
, DIAL_STILLGOING
);
570 HANDLE_CAUSE(in
->hangupcause
, in
);
573 if (f
->frametype
== AST_FRAME_CONTROL
) {
574 switch(f
->subclass
) {
575 case AST_CONTROL_ANSWER
:
576 /* This is our guy if someone answered. */
578 if (option_verbose
> 2)
579 ast_verbose( VERBOSE_PREFIX_3
"%s answered %s\n", c
->name
, in
->name
);
581 ast_copy_flags(peerflags
, o
,
582 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
583 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
584 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
585 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
587 ast_copy_string(c
->dialcontext
, "", sizeof(c
->dialcontext
));
588 ast_copy_string(c
->exten
, "", sizeof(c
->exten
));
589 /* Setup RTP early bridge if appropriate */
590 if (CAN_EARLY_BRIDGE(peerflags
, in
, peer
))
591 ast_rtp_early_bridge(in
, peer
);
593 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
594 in
->hangupcause
= AST_CAUSE_NORMAL_CLEARING
;
595 c
->hangupcause
= AST_CAUSE_NORMAL_CLEARING
;
597 case AST_CONTROL_BUSY
:
598 if (option_verbose
> 2)
599 ast_verbose(VERBOSE_PREFIX_3
"%s is busy\n", c
->name
);
600 in
->hangupcause
= c
->hangupcause
;
603 ast_clear_flag(o
, DIAL_STILLGOING
);
604 HANDLE_CAUSE(AST_CAUSE_BUSY
, in
);
606 case AST_CONTROL_CONGESTION
:
607 if (option_verbose
> 2)
608 ast_verbose(VERBOSE_PREFIX_3
"%s is circuit-busy\n", c
->name
);
609 in
->hangupcause
= c
->hangupcause
;
612 ast_clear_flag(o
, DIAL_STILLGOING
);
613 HANDLE_CAUSE(AST_CAUSE_CONGESTION
, in
);
615 case AST_CONTROL_RINGING
:
616 if (option_verbose
> 2)
617 ast_verbose(VERBOSE_PREFIX_3
"%s is ringing\n", c
->name
);
618 /* Setup early media if appropriate */
619 if (single
&& CAN_EARLY_BRIDGE(peerflags
, in
, c
))
620 ast_rtp_early_bridge(in
, c
);
621 if (!(*sentringing
) && !ast_test_flag(outgoing
, OPT_MUSICBACK
)) {
622 ast_indicate(in
, AST_CONTROL_RINGING
);
626 case AST_CONTROL_PROGRESS
:
627 if (option_verbose
> 2)
628 ast_verbose (VERBOSE_PREFIX_3
"%s is making progress passing it to %s\n", c
->name
, in
->name
);
629 /* Setup early media if appropriate */
630 if (single
&& CAN_EARLY_BRIDGE(peerflags
, in
, c
))
631 ast_rtp_early_bridge(in
, c
);
632 if (!ast_test_flag(outgoing
, OPT_RINGBACK
))
633 ast_indicate(in
, AST_CONTROL_PROGRESS
);
635 case AST_CONTROL_VIDUPDATE
:
636 if (option_verbose
> 2)
637 ast_verbose (VERBOSE_PREFIX_3
"%s requested a video update, passing it to %s\n", c
->name
, in
->name
);
638 ast_indicate(in
, AST_CONTROL_VIDUPDATE
);
640 case AST_CONTROL_SRCUPDATE
:
641 if (option_verbose
> 2)
642 ast_verbose (VERBOSE_PREFIX_3
"%s requested a source update, passing it to %s\n", c
->name
, in
->name
);
643 ast_indicate(in
, AST_CONTROL_SRCUPDATE
);
645 case AST_CONTROL_PROCEEDING
:
646 if (option_verbose
> 2)
647 ast_verbose (VERBOSE_PREFIX_3
"%s is proceeding passing it to %s\n", c
->name
, in
->name
);
648 if (single
&& CAN_EARLY_BRIDGE(peerflags
, in
, c
))
649 ast_rtp_early_bridge(in
, c
);
650 if (!ast_test_flag(outgoing
, OPT_RINGBACK
))
651 ast_indicate(in
, AST_CONTROL_PROCEEDING
);
653 case AST_CONTROL_HOLD
:
654 if (option_verbose
> 2)
655 ast_verbose(VERBOSE_PREFIX_3
"Call on %s placed on hold\n", c
->name
);
656 ast_indicate(in
, AST_CONTROL_HOLD
);
658 case AST_CONTROL_UNHOLD
:
659 if (option_verbose
> 2)
660 ast_verbose(VERBOSE_PREFIX_3
"Call on %s left from hold\n", c
->name
);
661 ast_indicate(in
, AST_CONTROL_UNHOLD
);
663 case AST_CONTROL_OFFHOOK
:
664 case AST_CONTROL_FLASH
:
665 /* Ignore going off hook and flash */
668 if (!ast_test_flag(outgoing
, OPT_RINGBACK
| OPT_MUSICBACK
)) {
669 if (option_verbose
> 2)
670 ast_verbose(VERBOSE_PREFIX_3
"%s stopped sounds\n", c
->name
);
671 ast_indicate(in
, -1);
677 ast_log(LOG_DEBUG
, "Dunno what to do with control type %d\n", f
->subclass
);
680 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
681 if (f
->frametype
== AST_FRAME_VOICE
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
682 if (ast_write(in
, f
))
683 ast_log(LOG_WARNING
, "Unable to forward voice frame\n");
684 } else if (f
->frametype
== AST_FRAME_IMAGE
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
685 if (ast_write(in
, f
))
686 ast_log(LOG_WARNING
, "Unable to forward image\n");
687 } else if (f
->frametype
== AST_FRAME_TEXT
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
688 if (ast_write(in
, f
))
689 ast_log(LOG_WARNING
, "Unable to send text\n");
690 } else if (f
->frametype
== AST_FRAME_HTML
&& !ast_test_flag(outgoing
, DIAL_NOFORWARDHTML
)) {
691 if (ast_channel_sendhtml(in
, f
->subclass
, f
->data
, f
->datalen
) == -1)
692 ast_log(LOG_WARNING
, "Unable to send URL\n");
698 struct ast_frame
*f
= ast_read(in
);
700 if (f
&& (f
->frametype
!= AST_FRAME_VOICE
))
701 printf("Frame type: %d, %d\n", f
->frametype
, f
->subclass
);
702 else if (!f
|| (f
->frametype
!= AST_FRAME_VOICE
))
703 printf("Hangup received on %s\n", in
->name
);
705 if (!f
|| ((f
->frametype
== AST_FRAME_CONTROL
) && (f
->subclass
== AST_CONTROL_HANGUP
))) {
708 ast_cdr_noanswer(in
->cdr
);
709 strcpy(status
, "CANCEL");
715 if (f
&& (f
->frametype
== AST_FRAME_DTMF
)) {
716 if (ast_test_flag(peerflags
, OPT_DTMF_EXIT
)) {
717 const char *context
= pbx_builtin_getvar_helper(in
, "EXITCONTEXT");
718 if (onedigit_goto(in
, context
, (char) f
->subclass
, 1)) {
719 if (option_verbose
> 2)
720 ast_verbose(VERBOSE_PREFIX_3
"User hit %c to disconnect call.\n", f
->subclass
);
722 ast_cdr_noanswer(in
->cdr
);
723 *result
= f
->subclass
;
724 strcpy(status
, "CANCEL");
730 if (ast_test_flag(peerflags
, OPT_CALLER_HANGUP
) &&
731 (f
->subclass
== '*')) { /* hmm it it not guaranteed to be '*' anymore. */
732 if (option_verbose
> 2)
733 ast_verbose(VERBOSE_PREFIX_3
"User hit %c to disconnect call.\n", f
->subclass
);
735 ast_cdr_noanswer(in
->cdr
);
736 strcpy(status
, "CANCEL");
742 /* Forward HTML stuff */
743 if (single
&& f
&& (f
->frametype
== AST_FRAME_HTML
) && !ast_test_flag(outgoing
, DIAL_NOFORWARDHTML
))
744 if(ast_channel_sendhtml(outgoing
->chan
, f
->subclass
, f
->data
, f
->datalen
) == -1)
745 ast_log(LOG_WARNING
, "Unable to send URL\n");
748 if (single
&& ((f
->frametype
== AST_FRAME_VOICE
) || (f
->frametype
== AST_FRAME_DTMF_BEGIN
) || (f
->frametype
== AST_FRAME_DTMF_END
))) {
749 if (ast_write(outgoing
->chan
, f
))
750 ast_log(LOG_WARNING
, "Unable to forward voice or dtmf\n");
752 if (single
&& (f
->frametype
== AST_FRAME_CONTROL
) &&
753 ((f
->subclass
== AST_CONTROL_HOLD
) ||
754 (f
->subclass
== AST_CONTROL_UNHOLD
) ||
755 (f
->subclass
== AST_CONTROL_VIDUPDATE
) ||
756 (f
->subclass
== AST_CONTROL_SRCUPDATE
))) {
757 if (option_verbose
> 2)
758 ast_verbose(VERBOSE_PREFIX_3
"%s requested special control %d, passing it to %s\n", in
->name
, f
->subclass
, outgoing
->chan
->name
);
759 ast_indicate_data(outgoing
->chan
, f
->subclass
, f
->data
, f
->datalen
);
763 if (!*to
&& (option_verbose
> 2))
764 ast_verbose(VERBOSE_PREFIX_3
"Nobody picked up in %d ms\n", orig
);
765 if (!*to
|| ast_check_hangup(in
)) {
766 ast_cdr_noanswer(in
->cdr
);
774 static void replace_macro_delimiter(char *s
)
782 /* returns true if there is a valid privacy reply */
783 static int valid_priv_reply(struct ast_flags
*opts
, int res
)
787 if (ast_test_flag(opts
, OPT_PRIVACY
) && res
<= '5')
789 if (ast_test_flag(opts
, OPT_SCREENING
) && res
<= '4')
794 static void set_dial_features(struct ast_flags
*opts
, struct ast_dial_features
*features
)
796 struct ast_flags perm_opts
= {.flags
= 0};
798 ast_copy_flags(&perm_opts
, opts
,
799 OPT_CALLER_TRANSFER
| OPT_CALLER_PARK
| OPT_CALLER_MONITOR
| OPT_CALLER_HANGUP
|
800 OPT_CALLEE_TRANSFER
| OPT_CALLEE_PARK
| OPT_CALLEE_MONITOR
| OPT_CALLEE_HANGUP
);
802 memset(features
->options
, 0, sizeof(features
->options
));
804 ast_app_options2str(dial_exec_options
, &perm_opts
, features
->options
, sizeof(features
->options
));
805 if (ast_test_flag(&perm_opts
, OPT_CALLEE_TRANSFER
))
806 ast_set_flag(&(features
->features_callee
), AST_FEATURE_REDIRECT
);
807 if (ast_test_flag(&perm_opts
, OPT_CALLER_TRANSFER
))
808 ast_set_flag(&(features
->features_caller
), AST_FEATURE_REDIRECT
);
809 if (ast_test_flag(&perm_opts
, OPT_CALLEE_HANGUP
))
810 ast_set_flag(&(features
->features_callee
), AST_FEATURE_DISCONNECT
);
811 if (ast_test_flag(&perm_opts
, OPT_CALLER_HANGUP
))
812 ast_set_flag(&(features
->features_caller
), AST_FEATURE_DISCONNECT
);
813 if (ast_test_flag(&perm_opts
, OPT_CALLEE_MONITOR
))
814 ast_set_flag(&(features
->features_callee
), AST_FEATURE_AUTOMON
);
815 if (ast_test_flag(&perm_opts
, OPT_CALLER_MONITOR
))
816 ast_set_flag(&(features
->features_caller
), AST_FEATURE_AUTOMON
);
817 if (ast_test_flag(&perm_opts
, OPT_CALLEE_PARK
))
818 ast_set_flag(&(features
->features_callee
), AST_FEATURE_PARKCALL
);
819 if (ast_test_flag(&perm_opts
, OPT_CALLER_PARK
))
820 ast_set_flag(&(features
->features_caller
), AST_FEATURE_PARKCALL
);
823 static int dial_exec_full(struct ast_channel
*chan
, void *data
, struct ast_flags
*peerflags
, int *continue_exec
)
826 struct ast_module_user
*u
;
828 struct dial_localuser
*outgoing
= NULL
;
829 struct ast_channel
*peer
;
832 int numcongestion
= 0;
836 char cidname
[AST_MAX_EXTENSION
] = "";
838 unsigned int calldurationlimit
= 0;
840 long play_warning
= 0;
841 long warning_freq
= 0;
842 const char *warning_sound
= NULL
;
843 const char *end_sound
= NULL
;
844 const char *start_sound
= NULL
;
845 char *dtmfcalled
= NULL
, *dtmfcalling
= NULL
;
846 char status
[256] = "INVALIDARGS";
847 int play_to_caller
= 0, play_to_callee
= 0;
848 int sentringing
= 0, moh
= 0;
849 const char *outbound_group
= NULL
;
852 char privintro
[1024];
856 AST_DECLARE_APP_ARGS(args
,
858 AST_APP_ARG(timeout
);
859 AST_APP_ARG(options
);
862 struct ast_flags opts
= { 0, };
863 char *opt_args
[OPT_ARG_ARRAY_SIZE
];
864 struct ast_datastore
*datastore
= NULL
;
865 struct ast_datastore
*ds_caller_features
= NULL
;
866 struct ast_datastore
*ds_callee_features
= NULL
;
867 struct ast_dial_features
*caller_features
;
868 int fulldial
= 0, num_dialed
= 0;
870 if (ast_strlen_zero(data
)) {
871 ast_log(LOG_WARNING
, "Dial requires an argument (technology/number)\n");
872 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
876 u
= ast_module_user_add(chan
);
878 parse
= ast_strdupa(data
);
880 AST_STANDARD_APP_ARGS(args
, parse
);
882 if (!ast_strlen_zero(args
.options
) &&
883 ast_app_parse_options(dial_exec_options
, &opts
, opt_args
, args
.options
)) {
884 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
888 if (ast_strlen_zero(args
.peers
)) {
889 ast_log(LOG_WARNING
, "Dial requires an argument (technology/number)\n");
890 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
894 if (ast_test_flag(&opts
, OPT_OPERMODE
)) {
895 if (ast_strlen_zero(opt_args
[OPT_ARG_OPERMODE
]))
897 else opermode
= atoi(opt_args
[OPT_ARG_OPERMODE
]);
898 if (option_verbose
> 2)
899 ast_verbose(VERBOSE_PREFIX_3
"Setting operator services mode to %d.\n", opermode
);
902 if (ast_test_flag(&opts
, OPT_DURATION_STOP
) && !ast_strlen_zero(opt_args
[OPT_ARG_DURATION_STOP
])) {
903 calldurationlimit
= atoi(opt_args
[OPT_ARG_DURATION_STOP
]);
904 if (!calldurationlimit
) {
905 ast_log(LOG_WARNING
, "Dial does not accept S(%s), hanging up.\n", opt_args
[OPT_ARG_DURATION_STOP
]);
906 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
909 if (option_verbose
> 2)
910 ast_verbose(VERBOSE_PREFIX_3
"Setting call duration limit to %d seconds.\n", calldurationlimit
);
913 if (ast_test_flag(&opts
, OPT_SENDDTMF
) && !ast_strlen_zero(opt_args
[OPT_ARG_SENDDTMF
])) {
914 dtmfcalling
= opt_args
[OPT_ARG_SENDDTMF
];
915 dtmfcalled
= strsep(&dtmfcalling
, ":");
918 if (ast_test_flag(&opts
, OPT_DURATION_LIMIT
) && !ast_strlen_zero(opt_args
[OPT_ARG_DURATION_LIMIT
])) {
919 char *limit_str
, *warning_str
, *warnfreq_str
;
922 warnfreq_str
= opt_args
[OPT_ARG_DURATION_LIMIT
];
923 limit_str
= strsep(&warnfreq_str
, ":");
924 warning_str
= strsep(&warnfreq_str
, ":");
926 timelimit
= atol(limit_str
);
928 play_warning
= atol(warning_str
);
930 warning_freq
= atol(warnfreq_str
);
933 ast_log(LOG_WARNING
, "Dial does not accept L(%s), hanging up.\n", limit_str
);
935 } else if (play_warning
> timelimit
) {
936 /* If the first warning is requested _after_ the entire call would end,
937 and no warning frequency is requested, then turn off the warning. If
938 a warning frequency is requested, reduce the 'first warning' time by
939 that frequency until it falls within the call's total time limit.
946 while (play_warning
> timelimit
)
947 play_warning
-= warning_freq
;
948 if (play_warning
< 1)
949 play_warning
= warning_freq
= 0;
953 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_PLAYAUDIO_CALLER");
954 play_to_caller
= var
? ast_true(var
) : 1;
956 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_PLAYAUDIO_CALLEE");
957 play_to_callee
= var
? ast_true(var
) : 0;
959 if (!play_to_caller
&& !play_to_callee
)
962 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_WARNING_FILE");
963 warning_sound
= S_OR(var
, "timeleft");
965 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_TIMEOUT_FILE");
966 end_sound
= S_OR(var
, NULL
); /* XXX not much of a point in doing this! */
968 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_CONNECT_FILE");
969 start_sound
= S_OR(var
, NULL
); /* XXX not much of a point in doing this! */
971 /* undo effect of S(x) in case they are both used */
972 calldurationlimit
= 0;
973 /* more efficient to do it like S(x) does since no advanced opts */
974 if (!play_warning
&& !start_sound
&& !end_sound
&& timelimit
) {
975 calldurationlimit
= timelimit
/ 1000;
976 if (option_verbose
> 2)
977 ast_verbose(VERBOSE_PREFIX_3
"Setting call duration limit to %d seconds.\n", calldurationlimit
);
978 timelimit
= play_to_caller
= play_to_callee
= play_warning
= warning_freq
= 0;
979 } else if (option_verbose
> 2) {
980 ast_verbose(VERBOSE_PREFIX_3
"Limit Data for this call:\n");
981 ast_verbose(VERBOSE_PREFIX_4
"timelimit = %ld\n", timelimit
);
982 ast_verbose(VERBOSE_PREFIX_4
"play_warning = %ld\n", play_warning
);
983 ast_verbose(VERBOSE_PREFIX_4
"play_to_caller = %s\n", play_to_caller
? "yes" : "no");
984 ast_verbose(VERBOSE_PREFIX_4
"play_to_callee = %s\n", play_to_callee
? "yes" : "no");
985 ast_verbose(VERBOSE_PREFIX_4
"warning_freq = %ld\n", warning_freq
);
986 ast_verbose(VERBOSE_PREFIX_4
"start_sound = %s\n", start_sound
);
987 ast_verbose(VERBOSE_PREFIX_4
"warning_sound = %s\n", warning_sound
);
988 ast_verbose(VERBOSE_PREFIX_4
"end_sound = %s\n", end_sound
);
992 if (ast_test_flag(&opts
, OPT_RESETCDR
) && chan
->cdr
)
993 ast_cdr_reset(chan
->cdr
, NULL
);
994 if (ast_test_flag(&opts
, OPT_PRIVACY
) && ast_strlen_zero(opt_args
[OPT_ARG_PRIVACY
]))
995 opt_args
[OPT_ARG_PRIVACY
] = ast_strdupa(chan
->exten
);
996 if (ast_test_flag(&opts
, OPT_PRIVACY
) || ast_test_flag(&opts
, OPT_SCREENING
)) {
998 char *l
= chan
->cid
.cid_num
; /* XXX watch out, we are overwriting it */
999 if (!ast_strlen_zero(l
)) {
1000 ast_shrink_phone_number(l
);
1001 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1002 if (option_verbose
> 2)
1003 ast_verbose(VERBOSE_PREFIX_3
"Privacy DB is '%s', clid is '%s'\n",
1004 opt_args
[OPT_ARG_PRIVACY
], l
);
1005 privdb_val
= ast_privacy_check(opt_args
[OPT_ARG_PRIVACY
], l
);
1008 if (option_verbose
> 2)
1009 ast_verbose(VERBOSE_PREFIX_3
"Privacy Screening, clid is '%s'\n", l
);
1010 privdb_val
= AST_PRIVACY_UNKNOWN
;
1015 tnam
= ast_strdupa(chan
->name
);
1016 /* clean the channel name so slashes don't try to end up in disk file name */
1017 for(tn2
= tnam
; *tn2
; tn2
++) {
1019 *tn2
= '='; /* any other chars to be afraid of? */
1021 if (option_verbose
> 2)
1022 ast_verbose(VERBOSE_PREFIX_3
"Privacy-- callerid is empty\n");
1024 snprintf(callerid
, sizeof(callerid
), "NOCALLERID_%s%s", chan
->exten
, tnam
);
1026 privdb_val
= AST_PRIVACY_UNKNOWN
;
1029 ast_copy_string(privcid
,l
,sizeof(privcid
));
1031 if( strncmp(privcid
,"NOCALLERID",10) != 0 && ast_test_flag(&opts
, OPT_SCREEN_NOCLID
) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */
1032 if (option_verbose
> 2)
1033 ast_verbose( VERBOSE_PREFIX_3
"CallerID set (%s); N option set; Screening should be off\n", privcid
);
1034 privdb_val
= AST_PRIVACY_ALLOW
;
1036 else if(ast_test_flag(&opts
, OPT_SCREEN_NOCLID
) && strncmp(privcid
,"NOCALLERID",10) == 0 ) {
1037 if (option_verbose
> 2)
1038 ast_verbose( VERBOSE_PREFIX_3
"CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val
);
1041 if(privdb_val
== AST_PRIVACY_DENY
) {
1042 ast_copy_string(status
, "NOANSWER", sizeof(status
));
1043 if (option_verbose
> 2)
1044 ast_verbose( VERBOSE_PREFIX_3
"Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1048 else if(privdb_val
== AST_PRIVACY_KILL
) {
1049 ast_copy_string(status
, "DONTCALL", sizeof(status
));
1050 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1051 ast_goto_if_exists(chan
, chan
->context
, chan
->exten
, chan
->priority
+ 201);
1054 goto out
; /* Is this right? */
1056 else if(privdb_val
== AST_PRIVACY_TORTURE
) {
1057 ast_copy_string(status
, "TORTURE", sizeof(status
));
1058 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1059 ast_goto_if_exists(chan
, chan
->context
, chan
->exten
, chan
->priority
+ 301);
1062 goto out
; /* is this right??? */
1064 else if(privdb_val
== AST_PRIVACY_UNKNOWN
) {
1065 /* Get the user's intro, store it in priv-callerintros/$CID,
1066 unless it is already there-- this should be done before the
1067 call is actually dialed */
1069 /* make sure the priv-callerintros dir actually exists */
1070 snprintf(privintro
, sizeof(privintro
), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR
);
1071 if (mkdir(privintro
, 0755) && errno
!= EEXIST
) {
1072 ast_log(LOG_WARNING
, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno
));
1077 snprintf(privintro
,sizeof(privintro
), "priv-callerintros/%s", privcid
);
1078 if( ast_fileexists(privintro
,NULL
,NULL
) > 0 && strncmp(privcid
,"NOCALLERID",10) != 0) {
1079 /* the DELUX version of this code would allow this caller the
1080 option to hear and retape their previously recorded intro.
1084 int duration
; /* for feedback from play_and_wait */
1085 /* the file doesn't exist yet. Let the caller submit his
1086 vocal intro for posterity */
1087 /* priv-recordintro script:
1089 "At the tone, please say your name:"
1093 res
= ast_play_and_record(chan
, "priv-recordintro", privintro
, 4, "gsm", &duration
, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1094 /* don't think we'll need a lock removed, we took care of
1095 conflicts by naming the privintro file */
1097 /* Delete the file regardless since they hung up during recording */
1098 ast_filedelete(privintro
, NULL
);
1099 if( ast_fileexists(privintro
,NULL
,NULL
) > 0 )
1100 ast_log(LOG_NOTICE
,"privacy: ast_filedelete didn't do its job on %s\n", privintro
);
1101 else if (option_verbose
> 2)
1102 ast_verbose( VERBOSE_PREFIX_3
"Successfully deleted %s intro file\n", privintro
);
1105 if( !ast_streamfile(chan
, "vm-dialout", chan
->language
) )
1106 ast_waitstream(chan
, "");
1114 /* If a channel group has been specified, get it for use when we create peer channels */
1115 if ((outbound_group
= pbx_builtin_getvar_helper(chan
, "OUTBOUND_GROUP_ONCE"))) {
1116 outbound_group
= ast_strdupa(outbound_group
);
1117 pbx_builtin_setvar_helper(chan
, "OUTBOUND_GROUP_ONCE", NULL
);
1119 outbound_group
= pbx_builtin_getvar_helper(chan
, "OUTBOUND_GROUP");
1122 ast_copy_flags(peerflags
, &opts
, OPT_DTMF_EXIT
| OPT_GO_ON
| OPT_ORIGINAL_CLID
| OPT_CALLER_HANGUP
| OPT_IGNORE_FORWARDING
);
1124 /* Create datastore for channel dial features for caller */
1125 if (!(ds_caller_features
= ast_channel_datastore_alloc(&dial_features_info
, NULL
))) {
1126 ast_log(LOG_WARNING
, "Unable to create channel datastore for dial features. Aborting!\n");
1130 if (!(caller_features
= ast_calloc(1, sizeof(*caller_features
)))) {
1131 ast_log(LOG_WARNING
, "Unable to allocate memory for feature flags. Aborting!\n");
1135 ast_channel_lock(chan
);
1136 caller_features
->is_caller
= 1;
1137 set_dial_features(&opts
, caller_features
);
1138 ds_caller_features
->inheritance
= -1;
1139 ds_caller_features
->data
= caller_features
;
1140 ast_channel_datastore_add(chan
, ds_caller_features
);
1141 ast_channel_unlock(chan
);
1143 /* loop through the list of dial destinations */
1145 while ((cur
= strsep(&rest
, "&")) ) {
1146 struct dial_localuser
*tmp
;
1147 /* Get a technology/[device:]number pair */
1149 char *interface
= ast_strdupa(number
);
1150 char *tech
= strsep(&number
, "/");
1151 /* find if we already dialed this interface */
1152 struct ast_dialed_interface
*di
;
1153 struct ast_dial_features
*callee_features
;
1154 AST_LIST_HEAD(, ast_dialed_interface
) *dialed_interfaces
;
1157 ast_log(LOG_WARNING
, "Dial argument takes format (technology/[device:]number1)\n");
1160 if (!(tmp
= ast_calloc(1, sizeof(*tmp
))))
1163 ast_copy_flags(tmp
, &opts
,
1164 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
1165 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
1166 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
1167 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
1168 OPT_RINGBACK
| OPT_MUSICBACK
| OPT_FORCECLID
);
1169 ast_set2_flag(tmp
, args
.url
, DIAL_NOFORWARDHTML
);
1171 ast_copy_string(numsubst
, number
, sizeof(numsubst
));
1172 /* Request the peer */
1174 ast_channel_lock(chan
);
1175 datastore
= ast_channel_datastore_find(chan
, &dialed_interface_info
, NULL
);
1176 ast_channel_unlock(chan
);
1179 dialed_interfaces
= datastore
->data
;
1181 if (!(datastore
= ast_channel_datastore_alloc(&dialed_interface_info
, NULL
))) {
1182 ast_log(LOG_WARNING
, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1187 datastore
->inheritance
= DATASTORE_INHERIT_FOREVER
;
1189 if (!(dialed_interfaces
= ast_calloc(1, sizeof(*dialed_interfaces
)))) {
1194 datastore
->data
= dialed_interfaces
;
1195 AST_LIST_HEAD_INIT(dialed_interfaces
);
1197 ast_channel_lock(chan
);
1198 ast_channel_datastore_add(chan
, datastore
);
1199 ast_channel_unlock(chan
);
1202 AST_LIST_LOCK(dialed_interfaces
);
1203 AST_LIST_TRAVERSE(dialed_interfaces
, di
, list
) {
1204 if (!strcasecmp(di
->interface
, interface
)) {
1205 ast_log(LOG_WARNING
, "Skipping dialing interface '%s' again since it has already been dialed\n",
1210 AST_LIST_UNLOCK(dialed_interfaces
);
1218 /* It is always ok to dial a Local interface. We only keep track of
1219 * which "real" interfaces have been dialed. The Local channel will
1220 * inherit this list so that if it ends up dialing a real interface,
1221 * it won't call one that has already been called. */
1222 if (strcasecmp(tech
, "Local")) {
1223 if (!(di
= ast_calloc(1, sizeof(*di
) + strlen(interface
)))) {
1224 AST_LIST_UNLOCK(dialed_interfaces
);
1228 strcpy(di
->interface
, interface
);
1230 AST_LIST_LOCK(dialed_interfaces
);
1231 AST_LIST_INSERT_TAIL(dialed_interfaces
, di
, list
);
1232 AST_LIST_UNLOCK(dialed_interfaces
);
1235 tmp
->chan
= ast_request(tech
, chan
->nativeformats
, numsubst
, &cause
);
1237 /* If we can't, just go on to the next call */
1238 ast_log(LOG_WARNING
, "Unable to create channel of type '%s' (cause %d - %s)\n", tech
, cause
, ast_cause2str(cause
));
1239 HANDLE_CAUSE(cause
, chan
);
1240 if (!rest
) /* we are on the last destination */
1241 chan
->hangupcause
= cause
;
1246 pbx_builtin_setvar_helper(tmp
->chan
, "DIALEDPEERNUMBER", numsubst
);
1248 /* Setup outgoing SDP to match incoming one */
1249 ast_rtp_make_compatible(tmp
->chan
, chan
, !outgoing
&& !rest
);
1251 /* Inherit specially named variables from parent channel */
1252 ast_channel_inherit_variables(chan
, tmp
->chan
);
1254 tmp
->chan
->appl
= "AppDial";
1255 tmp
->chan
->data
= "(Outgoing Line)";
1256 tmp
->chan
->whentohangup
= 0;
1258 if (tmp
->chan
->cid
.cid_num
)
1259 free(tmp
->chan
->cid
.cid_num
);
1260 tmp
->chan
->cid
.cid_num
= ast_strdup(chan
->cid
.cid_num
);
1262 if (tmp
->chan
->cid
.cid_name
)
1263 free(tmp
->chan
->cid
.cid_name
);
1264 tmp
->chan
->cid
.cid_name
= ast_strdup(chan
->cid
.cid_name
);
1266 if (tmp
->chan
->cid
.cid_ani
)
1267 free(tmp
->chan
->cid
.cid_ani
);
1268 tmp
->chan
->cid
.cid_ani
= ast_strdup(chan
->cid
.cid_ani
);
1270 /* Copy language from incoming to outgoing */
1271 ast_string_field_set(tmp
->chan
, language
, chan
->language
);
1272 ast_string_field_set(tmp
->chan
, accountcode
, chan
->accountcode
);
1273 tmp
->chan
->cdrflags
= chan
->cdrflags
;
1274 if (ast_strlen_zero(tmp
->chan
->musicclass
))
1275 ast_string_field_set(tmp
->chan
, musicclass
, chan
->musicclass
);
1276 /* XXX don't we free previous values ? */
1277 tmp
->chan
->cid
.cid_rdnis
= ast_strdup(chan
->cid
.cid_rdnis
);
1278 /* Pass callingpres setting */
1279 tmp
->chan
->cid
.cid_pres
= chan
->cid
.cid_pres
;
1280 /* Pass type of number */
1281 tmp
->chan
->cid
.cid_ton
= chan
->cid
.cid_ton
;
1282 /* Pass type of tns */
1283 tmp
->chan
->cid
.cid_tns
= chan
->cid
.cid_tns
;
1284 /* Presense of ADSI CPE on outgoing channel follows ours */
1285 tmp
->chan
->adsicpe
= chan
->adsicpe
;
1286 /* Pass the transfer capability */
1287 tmp
->chan
->transfercapability
= chan
->transfercapability
;
1289 /* If we have an outbound group, set this peer channel to it */
1291 ast_app_group_set_channel(tmp
->chan
, outbound_group
);
1293 /* Inherit context and extension */
1294 if (!ast_strlen_zero(chan
->macrocontext
))
1295 ast_copy_string(tmp
->chan
->dialcontext
, chan
->macrocontext
, sizeof(tmp
->chan
->dialcontext
));
1297 ast_copy_string(tmp
->chan
->dialcontext
, chan
->context
, sizeof(tmp
->chan
->dialcontext
));
1298 if (!ast_strlen_zero(chan
->macroexten
))
1299 ast_copy_string(tmp
->chan
->exten
, chan
->macroexten
, sizeof(tmp
->chan
->exten
));
1301 ast_copy_string(tmp
->chan
->exten
, chan
->exten
, sizeof(tmp
->chan
->exten
));
1303 /* Save callee features */
1304 if (!(ds_callee_features
= ast_channel_datastore_alloc(&dial_features_info
, NULL
))) {
1305 ast_log(LOG_WARNING
, "Unable to create channel datastore for dial features. Aborting!\n");
1310 if (!(callee_features
= ast_calloc(1, sizeof(*callee_features
)))) {
1311 ast_log(LOG_WARNING
, "Unable to allocate memory for feature flags. Aborting!\n");
1316 ast_channel_lock(tmp
->chan
);
1317 callee_features
->is_caller
= 0;
1318 set_dial_features(&opts
, callee_features
);
1319 ds_callee_features
->inheritance
= -1;
1320 ds_callee_features
->data
= callee_features
;
1321 ast_channel_datastore_add(tmp
->chan
, ds_callee_features
);
1322 ast_channel_unlock(tmp
->chan
);
1324 /* Place the call, but don't wait on the answer */
1325 res
= ast_call(tmp
->chan
, numsubst
, 0);
1327 /* Save the info in cdr's that we called them */
1329 ast_cdr_setdestchan(chan
->cdr
, tmp
->chan
->name
);
1331 /* check the results of ast_call */
1333 /* Again, keep going even if there's an error */
1335 ast_log(LOG_DEBUG
, "ast call on peer returned %d\n", res
);
1336 if (option_verbose
> 2)
1337 ast_verbose(VERBOSE_PREFIX_3
"Couldn't call %s\n", numsubst
);
1338 ast_hangup(tmp
->chan
);
1343 senddialevent(chan
, tmp
->chan
);
1344 if (option_verbose
> 2)
1345 ast_verbose(VERBOSE_PREFIX_3
"Called %s\n", numsubst
);
1346 if (!ast_test_flag(peerflags
, OPT_ORIGINAL_CLID
))
1347 ast_set_callerid(tmp
->chan
, S_OR(chan
->macroexten
, chan
->exten
), get_cid_name(cidname
, sizeof(cidname
), chan
), NULL
);
1349 /* Put them in the list of outgoing thingies... We're ready now.
1350 XXX If we're forcibly removed, these outgoing calls won't get
1352 ast_set_flag(tmp
, DIAL_STILLGOING
);
1353 tmp
->next
= outgoing
;
1355 /* If this line is up, don't try anybody else */
1356 if (outgoing
->chan
->_state
== AST_STATE_UP
)
1360 if (ast_strlen_zero(args
.timeout
)) {
1363 to
= atoi(args
.timeout
);
1367 ast_log(LOG_WARNING
, "Invalid timeout specified: '%s'\n", args
.timeout
);
1371 strcpy(status
, "CHANUNAVAIL");
1372 if(fulldial
== num_dialed
) {
1377 /* Our status will at least be NOANSWER */
1378 strcpy(status
, "NOANSWER");
1379 if (ast_test_flag(outgoing
, OPT_MUSICBACK
)) {
1381 if (!ast_strlen_zero(opt_args
[OPT_ARG_MUSICBACK
])) {
1382 char *original_moh
= ast_strdupa(chan
->musicclass
);
1383 ast_string_field_set(chan
, musicclass
, opt_args
[OPT_ARG_MUSICBACK
]);
1384 ast_moh_start(chan
, opt_args
[OPT_ARG_MUSICBACK
], NULL
);
1385 ast_string_field_set(chan
, musicclass
, original_moh
);
1387 ast_moh_start(chan
, NULL
, NULL
);
1389 ast_indicate(chan
, AST_CONTROL_PROGRESS
);
1390 } else if (ast_test_flag(outgoing
, OPT_RINGBACK
)) {
1391 ast_indicate(chan
, AST_CONTROL_RINGING
);
1397 peer
= wait_for_answer(chan
, outgoing
, &to
, peerflags
, &sentringing
, status
, sizeof(status
), numbusy
, numnochan
, numcongestion
, ast_test_flag(&opts
, OPT_PRIORITY_JUMP
), &result
);
1399 /* The ast_channel_datastore_remove() function could fail here if the
1400 * datastore was moved to another channel during a masquerade. If this is
1401 * the case, don't free the datastore here because later, when the channel
1402 * to which the datastore was moved hangs up, it will attempt to free this
1403 * datastore again, causing a crash
1405 if (!ast_channel_datastore_remove(chan
, datastore
))
1406 ast_channel_datastore_free(datastore
);
1410 } else if (to
) { /* Musta gotten hung up */
1412 } else { /* Nobody answered, next please? */
1415 /* almost done, although the 'else' block is 400 lines */
1418 time_t end_time
, answer_time
= time(NULL
);
1420 strcpy(status
, "ANSWER");
1421 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1422 we will always return with -1 so that it is hung up properly after the
1424 hanguptree(outgoing
, peer
);
1426 /* If appropriate, log that we have a destination channel */
1428 ast_cdr_setdestchan(chan
->cdr
, peer
->name
);
1430 pbx_builtin_setvar_helper(chan
, "DIALEDPEERNAME", peer
->name
);
1432 number
= pbx_builtin_getvar_helper(peer
, "DIALEDPEERNUMBER");
1435 pbx_builtin_setvar_helper(chan
, "DIALEDPEERNUMBER", number
);
1436 if (!ast_strlen_zero(args
.url
) && ast_channel_supports_html(peer
) ) {
1438 ast_log(LOG_DEBUG
, "app_dial: sendurl=%s.\n", args
.url
);
1439 ast_channel_sendurl( peer
, args
.url
);
1441 if ( (ast_test_flag(&opts
, OPT_PRIVACY
) || ast_test_flag(&opts
, OPT_SCREENING
)) && privdb_val
== AST_PRIVACY_UNKNOWN
) {
1445 /* Get the user's intro, store it in priv-callerintros/$CID,
1446 unless it is already there-- this should be done before the
1447 call is actually dialed */
1449 /* all ring indications and moh for the caller has been halted as soon as the
1450 target extension was picked up. We are going to have to kill some
1451 time and make the caller believe the peer hasn't picked up yet */
1453 if (ast_test_flag(&opts
, OPT_MUSICBACK
) && !ast_strlen_zero(opt_args
[OPT_ARG_MUSICBACK
])) {
1454 char *original_moh
= ast_strdupa(chan
->musicclass
);
1455 ast_indicate(chan
, -1);
1456 ast_string_field_set(chan
, musicclass
, opt_args
[OPT_ARG_MUSICBACK
]);
1457 ast_moh_start(chan
, opt_args
[OPT_ARG_MUSICBACK
], NULL
);
1458 ast_string_field_set(chan
, musicclass
, original_moh
);
1459 } else if (ast_test_flag(&opts
, OPT_RINGBACK
)) {
1460 ast_indicate(chan
, AST_CONTROL_RINGING
);
1464 /* Start autoservice on the other chan ?? */
1465 res2
= ast_autoservice_start(chan
);
1466 /* Now Stream the File */
1467 for (loopcount
= 0; loopcount
< 3; loopcount
++) {
1468 if (res2
&& loopcount
== 0) /* error in ast_autoservice_start() */
1470 if (!res2
) /* on timeout, play the message again */
1471 res2
= ast_play_and_wait(peer
,"priv-callpending");
1472 if (!valid_priv_reply(&opts
, res2
))
1474 /* priv-callpending script:
1475 "I have a caller waiting, who introduces themselves as:"
1478 res2
= ast_play_and_wait(peer
,privintro
);
1479 if (!valid_priv_reply(&opts
, res2
))
1481 /* now get input from the called party, as to their choice */
1483 /* XXX can we have both, or they are mutually exclusive ? */
1484 if( ast_test_flag(&opts
, OPT_PRIVACY
) )
1485 res2
= ast_play_and_wait(peer
,"priv-callee-options");
1486 if( ast_test_flag(&opts
, OPT_SCREENING
) )
1487 res2
= ast_play_and_wait(peer
,"screen-callee-options");
1489 /*! \page DialPrivacy Dial Privacy scripts
1490 \par priv-callee-options script:
1491 "Dial 1 if you wish this caller to reach you directly in the future,
1492 and immediately connect to their incoming call
1493 Dial 2 if you wish to send this caller to voicemail now and
1495 Dial 3 to send this caller to the torture menus, now and forevermore.
1496 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1497 Dial 5 to allow this caller to come straight thru to you in the future,
1498 but right now, just this once, send them to voicemail."
1499 \par screen-callee-options script:
1500 "Dial 1 if you wish to immediately connect to the incoming call
1501 Dial 2 if you wish to send this caller to voicemail.
1502 Dial 3 to send this caller to the torture menus.
1503 Dial 4 to send this caller to a simple "go away" menu.
1505 if (valid_priv_reply(&opts
, res2
))
1507 /* invalid option */
1508 res2
= ast_play_and_wait(peer
, "vm-sorry");
1511 if (ast_test_flag(&opts
, OPT_MUSICBACK
)) {
1513 } else if (ast_test_flag(&opts
, OPT_RINGBACK
)) {
1514 ast_indicate(chan
, -1);
1517 ast_autoservice_stop(chan
);
1521 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1522 if (option_verbose
> 2)
1523 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to ALLOW\n",
1524 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1525 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_ALLOW
);
1529 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1530 if (option_verbose
> 2)
1531 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to DENY\n",
1532 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1533 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_DENY
);
1535 ast_copy_string(status
, "NOANSWER", sizeof(status
));
1536 ast_hangup(peer
); /* hang up on the callee -- he didn't want to talk anyway! */
1540 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1541 if (option_verbose
> 2)
1542 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to TORTURE\n",
1543 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1544 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_TORTURE
);
1546 ast_copy_string(status
, "TORTURE", sizeof(status
));
1549 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1550 goto out
; /* Is this right? */
1552 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1553 if (option_verbose
> 2)
1554 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to KILL\n",
1555 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1556 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_KILL
);
1559 ast_copy_string(status
, "DONTCALL", sizeof(status
));
1561 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1562 goto out
; /* Is this right? */
1564 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1565 if (option_verbose
> 2)
1566 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to ALLOW\n",
1567 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1568 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_ALLOW
);
1569 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1572 } /* if not privacy, then 5 is the same as "default" case */
1573 default: /* bad input or -1 if failure to start autoservice */
1574 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1575 /* well, there seems basically two choices. Just patch the caller thru immediately,
1576 or,... put 'em thru to voicemail. */
1577 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1578 ast_log(LOG_NOTICE
, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1579 ast_hangup(peer
); /* hang up on the callee -- he didn't want to talk anyway! */
1584 /* XXX once again, this path is only taken in the case '1', so it could be
1585 * moved there, although i am not really sure that this is correct - maybe
1586 * the check applies to other cases as well.
1588 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1589 just clog things up, and it's not useful information, not being tied to a CID */
1590 if( strncmp(privcid
,"NOCALLERID",10) == 0 || ast_test_flag(&opts
, OPT_SCREEN_NOINTRO
) ) {
1591 ast_filedelete(privintro
, NULL
);
1592 if( ast_fileexists(privintro
, NULL
, NULL
) > 0 )
1593 ast_log(LOG_NOTICE
, "privacy: ast_filedelete didn't do its job on %s\n", privintro
);
1594 else if (option_verbose
> 2)
1595 ast_verbose(VERBOSE_PREFIX_3
"Successfully deleted %s intro file\n", privintro
);
1598 if (!ast_test_flag(&opts
, OPT_ANNOUNCE
) || ast_strlen_zero(opt_args
[OPT_ARG_ANNOUNCE
])) {
1602 /* Start autoservice on the other chan */
1603 res
= ast_autoservice_start(chan
);
1604 /* Now Stream the File */
1606 res
= ast_streamfile(peer
, opt_args
[OPT_ARG_ANNOUNCE
], peer
->language
);
1608 digit
= ast_waitstream(peer
, AST_DIGIT_ANY
);
1610 /* Ok, done. stop autoservice */
1611 res
= ast_autoservice_stop(chan
);
1612 if (digit
> 0 && !res
)
1613 res
= ast_senddigit(chan
, digit
);
1619 if (chan
&& peer
&& ast_test_flag(&opts
, OPT_GOTO
) && !ast_strlen_zero(opt_args
[OPT_ARG_GOTO
])) {
1620 replace_macro_delimiter(opt_args
[OPT_ARG_GOTO
]);
1621 ast_parseable_goto(chan
, opt_args
[OPT_ARG_GOTO
]);
1622 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1623 ast_copy_string(peer
->context
, chan
->context
, sizeof(peer
->context
));
1624 ast_copy_string(peer
->exten
, chan
->exten
, sizeof(peer
->exten
));
1625 peer
->priority
= chan
->priority
+ 2;
1626 ast_pbx_start(peer
);
1627 hanguptree(outgoing
, NULL
);
1634 if (ast_test_flag(&opts
, OPT_CALLEE_MACRO
) && !ast_strlen_zero(opt_args
[OPT_ARG_CALLEE_MACRO
])) {
1635 struct ast_app
*theapp
;
1636 const char *macro_result
;
1638 res
= ast_autoservice_start(chan
);
1640 ast_log(LOG_ERROR
, "Unable to start autoservice on calling channel\n");
1644 theapp
= pbx_findapp("Macro");
1646 if (theapp
&& !res
) { /* XXX why check res here ? */
1647 replace_macro_delimiter(opt_args
[OPT_ARG_CALLEE_MACRO
]);
1648 res
= pbx_exec(peer
, theapp
, opt_args
[OPT_ARG_CALLEE_MACRO
]);
1649 ast_log(LOG_DEBUG
, "Macro exited with status %d\n", res
);
1652 ast_log(LOG_ERROR
, "Could not find application Macro\n");
1656 if (ast_autoservice_stop(chan
) < 0) {
1657 ast_log(LOG_ERROR
, "Could not stop autoservice on calling channel\n");
1661 if (!res
&& (macro_result
= pbx_builtin_getvar_helper(peer
, "MACRO_RESULT"))) {
1662 char *macro_transfer_dest
;
1664 if (!strcasecmp(macro_result
, "BUSY")) {
1665 ast_copy_string(status
, macro_result
, sizeof(status
));
1666 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1667 if (!ast_goto_if_exists(chan
, NULL
, NULL
, chan
->priority
+ 101)) {
1668 ast_set_flag(peerflags
, OPT_GO_ON
);
1671 ast_set_flag(peerflags
, OPT_GO_ON
);
1673 } else if (!strcasecmp(macro_result
, "CONGESTION") || !strcasecmp(macro_result
, "CHANUNAVAIL")) {
1674 ast_copy_string(status
, macro_result
, sizeof(status
));
1675 ast_set_flag(peerflags
, OPT_GO_ON
);
1677 } else if (!strcasecmp(macro_result
, "CONTINUE")) {
1678 /* hangup peer and keep chan alive assuming the macro has changed
1679 the context / exten / priority or perhaps
1680 the next priority in the current exten is desired.
1682 ast_set_flag(peerflags
, OPT_GO_ON
);
1684 } else if (!strcasecmp(macro_result
, "ABORT")) {
1685 /* Hangup both ends unless the caller has the g flag */
1687 } else if (!strncasecmp(macro_result
, "GOTO:", 5) && (macro_transfer_dest
= ast_strdupa(macro_result
+ 5))) {
1689 /* perform a transfer to a new extension */
1690 if (strchr(macro_transfer_dest
, '^')) { /* context^exten^priority*/
1691 replace_macro_delimiter(macro_transfer_dest
);
1692 if (!ast_parseable_goto(chan
, macro_transfer_dest
))
1693 ast_set_flag(peerflags
, OPT_GO_ON
);
1701 if (calldurationlimit
> 0) {
1702 peer
->whentohangup
= time(NULL
) + calldurationlimit
;
1704 if (!ast_strlen_zero(dtmfcalled
)) {
1705 if (option_verbose
> 2)
1706 ast_verbose(VERBOSE_PREFIX_3
"Sending DTMF '%s' to the called party.\n", dtmfcalled
);
1707 res
= ast_dtmf_stream(peer
,chan
,dtmfcalled
,250);
1709 if (!ast_strlen_zero(dtmfcalling
)) {
1710 if (option_verbose
> 2)
1711 ast_verbose(VERBOSE_PREFIX_3
"Sending DTMF '%s' to the calling party.\n", dtmfcalling
);
1712 res
= ast_dtmf_stream(chan
,peer
,dtmfcalling
,250);
1717 struct ast_bridge_config config
;
1719 memset(&config
,0,sizeof(struct ast_bridge_config
));
1721 ast_set_flag(&(config
.features_caller
), AST_FEATURE_PLAY_WARNING
);
1723 ast_set_flag(&(config
.features_callee
), AST_FEATURE_PLAY_WARNING
);
1724 if (ast_test_flag(peerflags
, OPT_CALLEE_TRANSFER
))
1725 ast_set_flag(&(config
.features_callee
), AST_FEATURE_REDIRECT
);
1726 if (ast_test_flag(peerflags
, OPT_CALLER_TRANSFER
))
1727 ast_set_flag(&(config
.features_caller
), AST_FEATURE_REDIRECT
);
1728 if (ast_test_flag(peerflags
, OPT_CALLEE_HANGUP
))
1729 ast_set_flag(&(config
.features_callee
), AST_FEATURE_DISCONNECT
);
1730 if (ast_test_flag(peerflags
, OPT_CALLER_HANGUP
))
1731 ast_set_flag(&(config
.features_caller
), AST_FEATURE_DISCONNECT
);
1732 if (ast_test_flag(peerflags
, OPT_CALLEE_MONITOR
))
1733 ast_set_flag(&(config
.features_callee
), AST_FEATURE_AUTOMON
);
1734 if (ast_test_flag(peerflags
, OPT_CALLER_MONITOR
))
1735 ast_set_flag(&(config
.features_caller
), AST_FEATURE_AUTOMON
);
1736 if (ast_test_flag(peerflags
, OPT_CALLEE_PARK
))
1737 ast_set_flag(&(config
.features_callee
), AST_FEATURE_PARKCALL
);
1738 if (ast_test_flag(peerflags
, OPT_CALLER_PARK
))
1739 ast_set_flag(&(config
.features_caller
), AST_FEATURE_PARKCALL
);
1741 config
.timelimit
= timelimit
;
1742 config
.play_warning
= play_warning
;
1743 config
.warning_freq
= warning_freq
;
1744 config
.warning_sound
= warning_sound
;
1745 config
.end_sound
= end_sound
;
1746 config
.start_sound
= start_sound
;
1750 } else if (sentringing
) {
1752 ast_indicate(chan
, -1);
1754 /* Be sure no generators are left on it */
1755 ast_deactivate_generator(chan
);
1756 /* Make sure channels are compatible */
1757 res
= ast_channel_make_compatible(chan
, peer
);
1759 ast_log(LOG_WARNING
, "Had to drop call because I couldn't make %s compatible with %s\n", chan
->name
, peer
->name
);
1764 if (opermode
&& (!strncmp(chan
->name
,"Zap",3)) &&
1765 (!strncmp(peer
->name
,"Zap",3)))
1767 struct oprmode oprmode
;
1769 oprmode
.peer
= peer
;
1770 oprmode
.mode
= opermode
;
1772 ast_channel_setoption(chan
,
1773 AST_OPTION_OPRMODE
,&oprmode
,sizeof(struct oprmode
),0);
1775 res
= ast_bridge_call(chan
,peer
,&config
);
1779 snprintf(toast
, sizeof(toast
), "%ld", (long)(end_time
- answer_time
));
1780 pbx_builtin_setvar_helper(chan
, "ANSWEREDTIME", toast
);
1788 snprintf(toast
, sizeof(toast
), "%ld", (long)(end_time
- start_time
));
1789 pbx_builtin_setvar_helper(chan
, "DIALEDTIME", toast
);
1792 if (res
!= AST_PBX_NO_HANGUP_PEER
) {
1793 if (!chan
->_softhangup
)
1794 chan
->hangupcause
= peer
->hangupcause
;
1802 } else if (sentringing
) {
1804 ast_indicate(chan
, -1);
1806 ast_rtp_early_bridge(chan
, NULL
);
1807 hanguptree(outgoing
, NULL
);
1808 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
1810 ast_log(LOG_DEBUG
, "Exiting with DIALSTATUS=%s.\n", status
);
1812 if ((ast_test_flag(peerflags
, OPT_GO_ON
)) && (!chan
->_softhangup
) && (res
!= AST_PBX_KEEPALIVE
)) {
1813 if (calldurationlimit
)
1814 chan
->whentohangup
= 0;
1819 ast_module_user_remove(u
);
1823 static int dial_exec(struct ast_channel
*chan
, void *data
)
1825 struct ast_flags peerflags
;
1827 memset(&peerflags
, 0, sizeof(peerflags
));
1829 return dial_exec_full(chan
, data
, &peerflags
, NULL
);
1832 static int retrydial_exec(struct ast_channel
*chan
, void *data
)
1834 char *announce
= NULL
, *dialdata
= NULL
;
1835 const char *context
= NULL
;
1836 int sleep
= 0, loops
= 0, res
= -1;
1837 struct ast_module_user
*u
;
1838 struct ast_flags peerflags
;
1840 if (ast_strlen_zero(data
)) {
1841 ast_log(LOG_WARNING
, "RetryDial requires an argument!\n");
1845 u
= ast_module_user_add(chan
);
1847 announce
= ast_strdupa(data
);
1849 memset(&peerflags
, 0, sizeof(peerflags
));
1851 if ((dialdata
= strchr(announce
, '|'))) {
1853 if (sscanf(dialdata
, "%d", &sleep
) == 1) {
1856 ast_log(LOG_ERROR
, "%s requires the numerical argument <sleep>\n",rapp
);
1859 if ((dialdata
= strchr(dialdata
, '|'))) {
1861 if (sscanf(dialdata
, "%d", &loops
) != 1) {
1862 ast_log(LOG_ERROR
, "%s requires the numerical argument <loops>\n",rapp
);
1868 if ((dialdata
= strchr(dialdata
, '|'))) {
1871 ast_log(LOG_ERROR
, "%s requires more arguments\n",rapp
);
1879 loops
= -1; /* run forever */
1881 context
= pbx_builtin_getvar_helper(chan
, "EXITCONTEXT");
1887 chan
->data
= "Retrying";
1888 if (ast_test_flag(chan
, AST_FLAG_MOH
))
1891 res
= dial_exec_full(chan
, dialdata
, &peerflags
, &continue_exec
);
1896 if (ast_test_flag(&peerflags
, OPT_DTMF_EXIT
)) {
1897 if (!ast_strlen_zero(announce
)) {
1898 if (ast_fileexists(announce
, NULL
, chan
->language
) > 0) {
1899 if(!(res
= ast_streamfile(chan
, announce
, chan
->language
)))
1900 ast_waitstream(chan
, AST_DIGIT_ANY
);
1902 ast_log(LOG_WARNING
, "Announce file \"%s\" specified in Retrydial does not exist\n", announce
);
1904 if (!res
&& sleep
) {
1905 if (!ast_test_flag(chan
, AST_FLAG_MOH
))
1906 ast_moh_start(chan
, NULL
, NULL
);
1907 res
= ast_waitfordigit(chan
, sleep
);
1910 if (!ast_strlen_zero(announce
)) {
1911 if (ast_fileexists(announce
, NULL
, chan
->language
) > 0) {
1912 if (!(res
= ast_streamfile(chan
, announce
, chan
->language
)))
1913 res
= ast_waitstream(chan
, "");
1915 ast_log(LOG_WARNING
, "Announce file \"%s\" specified in Retrydial does not exist\n", announce
);
1918 if (!ast_test_flag(chan
, AST_FLAG_MOH
))
1919 ast_moh_start(chan
, NULL
, NULL
);
1921 res
= ast_waitfordigit(chan
, sleep
);
1928 else if (res
> 0) { /* Trying to send the call elsewhere (1 digit ext) */
1929 if (onedigit_goto(chan
, context
, (char) res
, 1)) {
1941 if (ast_test_flag(chan
, AST_FLAG_MOH
))
1944 ast_module_user_remove(u
);
1948 static int unload_module(void)
1952 res
= ast_unregister_application(app
);
1953 res
|= ast_unregister_application(rapp
);
1955 ast_module_user_hangup_all();
1960 static int load_module(void)
1964 res
= ast_register_application(app
, dial_exec
, synopsis
, descrip
);
1965 res
|= ast_register_application(rapp
, retrydial_exec
, rsynopsis
, rdescrip
);
1970 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Dialing Application");