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
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
39 #include <sys/signal.h>
41 #include <netinet/in.h>
43 #include "asterisk/lock.h"
44 #include "asterisk/file.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/pbx.h"
48 #include "asterisk/options.h"
49 #include "asterisk/module.h"
50 #include "asterisk/translate.h"
51 #include "asterisk/say.h"
52 #include "asterisk/config.h"
53 #include "asterisk/features.h"
54 #include "asterisk/musiconhold.h"
55 #include "asterisk/callerid.h"
56 #include "asterisk/utils.h"
57 #include "asterisk/app.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/rtp.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/privacy.h"
62 #include "asterisk/stringfields.h"
64 static char *app = "Dial";
66 static char *synopsis = "Place a call and connect to the current channel";
68 static char *descrip =
69 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
70 "This application will place calls to one or more specified channels. As soon\n"
71 "as one of the requested channels answers, the originating channel will be\n"
72 "answered, if it has not already been answered. These two channels will then\n"
73 "be active in a bridged call. All other channels that were requested will then\n"
75 " Unless there is a timeout specified, the Dial application will wait\n"
76 "indefinitely until one of the called channels answers, the user hangs up, or\n"
77 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
78 "continue if no requested channels can be called, or if the timeout expires.\n\n"
79 " This application sets the following channel variables upon completion:\n"
80 " DIALEDTIME - This is the time from dialing a channel until when it\n"
82 " ANSWEREDTIME - This is the amount of time for actual call.\n"
83 " DIALSTATUS - This is the status of the call:\n"
84 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
85 " DONTCALL | TORTURE | INVALIDARGS\n"
86 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
87 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
88 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
89 "wants to send the caller to the 'torture' script.\n"
90 " This application will report normal termination if the originating channel\n"
91 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
93 " The optional URL will be sent to the called party if the channel supports it.\n"
94 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
95 "application will be put into that group (as in Set(GROUP()=...).\n"
96 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
97 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
98 "however, the variable will be unset after use.\n\n"
100 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
101 " C - Reset the CDR for this call.\n"
102 " c - If DIAL cancels this call, always set the flag to tell the channel\n"
103 " driver that the call is answered elsewhere.\n"
104 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
105 " a call to be answered. Exit to that extension if it exists in the\n"
106 " current context, or the context defined in the EXITCONTEXT variable,\n"
108 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
109 " party has answered, but before the call gets bridged. The 'called'\n"
110 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
111 " string is sent to the calling party. Both parameters can be used\n"
113 " f - Force the callerid of the *calling* channel to be set as the\n"
114 " extension associated with the channel using a dialplan 'hint'.\n"
115 " For example, some PSTNs do not allow CallerID to be set to anything\n"
116 " other than the number assigned to the caller.\n"
117 " g - Proceed with dialplan execution at the current extension if the\n"
118 " destination channel hangs up.\n"
119 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
120 " the specified priority and the called party to the specified priority+1.\n"
121 " Optionally, an extension, or extension and context may be specified. \n"
122 " Otherwise, the current extension is used. You cannot use any additional\n"
123 " action post answer options in conjunction with this option.\n"
124 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
125 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
126 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
128 " k - Allow the called party to enable parking of the call by sending\n"
129 " the DTMF sequence defined for call parking in features.conf.\n"
130 " K - Allow the calling party to enable parking of the call by sending\n"
131 " the DTMF sequence defined for call parking in features.conf.\n"
132 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
133 " left. Repeat the warning every 'z' ms. The following special\n"
134 " variables can be used with this option:\n"
135 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
136 " Play sounds to the caller.\n"
137 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
138 " Play sounds to the callee.\n"
139 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
140 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
141 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
142 " The default is to say the time remaining.\n"
143 " m([class]) - Provide hold music to the calling party until a requested\n"
144 " channel answers. A specific MusicOnHold class can be\n"
146 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
147 " to the calling channel. Arguments can be specified to the Macro\n"
148 " using '^' as a delimeter. The Macro can set the variable\n"
149 " MACRO_RESULT to specify the following actions after the Macro is\n"
150 " finished executing.\n"
151 " * ABORT Hangup both legs of the call.\n"
152 " * CONGESTION Behave as if line congestion was encountered.\n"
153 " * BUSY Behave as if a busy signal was encountered.\n"
154 " * CONTINUE Hangup the called party and allow the calling party\n"
155 " to continue dialplan execution at the next priority.\n"
156 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
157 " specified priority. Optionally, an extension, or\n"
158 " extension and priority can be specified.\n"
159 " You cannot use any additional action post answer options in conjunction\n"
160 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
161 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
162 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
163 " that no introductions are to be saved in the priv-callerintros\n"
165 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
166 " that if callerID is present, do not screen the call.\n"
167 " o - Specify that the CallerID that was present on the *calling* channel\n"
168 " be set as the CallerID on the *called* channel. This was the\n"
169 " behavior of Asterisk 1.0 and earlier.\n"
170 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
171 " only, if specified on non-Zaptel interface, it will be ignored).\n"
172 " When the destination answers (presumably an operator services\n"
173 " station), the originator no longer has control of their line.\n"
174 " They may hang up, but the switch will not release their line\n"
175 " until the destination party hangs up (the operator). Specified\n"
176 " without an arg, or with 1 as an arg, the originator hanging up\n"
177 " will cause the phone to ring back immediately. With a 2 specified,\n"
178 " when the \"operator\" flashes the trunk, it will ring their phone\n"
180 " p - This option enables screening mode. This is basically Privacy mode\n"
182 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
183 " it is provided. The current extension is used if a database\n"
184 " family/key is not specified.\n"
185 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
186 " party until the called channel has answered.\n"
187 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
188 " answered the call.\n"
189 " t - Allow the called party to transfer the calling party by sending the\n"
190 " DTMF sequence defined in features.conf.\n"
191 " T - Allow the calling party to transfer the called party by sending the\n"
192 " DTMF sequence defined in features.conf.\n"
193 " U(x[^arg]) - Execute via Gosub the routine 'x' for the *called* channel before connecting\n"
194 " to the calling channel. Arguments can be specified to the Gosub\n"
195 " using '^' as a delimeter. The Gosub routine can set the variable\n"
196 " GOSUB_RESULT to specify the following actions after the Gosub returns.\n"
197 " * ABORT Hangup both legs of the call.\n"
198 " * CONGESTION Behave as if line congestion was encountered.\n"
199 " * BUSY Behave as if a busy signal was encountered.\n"
200 " * CONTINUE Hangup the called party and allow the calling party\n"
201 " to continue dialplan execution at the next priority.\n"
202 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
203 " specified priority. Optionally, an extension, or\n"
204 " extension and priority can be specified.\n"
205 " You cannot use any additional action post answer options in conjunction\n"
206 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
207 " so you will not be able to set timeouts via the TIMEOUT() function in this routine.\n"
208 " w - Allow the called party to enable recording of the call by sending\n"
209 " the DTMF sequence defined for one-touch recording in features.conf.\n"
210 " W - Allow the calling party to enable recording of the call by sending\n"
211 " the DTMF sequence defined for one-touch recording in features.conf.\n";
213 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
214 static char *rapp = "RetryDial";
215 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
216 static char *rdescrip =
217 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
218 "place a call using the normal Dial application. If no channel can be reached,\n"
219 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
220 "seconds before retying the call. After 'retires' number of attempts, the\n"
221 "calling channel will continue at the next priority in the dialplan. If the\n"
222 "'retries' setting is set to 0, this application will retry endlessly.\n"
223 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
224 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
225 "one, The call will jump to that extension immediately.\n"
226 " The 'dialargs' are specified in the same format that arguments are provided\n"
227 "to the Dial application.\n";
230 OPT_ANNOUNCE = (1 << 0),
231 OPT_RESETCDR = (1 << 1),
232 OPT_DTMF_EXIT = (1 << 2),
233 OPT_SENDDTMF = (1 << 3),
234 OPT_FORCECLID = (1 << 4),
235 OPT_GO_ON = (1 << 5),
236 OPT_CALLEE_HANGUP = (1 << 6),
237 OPT_CALLER_HANGUP = (1 << 7),
238 OPT_DURATION_LIMIT = (1 << 9),
239 OPT_MUSICBACK = (1 << 10),
240 OPT_CALLEE_MACRO = (1 << 11),
241 OPT_SCREEN_NOINTRO = (1 << 12),
242 OPT_SCREEN_NOCLID = (1 << 13),
243 OPT_ORIGINAL_CLID = (1 << 14),
244 OPT_SCREENING = (1 << 15),
245 OPT_PRIVACY = (1 << 16),
246 OPT_RINGBACK = (1 << 17),
247 OPT_DURATION_STOP = (1 << 18),
248 OPT_CALLEE_TRANSFER = (1 << 19),
249 OPT_CALLER_TRANSFER = (1 << 20),
250 OPT_CALLEE_MONITOR = (1 << 21),
251 OPT_CALLER_MONITOR = (1 << 22),
252 OPT_GOTO = (1 << 23),
253 OPT_OPERMODE = (1 << 24),
254 OPT_CALLEE_PARK = (1 << 25),
255 OPT_CALLER_PARK = (1 << 26),
256 OPT_IGNORE_FORWARDING = (1 << 27),
257 OPT_CALLEE_GOSUB = (1 << 28),
258 OPT_CANCEL_ELSEWHERE = (1 << 29),
261 #define DIAL_STILLGOING (1 << 30)
262 #define DIAL_NOFORWARDHTML (1 << 31)
265 OPT_ARG_ANNOUNCE = 0,
268 OPT_ARG_DURATION_LIMIT,
270 OPT_ARG_CALLEE_MACRO,
271 OPT_ARG_CALLEE_GOSUB,
273 OPT_ARG_DURATION_STOP,
275 /* note: this entry _MUST_ be the last one in the enum */
279 AST_APP_OPTIONS(dial_exec_options, {
280 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
281 AST_APP_OPTION('C', OPT_RESETCDR),
282 AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
283 AST_APP_OPTION('d', OPT_DTMF_EXIT),
284 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
285 AST_APP_OPTION('f', OPT_FORCECLID),
286 AST_APP_OPTION('g', OPT_GO_ON),
287 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
288 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
289 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
290 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
291 AST_APP_OPTION('k', OPT_CALLEE_PARK),
292 AST_APP_OPTION('K', OPT_CALLER_PARK),
293 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
294 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
295 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
296 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
297 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
298 AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
299 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
300 AST_APP_OPTION('p', OPT_SCREENING),
301 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
302 AST_APP_OPTION('r', OPT_RINGBACK),
303 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
304 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
305 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
306 AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
307 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
308 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
312 * The list of active channels
315 struct chanlist *next;
316 struct ast_channel *chan;
322 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
324 /* Hang up a tree of stuff */
327 /* Hangup any existing lines we have open */
328 if (outgoing->chan && (outgoing->chan != exception)) {
329 if (answered_elsewhere)
330 ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
331 ast_hangup(outgoing->chan);
334 outgoing=outgoing->next;
339 #define AST_MAX_FORWARDS 8
341 #define AST_MAX_WATCHERS 256
344 * argument to handle_cause() and other functions.
347 struct ast_channel *chan;
353 static void handle_cause(int cause, struct cause_args *num)
355 struct ast_cdr *cdr = num->chan->cdr;
364 case AST_CAUSE_CONGESTION:
370 case AST_CAUSE_UNREGISTERED:
376 case AST_CAUSE_NORMAL_CLEARING:
385 /* free the buffer if allocated, and set the pointer to the second arg */
386 #define S_REPLACE(s, new_val) \
393 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
395 char rexten[2] = { exten, '\0' };
398 if (!ast_goto_if_exists(chan, context, rexten, pri))
401 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
403 else if (!ast_strlen_zero(chan->macrocontext)) {
404 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
412 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
414 const char *context = S_OR(chan->macrocontext, chan->context);
415 const char *exten = S_OR(chan->macroexten, chan->exten);
417 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
420 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
422 manager_event(EVENT_FLAG_CALL, "Dial",
423 "SubEvent: Begin\r\n"
425 "Destination: %s\r\n"
426 "CallerIDNum: %s\r\n"
427 "CallerIDName: %s\r\n"
428 "SrcUniqueID: %s\r\n"
429 "DestUniqueID: %s\r\n",
430 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
431 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
435 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
437 manager_event(EVENT_FLAG_CALL, "Dial",
440 "DialStatus: %s\r\n",
441 src->name, dialstatus);
445 * helper function for wait_for_answer()
447 * XXX this code is highly suspicious, as it essentially overwrites
448 * the outgoing channel without properly deleting it.
450 static void do_forward(struct chanlist *o,
451 struct cause_args *num, struct ast_flags *peerflags, int single)
454 struct ast_channel *original = o->chan;
455 struct ast_channel *c = o->chan; /* the winner */
456 struct ast_channel *in = num->chan; /* the input channel */
461 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
462 if ((stuff = strchr(tmpchan, '/'))) {
466 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
467 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
471 /* Before processing channel, go ahead and check for forwarding */
473 if (o->forwards < AST_MAX_FORWARDS) {
474 if (option_verbose > 2)
475 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
476 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
477 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
478 if (option_verbose > 2)
479 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
481 cause = AST_CAUSE_BUSY;
483 /* Setup parameters */
484 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
487 ast_channel_make_compatible(o->chan, in);
488 ast_channel_inherit_variables(in, o->chan);
490 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
493 if (option_verbose > 2)
494 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
495 cause = AST_CAUSE_CONGESTION;
499 ast_clear_flag(o, DIAL_STILLGOING);
500 handle_cause(cause, num);
502 char *new_cid_num, *new_cid_name;
503 struct ast_channel *src;
505 ast_rtp_make_compatible(c, in, single);
506 if (ast_test_flag(o, OPT_FORCECLID)) {
507 new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
508 new_cid_name = NULL; /* XXX no name ? */
509 src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
511 new_cid_num = ast_strdup(in->cid.cid_num);
512 new_cid_name = ast_strdup(in->cid.cid_name);
515 ast_string_field_set(c, accountcode, src->accountcode);
516 c->cdrflags = src->cdrflags;
517 S_REPLACE(c->cid.cid_num, new_cid_num);
518 S_REPLACE(c->cid.cid_name, new_cid_name);
520 if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
521 S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
523 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
524 if (ast_call(c, tmpchan, 0)) {
525 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
526 ast_clear_flag(o, DIAL_STILLGOING);
527 ast_hangup(original);
531 senddialevent(in, c);
532 /* After calling, set callerid to extension */
533 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
534 char cidname[AST_MAX_EXTENSION] = "";
535 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
537 /* Hangup the original channel now, in case we needed it */
538 ast_hangup(original);
543 /* argument used for some functions. */
544 struct privacy_args {
548 char privintro[1024];
552 static struct ast_channel *wait_for_answer(struct ast_channel *in,
553 struct chanlist *outgoing, int *to, struct ast_flags *peerflags,
554 struct privacy_args *pa,
555 const struct cause_args *num_in, int *result)
557 struct cause_args num = *num_in;
558 int prestart = num.busy + num.congestion + num.nochan;
560 struct ast_channel *peer = NULL;
561 /* single is set if only one destination is enabled */
562 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
565 /* Turn off hold music, etc */
566 ast_deactivate_generator(in);
567 /* If we are calling a single channel, make them compatible for in-band tone purpose */
568 ast_channel_make_compatible(outgoing->chan, in);
572 while (*to && !peer) {
574 int pos = 0; /* how many channels do we handle */
575 int numlines = prestart;
576 struct ast_channel *winner;
577 struct ast_channel *watchers[AST_MAX_WATCHERS];
579 watchers[pos++] = in;
580 for (o = outgoing; o; o = o->next) {
581 /* Keep track of important channels */
582 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
583 watchers[pos++] = o->chan;
586 if (pos == 1) { /* only the input channel is available */
587 if (numlines == (num.busy + num.congestion + num.nochan)) {
588 if (option_verbose > 2)
589 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
591 strcpy(pa->status, "BUSY");
592 else if (num.congestion)
593 strcpy(pa->status, "CONGESTION");
595 strcpy(pa->status, "CHANUNAVAIL");
597 if (option_verbose > 2)
598 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
603 winner = ast_waitfor_n(watchers, pos, to);
604 for (o = outgoing; o; o = o->next) {
606 struct ast_channel *c = o->chan;
610 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
612 if (option_verbose > 2)
613 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
615 ast_copy_flags(peerflags, o,
616 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
617 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
618 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
619 OPT_CALLEE_PARK | OPT_CALLER_PARK |
621 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
622 ast_copy_string(c->exten, "", sizeof(c->exten));
628 /* here, o->chan == c == winner */
629 if (!ast_strlen_zero(c->call_forward)) {
630 do_forward(o, &num, peerflags, single);
633 f = ast_read(winner);
635 in->hangupcause = c->hangupcause;
638 ast_clear_flag(o, DIAL_STILLGOING);
639 handle_cause(in->hangupcause, &num);
642 if (f->frametype == AST_FRAME_CONTROL) {
643 switch(f->subclass) {
644 case AST_CONTROL_ANSWER:
645 /* This is our guy if someone answered. */
647 if (option_verbose > 2)
648 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
650 ast_copy_flags(peerflags, o,
651 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
652 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
653 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
654 OPT_CALLEE_PARK | OPT_CALLER_PARK |
656 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
657 ast_copy_string(c->exten, "", sizeof(c->exten));
658 /* Setup early bridge if appropriate */
659 ast_channel_early_bridge(in, peer);
661 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
662 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
663 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
665 case AST_CONTROL_BUSY:
666 if (option_verbose > 2)
667 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
668 in->hangupcause = c->hangupcause;
671 ast_clear_flag(o, DIAL_STILLGOING);
672 handle_cause(AST_CAUSE_BUSY, &num);
674 case AST_CONTROL_CONGESTION:
675 if (option_verbose > 2)
676 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
677 in->hangupcause = c->hangupcause;
680 ast_clear_flag(o, DIAL_STILLGOING);
681 handle_cause(AST_CAUSE_CONGESTION, &num);
683 case AST_CONTROL_RINGING:
684 if (option_verbose > 2)
685 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
686 /* Setup early media if appropriate */
688 ast_channel_early_bridge(in, c);
689 if (!(pa->sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
690 ast_indicate(in, AST_CONTROL_RINGING);
694 case AST_CONTROL_PROGRESS:
695 if (option_verbose > 2)
696 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
697 /* Setup early media if appropriate */
699 ast_channel_early_bridge(in, c);
700 if (!ast_test_flag(outgoing, OPT_RINGBACK))
701 ast_indicate(in, AST_CONTROL_PROGRESS);
703 case AST_CONTROL_VIDUPDATE:
704 if (option_verbose > 2)
705 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
706 ast_indicate(in, AST_CONTROL_VIDUPDATE);
708 case AST_CONTROL_PROCEEDING:
709 if (option_verbose > 2)
710 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
712 ast_channel_early_bridge(in, c);
713 if (!ast_test_flag(outgoing, OPT_RINGBACK))
714 ast_indicate(in, AST_CONTROL_PROCEEDING);
716 case AST_CONTROL_HOLD:
717 if (option_verbose > 2)
718 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
719 ast_indicate(in, AST_CONTROL_HOLD);
721 case AST_CONTROL_UNHOLD:
722 if (option_verbose > 2)
723 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
724 ast_indicate(in, AST_CONTROL_UNHOLD);
726 case AST_CONTROL_OFFHOOK:
727 case AST_CONTROL_FLASH:
728 /* Ignore going off hook and flash */
731 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
732 if (option_verbose > 2)
733 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
734 ast_indicate(in, -1);
739 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
742 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
743 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
744 if (ast_write(in, f))
745 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
746 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
747 if (ast_write(in, f))
748 ast_log(LOG_WARNING, "Unable to forward image\n");
749 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
750 if (ast_write(in, f))
751 ast_log(LOG_WARNING, "Unable to send text\n");
752 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
753 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
754 ast_log(LOG_WARNING, "Unable to send URL\n");
760 struct ast_frame *f = ast_read(in);
762 if (f && (f->frametype != AST_FRAME_VOICE))
763 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
764 else if (!f || (f->frametype != AST_FRAME_VOICE))
765 printf("Hangup received on %s\n", in->name);
767 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
770 strcpy(pa->status, "CANCEL");
771 ast_cdr_noanswer(in->cdr);
777 /* now f is guaranteed non-NULL */
778 if (f->frametype == AST_FRAME_DTMF) {
779 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
780 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
781 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
782 if (option_verbose > 2)
783 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
785 ast_cdr_noanswer(in->cdr);
786 *result = f->subclass;
787 strcpy(pa->status, "CANCEL");
793 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
794 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
795 if (option_verbose > 2)
796 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
798 strcpy(pa->status, "CANCEL");
799 ast_cdr_noanswer(in->cdr);
805 /* Forward HTML stuff */
806 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
807 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
808 ast_log(LOG_WARNING, "Unable to send URL\n");
811 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
812 if (ast_write(outgoing->chan, f))
813 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
815 if (single && (f->frametype == AST_FRAME_CONTROL) &&
816 ((f->subclass == AST_CONTROL_HOLD) ||
817 (f->subclass == AST_CONTROL_UNHOLD) ||
818 (f->subclass == AST_CONTROL_VIDUPDATE))) {
819 if (option_verbose > 2)
820 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
821 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
825 if (!*to && (option_verbose > 2))
826 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
827 if (!*to || ast_check_hangup(in)) {
828 ast_cdr_noanswer(in->cdr);
836 static void replace_macro_delimiter(char *s)
844 /* returns true if there is a valid privacy reply */
845 static int valid_priv_reply(struct ast_flags *opts, int res)
849 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
851 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
856 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
857 char *parse, unsigned int *calldurationlimit)
859 char *stringp = ast_strdupa(parse);
860 char *limit_str, *warning_str, *warnfreq_str;
862 int play_to_caller=0,play_to_callee=0;
865 limit_str = strsep(&stringp, ":");
866 warning_str = strsep(&stringp, ":");
867 warnfreq_str = strsep(&stringp, ":");
869 config->timelimit = atol(limit_str);
871 config->play_warning = atol(warning_str);
873 config->warning_freq = atol(warnfreq_str);
875 if (!config->timelimit) {
876 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
877 config->timelimit = config->play_warning = config->warning_freq = 0;
878 config->warning_sound = NULL;
879 return -1; /* error */
880 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
881 int w = config->warning_freq;
883 /* If the first warning is requested _after_ the entire call would end,
884 and no warning frequency is requested, then turn off the warning. If
885 a warning frequency is requested, reduce the 'first warning' time by
886 that frequency until it falls within the call's total time limit.
888 timelim->| delta |<-playwarning
889 0__________________|_________________|
892 so the number of intervals to cut is 1+(delta-1)/w
896 config->play_warning = 0;
898 config->play_warning -= w * ( 1 + (delta-1)/w );
899 if (config->play_warning < 1)
900 config->play_warning = config->warning_freq = 0;
904 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
905 play_to_caller = var ? ast_true(var) : 1;
907 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
908 play_to_callee = var ? ast_true(var) : 0;
910 if (!play_to_caller && !play_to_callee)
913 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
914 config->warning_sound = S_OR(var, "timeleft");
916 /* The code looking at config wants a NULL, not just "", to decide
917 * that the message should not be played, so we replace "" with NULL.
918 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
921 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
922 config->end_sound = S_OR(var, NULL);
923 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
924 config->start_sound = S_OR(var, NULL);
926 /* undo effect of S(x) in case they are both used */
927 *calldurationlimit = 0;
928 /* more efficient to do it like S(x) does since no advanced opts */
929 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
930 *calldurationlimit = config->timelimit / 1000;
931 if (option_verbose > 2)
932 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",
934 config->timelimit = play_to_caller = play_to_callee =
935 config->play_warning = config->warning_freq = 0;
936 } else if (option_verbose > 2) {
937 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
938 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", config->timelimit);
939 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", config->play_warning);
940 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
941 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
942 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", config->warning_freq);
943 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", S_OR(config->start_sound, ""));
944 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", config->warning_sound);
945 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", S_OR(config->end_sound, ""));
948 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
950 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
954 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
955 struct ast_flags *opts, char **opt_args, struct privacy_args *pa)
961 /* Get the user's intro, store it in priv-callerintros/$CID,
962 unless it is already there-- this should be done before the
963 call is actually dialed */
965 /* all ring indications and moh for the caller has been halted as soon as the
966 target extension was picked up. We are going to have to kill some
967 time and make the caller believe the peer hasn't picked up yet */
969 if (ast_test_flag(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
970 char *original_moh = ast_strdupa(chan->musicclass);
971 ast_indicate(chan, -1);
972 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
973 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
974 ast_string_field_set(chan, musicclass, original_moh);
975 } else if (ast_test_flag(opts, OPT_RINGBACK)) {
976 ast_indicate(chan, AST_CONTROL_RINGING);
980 /* Start autoservice on the other chan ?? */
981 res2 = ast_autoservice_start(chan);
982 /* Now Stream the File */
983 for (loopcount = 0; loopcount < 3; loopcount++) {
984 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
986 if (!res2) /* on timeout, play the message again */
987 res2 = ast_play_and_wait(peer,"priv-callpending");
988 if (!valid_priv_reply(opts, res2))
990 /* priv-callpending script:
991 "I have a caller waiting, who introduces themselves as:"
994 res2 = ast_play_and_wait(peer, pa->privintro);
995 if (!valid_priv_reply(opts, res2))
997 /* now get input from the called party, as to their choice */
999 /* XXX can we have both, or they are mutually exclusive ? */
1000 if( ast_test_flag(opts, OPT_PRIVACY) )
1001 res2 = ast_play_and_wait(peer,"priv-callee-options");
1002 if( ast_test_flag(opts, OPT_SCREENING) )
1003 res2 = ast_play_and_wait(peer,"screen-callee-options");
1005 /*! \page DialPrivacy Dial Privacy scripts
1006 \par priv-callee-options script:
1007 "Dial 1 if you wish this caller to reach you directly in the future,
1008 and immediately connect to their incoming call
1009 Dial 2 if you wish to send this caller to voicemail now and
1011 Dial 3 to send this caller to the torture menus, now and forevermore.
1012 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1013 Dial 5 to allow this caller to come straight thru to you in the future,
1014 but right now, just this once, send them to voicemail."
1015 \par screen-callee-options script:
1016 "Dial 1 if you wish to immediately connect to the incoming call
1017 Dial 2 if you wish to send this caller to voicemail.
1018 Dial 3 to send this caller to the torture menus.
1019 Dial 4 to send this caller to a simple "go away" menu.
1021 if (valid_priv_reply(opts, res2))
1023 /* invalid option */
1024 res2 = ast_play_and_wait(peer, "vm-sorry");
1027 if (ast_test_flag(opts, OPT_MUSICBACK)) {
1029 } else if (ast_test_flag(opts, OPT_RINGBACK)) {
1030 ast_indicate(chan, -1);
1033 ast_autoservice_stop(chan);
1034 if(ast_test_flag(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1035 /* map keypresses to various things, the index is res2 - '1' */
1036 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1037 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1039 if (option_verbose > 2)
1040 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to %s\n",
1041 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1042 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1048 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1051 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1054 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1057 /* XXX should we set status to DENY ? */
1058 if( ast_test_flag(opts, OPT_PRIVACY) )
1060 /* if not privacy, then 5 is the same as "default" case */
1061 default: /* bad input or -1 if failure to start autoservice */
1062 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1063 /* well, there seems basically two choices. Just patch the caller thru immediately,
1064 or,... put 'em thru to voicemail. */
1065 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1066 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1067 /* XXX should we set status to DENY ? */
1068 /* XXX what about the privacy flags ? */
1072 if (res2 == '1') { /* the only case where we actually connect */
1073 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1074 just clog things up, and it's not useful information, not being tied to a CID */
1075 if( strncmp(pa->privcid,"NOCALLERID",10) == 0 || ast_test_flag(opts, OPT_SCREEN_NOINTRO) ) {
1076 ast_filedelete(pa->privintro, NULL);
1077 if( ast_fileexists(pa->privintro, NULL, NULL ) > 0 )
1078 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1079 else if (option_verbose > 2)
1080 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
1082 return 0; /* the good exit path */
1084 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1089 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1090 static int setup_privacy_args(struct privacy_args *pa,
1091 struct ast_flags *opts, char *opt_args[], struct ast_channel *chan)
1097 if (!ast_strlen_zero(chan->cid.cid_num)) {
1098 l = ast_strdupa(chan->cid.cid_num);
1099 ast_shrink_phone_number(l);
1100 if (ast_test_flag(opts, OPT_PRIVACY) ) {
1101 if (option_verbose > 2)
1102 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
1103 opt_args[OPT_ARG_PRIVACY], l);
1104 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1106 if (option_verbose > 2)
1107 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
1108 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1113 tnam = ast_strdupa(chan->name);
1114 /* clean the channel name so slashes don't try to end up in disk file name */
1115 for (tn2 = tnam; *tn2; tn2++) {
1116 if (*tn2=='/') /* any other chars to be afraid of? */
1119 if (option_verbose > 2)
1120 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
1122 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1124 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1127 ast_copy_string(pa->privcid,l,sizeof(pa->privcid));
1129 if( strncmp(pa->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 */
1130 if (option_verbose > 2)
1131 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1132 pa->privdb_val = AST_PRIVACY_ALLOW;
1133 } else if (ast_test_flag(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid,"NOCALLERID",10) == 0 ) {
1134 if (option_verbose > 2)
1135 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1138 if (pa->privdb_val == AST_PRIVACY_DENY ) {
1139 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1140 if (option_verbose > 2)
1141 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1143 } else if (pa->privdb_val == AST_PRIVACY_KILL ) {
1144 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1145 return 0; /* Is this right? */
1146 } else if (pa->privdb_val == AST_PRIVACY_TORTURE ) {
1147 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1148 return 0; /* is this right??? */
1149 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN ) {
1150 /* Get the user's intro, store it in priv-callerintros/$CID,
1151 unless it is already there-- this should be done before the
1152 call is actually dialed */
1154 /* make sure the priv-callerintros dir actually exists */
1155 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1156 if ((res = ast_mkdir(pa->privintro, 0755))) {
1157 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1161 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1162 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1163 /* the DELUX version of this code would allow this caller the
1164 option to hear and retape their previously recorded intro.
1167 int duration; /* for feedback from play_and_wait */
1168 /* the file doesn't exist yet. Let the caller submit his
1169 vocal intro for posterity */
1170 /* priv-recordintro script:
1172 "At the tone, please say your name:"
1176 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1177 /* don't think we'll need a lock removed, we took care of
1178 conflicts by naming the pa.privintro file */
1180 /* Delete the file regardless since they hung up during recording */
1181 ast_filedelete(pa->privintro, NULL);
1182 if (ast_fileexists(pa->privintro,NULL,NULL ) > 0 )
1183 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1184 else if (option_verbose > 2)
1185 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
1188 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1189 ast_waitstream(chan, "");
1192 return 1; /* success */
1195 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
1197 int res = -1; /* default: error */
1198 char *rest, *cur; /* scan the list of destinations */
1199 struct chanlist *outgoing = NULL; /* list of destinations */
1200 struct ast_channel *peer;
1201 int to; /* timeout */
1202 struct cause_args num = { chan, 0, 0, 0 };
1205 char cidname[AST_MAX_EXTENSION] = "";
1207 struct ast_bridge_config config;
1208 unsigned int calldurationlimit = 0;
1209 char *dtmfcalled = NULL, *dtmfcalling = NULL;
1210 struct privacy_args pa = {
1213 .status = "INVALIDARGS",
1215 int sentringing = 0, moh = 0;
1216 const char *outbound_group = NULL;
1221 AST_DECLARE_APP_ARGS(args,
1223 AST_APP_ARG(timeout);
1224 AST_APP_ARG(options);
1227 struct ast_flags opts = { 0, };
1228 char *opt_args[OPT_ARG_ARRAY_SIZE];
1230 if (ast_strlen_zero(data)) {
1231 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1232 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1236 parse = ast_strdupa(data);
1238 AST_STANDARD_APP_ARGS(args, parse);
1240 memset(&config,0,sizeof(struct ast_bridge_config));
1242 if (!ast_strlen_zero(args.options) &&
1243 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
1244 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1248 if (ast_strlen_zero(args.peers)) {
1249 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1250 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1254 if (ast_test_flag(&opts, OPT_OPERMODE)) {
1255 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1256 if (option_verbose > 2)
1257 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
1260 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1261 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1262 if (!calldurationlimit) {
1263 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1264 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1267 if (option_verbose > 2)
1268 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
1271 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1272 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
1273 dtmfcalled = strsep(&dtmfcalling, ":");
1276 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1277 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1281 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
1282 ast_cdr_reset(chan->cdr, NULL);
1283 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1284 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1286 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1287 res = setup_privacy_args(&pa, &opts, opt_args, chan);
1290 res = -1; /* reset default */
1296 /* If a channel group has been specified, get it for use when we create peer channels */
1297 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1298 outbound_group = ast_strdupa(outbound_group);
1299 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1301 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1304 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1305 /* loop through the list of dial destinations */
1307 while ((cur = strsep(&rest, "&")) ) {
1308 struct chanlist *tmp;
1309 struct ast_channel *tc; /* channel for this destination */
1310 /* Get a technology/[device:]number pair */
1312 char *tech = strsep(&number, "/");
1314 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1317 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1320 ast_copy_flags(tmp, &opts,
1321 OPT_CANCEL_ELSEWHERE |
1322 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1323 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1324 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1325 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1326 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1327 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
1329 ast_copy_string(numsubst, number, sizeof(numsubst));
1330 /* Request the peer */
1331 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
1333 /* If we can't, just go on to the next call */
1334 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1335 tech, cause, ast_cause2str(cause));
1336 handle_cause(cause, &num);
1337 if (!rest) /* we are on the last destination */
1338 chan->hangupcause = cause;
1342 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1343 if (!ast_strlen_zero(tc->call_forward)) {
1347 ast_copy_string(tmpchan, tc->call_forward, sizeof(tmpchan));
1348 if ((stuff = strchr(tmpchan, '/'))) {
1352 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tc->call_forward, tc->context);
1357 if (tmp->forwards < AST_MAX_FORWARDS) {
1358 if (option_verbose > 2)
1359 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n",
1360 chan->name, tech, stuff, tc->name);
1362 /* If we have been told to ignore forwards, just set this channel to null
1363 * and continue processing extensions normally */
1364 if (ast_test_flag(&opts, OPT_IGNORE_FORWARDING)) {
1366 cause = AST_CAUSE_BUSY;
1367 if (option_verbose > 2)
1368 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n",
1369 chan->name, tech, stuff);
1371 tc = ast_request(tech, chan->nativeformats, stuff, &cause);
1374 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1376 ast_channel_inherit_variables(chan, tc);
1378 if (option_verbose > 2)
1379 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tc->name);
1382 cause = AST_CAUSE_CONGESTION;
1385 handle_cause(cause, &num);
1391 /* Setup outgoing SDP to match incoming one */
1392 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
1394 /* Inherit specially named variables from parent channel */
1395 ast_channel_inherit_variables(chan, tc);
1397 tc->appl = "AppDial";
1398 tc->data = "(Outgoing Line)";
1399 tc->whentohangup = 0;
1401 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
1402 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
1403 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
1404 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
1406 /* Copy language from incoming to outgoing */
1407 ast_string_field_set(tc, language, chan->language);
1408 ast_string_field_set(tc, accountcode, chan->accountcode);
1409 tc->cdrflags = chan->cdrflags;
1410 if (ast_strlen_zero(tc->musicclass))
1411 ast_string_field_set(tc, musicclass, chan->musicclass);
1412 /* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
1413 tc->cid.cid_pres = chan->cid.cid_pres;
1414 tc->cid.cid_ton = chan->cid.cid_ton;
1415 tc->cid.cid_tns = chan->cid.cid_tns;
1416 tc->adsicpe = chan->adsicpe;
1417 tc->transfercapability = chan->transfercapability;
1419 /* If we have an outbound group, set this peer channel to it */
1421 ast_app_group_set_channel(tc, outbound_group);
1423 /* Inherit context and extension */
1424 if (!ast_strlen_zero(chan->macrocontext))
1425 ast_copy_string(tc->dialcontext, chan->macrocontext, sizeof(tc->dialcontext));
1427 ast_copy_string(tc->dialcontext, chan->context, sizeof(tc->dialcontext));
1428 if (!ast_strlen_zero(chan->macroexten))
1429 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
1431 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
1433 res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
1435 /* Save the info in cdr's that we called them */
1437 ast_cdr_setdestchan(chan->cdr, tc->name);
1439 /* check the results of ast_call */
1441 /* Again, keep going even if there's an error */
1442 ast_debug(1, "ast call on peer returned %d\n", res);
1443 if (option_verbose > 2)
1444 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1450 senddialevent(chan, tc);
1451 if (option_verbose > 2)
1452 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1453 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1454 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1456 /* Put them in the list of outgoing thingies... We're ready now.
1457 XXX If we're forcibly removed, these outgoing calls won't get
1459 ast_set_flag(tmp, DIAL_STILLGOING);
1461 tmp->next = outgoing;
1463 /* If this line is up, don't try anybody else */
1464 if (outgoing->chan->_state == AST_STATE_UP)
1468 if (ast_strlen_zero(args.timeout)) {
1471 to = atoi(args.timeout);
1475 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1479 strcpy(pa.status, "CHANUNAVAIL");
1481 /* Our status will at least be NOANSWER */
1482 strcpy(pa.status, "NOANSWER");
1483 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1485 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1486 char *original_moh = ast_strdupa(chan->musicclass);
1487 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1488 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1489 ast_string_field_set(chan, musicclass, original_moh);
1491 ast_moh_start(chan, NULL, NULL);
1493 ast_indicate(chan, AST_CONTROL_PROGRESS);
1494 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1495 ast_indicate(chan, AST_CONTROL_RINGING);
1501 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
1506 } else if (to) { /* Musta gotten hung up */
1508 } else { /* Nobody answered, next please? */
1511 /* almost done, although the 'else' block is 400 lines */
1514 time_t end_time, answer_time = time(NULL);
1515 char toast[80]; /* buffer to set variables */
1517 strcpy(pa.status, "ANSWER");
1518 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1519 we will always return with -1 so that it is hung up properly after the
1521 hanguptree(outgoing, peer, 1);
1523 /* If appropriate, log that we have a destination channel */
1525 ast_cdr_setdestchan(chan->cdr, peer->name);
1527 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1529 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1532 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1533 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1534 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
1535 ast_channel_sendurl( peer, args.url );
1537 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
1538 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
1543 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1547 /* Start autoservice on the other chan */
1548 res = ast_autoservice_start(chan);
1549 /* Now Stream the File */
1551 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1553 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1555 /* Ok, done. stop autoservice */
1556 res = ast_autoservice_stop(chan);
1557 if (digit > 0 && !res)
1558 res = ast_senddigit(chan, digit);
1564 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1565 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1566 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1567 ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1569 ast_pbx_start(peer);
1570 hanguptree(outgoing, NULL, ast_test_flag(&opts, OPT_CANCEL_ELSEWHERE ? 1 : 0));
1577 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1578 struct ast_app *theapp;
1579 const char *macro_result;
1581 res = ast_autoservice_start(chan);
1583 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1587 theapp = pbx_findapp("Macro");
1589 if (theapp && !res) { /* XXX why check res here ? */
1590 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1591 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1592 ast_debug(1, "Macro exited with status %d\n", res);
1595 ast_log(LOG_ERROR, "Could not find application Macro\n");
1599 if (ast_autoservice_stop(chan) < 0) {
1600 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1604 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1605 char *macro_transfer_dest;
1607 if (!strcasecmp(macro_result, "BUSY")) {
1608 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1609 ast_set_flag(peerflags, OPT_GO_ON);
1611 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1612 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1613 ast_set_flag(peerflags, OPT_GO_ON);
1615 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1616 /* hangup peer and keep chan alive assuming the macro has changed
1617 the context / exten / priority or perhaps
1618 the next priority in the current exten is desired.
1620 ast_set_flag(peerflags, OPT_GO_ON);
1622 } else if (!strcasecmp(macro_result, "ABORT")) {
1623 /* Hangup both ends unless the caller has the g flag */
1625 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1627 /* perform a transfer to a new extension */
1628 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1629 replace_macro_delimiter(macro_transfer_dest);
1630 if (!ast_parseable_goto(chan, macro_transfer_dest))
1631 ast_set_flag(peerflags, OPT_GO_ON);
1637 if (ast_test_flag(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
1638 struct ast_app *theapp;
1639 const char *gosub_result;
1640 char *gosub_args, *gosub_argstart;
1642 res = ast_autoservice_start(chan);
1644 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1648 theapp = pbx_findapp("Gosub");
1650 if (theapp && !res) { /* XXX why check res here ? */
1651 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
1653 /* Set where we came from */
1654 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
1655 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
1658 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], '|');
1659 if (gosub_argstart) {
1660 *gosub_argstart = 0;
1661 asprintf(&gosub_args, "%s|s|1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1);
1662 *gosub_argstart = '|';
1664 asprintf(&gosub_args, "%s|s|1", opt_args[OPT_ARG_CALLEE_GOSUB]);
1668 res = pbx_exec(peer, theapp, gosub_args);
1672 ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
1674 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
1678 ast_log(LOG_ERROR, "Could not find application Gosub\n");
1682 if (ast_autoservice_stop(chan) < 0) {
1683 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1687 if (!res && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
1688 char *gosub_transfer_dest;
1690 if (!strcasecmp(gosub_result, "BUSY")) {
1691 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1692 ast_set_flag(peerflags, OPT_GO_ON);
1694 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
1695 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1696 ast_set_flag(peerflags, OPT_GO_ON);
1698 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
1699 /* hangup peer and keep chan alive assuming the macro has changed
1700 the context / exten / priority or perhaps
1701 the next priority in the current exten is desired.
1703 ast_set_flag(peerflags, OPT_GO_ON);
1705 } else if (!strcasecmp(gosub_result, "ABORT")) {
1706 /* Hangup both ends unless the caller has the g flag */
1708 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
1710 /* perform a transfer to a new extension */
1711 if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
1712 replace_macro_delimiter(gosub_transfer_dest);
1713 if (!ast_parseable_goto(chan, gosub_transfer_dest))
1714 ast_set_flag(peerflags, OPT_GO_ON);
1721 if (calldurationlimit > 0) {
1722 peer->whentohangup = time(NULL) + calldurationlimit;
1724 if (!ast_strlen_zero(dtmfcalled)) {
1725 if (option_verbose > 2)
1726 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1727 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1729 if (!ast_strlen_zero(dtmfcalling)) {
1730 if (option_verbose > 2)
1731 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1732 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1736 if (res) { /* some error */
1738 end_time = time(NULL);
1740 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1741 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1742 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1743 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1744 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1745 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1746 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1747 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1748 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1749 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1750 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1751 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1752 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1753 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1754 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1755 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1760 } else if (sentringing) {
1762 ast_indicate(chan, -1);
1764 /* Be sure no generators are left on it */
1765 ast_deactivate_generator(chan);
1766 /* Make sure channels are compatible */
1767 res = ast_channel_make_compatible(chan, peer);
1769 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1774 if (opermode && !strncmp(chan->name,"Zap",3) && !strncmp(peer->name,"Zap",3)) {
1775 /* XXX what's this special handling for Zap <-> Zap ? */
1776 struct oprmode oprmode;
1778 oprmode.peer = peer;
1779 oprmode.mode = opermode;
1781 ast_channel_setoption(chan,
1782 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1784 res = ast_bridge_call(chan,peer,&config);
1785 end_time = time(NULL);
1786 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1787 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1790 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1791 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1793 if (res != AST_PBX_NO_HANGUP_PEER) {
1794 if (!chan->_softhangup)
1795 chan->hangupcause = peer->hangupcause;
1803 } else if (sentringing) {
1805 ast_indicate(chan, -1);
1807 ast_channel_early_bridge(chan, NULL);
1808 hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
1809 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1810 senddialendevent(chan, pa.status);
1811 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
1813 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
1814 if (calldurationlimit)
1815 chan->whentohangup = 0;
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_flags peerflags;
1839 if (ast_strlen_zero(data)) {
1840 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1844 announce = ast_strdupa(data);
1846 memset(&peerflags, 0, sizeof(peerflags));
1848 if ((dialdata = strchr(announce, '|'))) {
1850 if (sscanf(dialdata, "%d", &sleep) == 1) {
1853 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1856 if ((dialdata = strchr(dialdata, '|'))) {
1858 if (sscanf(dialdata, "%d", &loops) != 1) {
1859 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1865 if ((dialdata = strchr(dialdata, '|'))) {
1868 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1876 loops = -1; /* run forever */
1878 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1884 chan->data = "Retrying";
1885 if (ast_test_flag(chan, AST_FLAG_MOH))
1888 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1893 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1894 if (!ast_strlen_zero(announce)) {
1895 if (ast_fileexists(announce, NULL, chan->language)) {
1896 if(!(res = ast_streamfile(chan, announce, chan->language)))
1897 ast_waitstream(chan, AST_DIGIT_ANY);
1899 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1901 if (!res && sleep) {
1902 if (!ast_test_flag(chan, AST_FLAG_MOH))
1903 ast_moh_start(chan, NULL, NULL);
1904 res = ast_waitfordigit(chan, sleep);
1907 if (!ast_strlen_zero(announce)) {
1908 if (ast_fileexists(announce, NULL, chan->language)) {
1909 if (!(res = ast_streamfile(chan, announce, chan->language)))
1910 res = ast_waitstream(chan, "");
1912 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1915 if (!ast_test_flag(chan, AST_FLAG_MOH))
1916 ast_moh_start(chan, NULL, NULL);
1918 res = ast_waitfordigit(chan, sleep);
1925 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1926 if (onedigit_goto(chan, context, (char) res, 1)) {
1938 if (ast_test_flag(chan, AST_FLAG_MOH))
1944 static int unload_module(void)
1947 struct ast_context *con;
1949 res = ast_unregister_application(app);
1950 res |= ast_unregister_application(rapp);
1952 if ((con = ast_context_find("app_dial_gosub_virtual_context")))
1953 ast_context_remove_extension2(con, "s", 1, NULL);
1958 static int load_module(void)
1961 struct ast_context *con;
1963 con = ast_context_find("app_dial_gosub_virtual_context");
1965 con = ast_context_create(NULL, "app_dial_gosub_virtual_context", "app_dial");
1967 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
1969 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free, "app_dial");
1971 res = ast_register_application(app, dial_exec, synopsis, descrip);
1972 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1977 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");