Fix another typo in documentation
[asterisk-bristuff.git] / apps / app_dial.c
blobd5e5fe8c90a78ec42d7a4d7987a1c9aa8fd061fc
1 /*
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.
19 /*! \file
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
28 /*** MODULEINFO
29 <depend>chan_local</depend>
30 ***/
33 #include "asterisk.h"
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <sys/time.h>
44 #include <sys/signal.h>
45 #include <sys/stat.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"
81 "be hung up.\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"
88 " is disconnected.\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"
99 "ends the call.\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"
106 " Options:\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"
112 " if it exists.\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"
117 " alone.\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"
132 " dial attempt.\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"
151 " specified.\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"
172 " directory.\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"
187 " back.\n"
188 " p - This option enables screening mode. This is basically Privacy mode\n"
189 " without memory.\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";
222 enum {
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)
256 enum {
257 OPT_ARG_ANNOUNCE = 0,
258 OPT_ARG_SENDDTMF,
259 OPT_ARG_GOTO,
260 OPT_ARG_DURATION_LIMIT,
261 OPT_ARG_MUSICBACK,
262 OPT_ARG_CALLEE_MACRO,
263 OPT_ARG_PRIVACY,
264 OPT_ARG_DURATION_STOP,
265 OPT_ARG_OPERMODE,
266 /* note: this entry _MUST_ be the last one in the enum */
267 OPT_ARG_ARRAY_SIZE,
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) (!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))
305 /* We define a custom "local user" structure because we
306 use it not only for keeping track of what is in use but
307 also for keeping track of who we're dialing. */
309 struct dial_localuser {
310 struct ast_channel *chan;
311 unsigned int flags;
312 struct dial_localuser *next;
316 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
318 /* Hang up a tree of stuff */
319 struct dial_localuser *oo;
320 while (outgoing) {
321 /* Hangup any existing lines we have open */
322 if (outgoing->chan && (outgoing->chan != exception))
323 ast_hangup(outgoing->chan);
324 oo = outgoing;
325 outgoing=outgoing->next;
326 free(oo);
330 #define AST_MAX_WATCHERS 256
332 #define HANDLE_CAUSE(cause, chan) do { \
333 switch(cause) { \
334 case AST_CAUSE_BUSY: \
335 if (chan->cdr) \
336 ast_cdr_busy(chan->cdr); \
337 numbusy++; \
338 break; \
339 case AST_CAUSE_CONGESTION: \
340 if (chan->cdr) \
341 ast_cdr_failed(chan->cdr); \
342 numcongestion++; \
343 break; \
344 case AST_CAUSE_UNREGISTERED: \
345 if (chan->cdr) \
346 ast_cdr_failed(chan->cdr); \
347 numnochan++; \
348 break; \
349 case AST_CAUSE_NORMAL_CLEARING: \
350 break; \
351 default: \
352 numnochan++; \
353 break; \
355 } while (0)
358 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
360 char rexten[2] = { exten, '\0' };
362 if (context) {
363 if (!ast_goto_if_exists(chan, context, rexten, pri))
364 return 1;
365 } else {
366 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
367 return 1;
368 else if (!ast_strlen_zero(chan->macrocontext)) {
369 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
370 return 1;
373 return 0;
377 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
379 const char *context = S_OR(chan->macrocontext, chan->context);
380 const char *exten = S_OR(chan->macroexten, chan->exten);
382 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
385 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
387 /* XXX do we need also CallerIDnum ? */
388 manager_event(EVENT_FLAG_CALL, "Dial",
389 "Source: %s\r\n"
390 "Destination: %s\r\n"
391 "CallerID: %s\r\n"
392 "CallerIDName: %s\r\n"
393 "SrcUniqueID: %s\r\n"
394 "DestUniqueID: %s\r\n",
395 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
396 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
397 dst->uniqueid);
400 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)
402 int numbusy = busystart;
403 int numcongestion = congestionstart;
404 int numnochan = nochanstart;
405 int prestart = busystart + congestionstart + nochanstart;
406 int orig = *to;
407 struct ast_channel *peer = NULL;
408 /* single is set if only one destination is enabled */
409 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
411 if (single) {
412 /* Turn off hold music, etc */
413 ast_deactivate_generator(in);
414 /* If we are calling a single channel, make them compatible for in-band tone purpose */
415 ast_channel_make_compatible(outgoing->chan, in);
419 while (*to && !peer) {
420 struct dial_localuser *o;
421 int pos = 0; /* how many channels do we handle */
422 int numlines = prestart;
423 struct ast_channel *winner;
424 struct ast_channel *watchers[AST_MAX_WATCHERS];
426 watchers[pos++] = in;
427 for (o = outgoing; o; o = o->next) {
428 /* Keep track of important channels */
429 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
430 watchers[pos++] = o->chan;
431 numlines++;
433 if (pos == 1) { /* only the input channel is available */
434 if (numlines == (numbusy + numcongestion + numnochan)) {
435 if (option_verbose > 2)
436 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
437 if (numbusy)
438 strcpy(status, "BUSY");
439 else if (numcongestion)
440 strcpy(status, "CONGESTION");
441 else if (numnochan)
442 strcpy(status, "CHANUNAVAIL");
443 if (ast_opt_priority_jumping || priority_jump)
444 ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
445 } else {
446 if (option_verbose > 2)
447 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
449 *to = 0;
450 return NULL;
452 winner = ast_waitfor_n(watchers, pos, to);
453 for (o = outgoing; o; o = o->next) {
454 struct ast_frame *f;
455 struct ast_channel *c = o->chan;
457 if (c == NULL)
458 continue;
459 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
460 if (!peer) {
461 if (option_verbose > 2)
462 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
463 peer = c;
464 ast_copy_flags(peerflags, o,
465 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
466 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
467 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
468 OPT_CALLEE_PARK | OPT_CALLER_PARK |
469 DIAL_NOFORWARDHTML);
470 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
471 ast_copy_string(c->exten, "", sizeof(c->exten));
473 continue;
475 if (c != winner)
476 continue;
477 if (!ast_strlen_zero(c->call_forward)) {
478 char tmpchan[256];
479 char *stuff;
480 char *tech;
481 int cause;
483 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
484 if ((stuff = strchr(tmpchan, '/'))) {
485 *stuff++ = '\0';
486 tech = tmpchan;
487 } else {
488 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
489 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
490 stuff = tmpchan;
491 tech = "Local";
493 /* Before processing channel, go ahead and check for forwarding */
494 if (option_verbose > 2)
495 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
496 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
497 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
498 if (option_verbose > 2)
499 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
500 c = o->chan = NULL;
501 cause = AST_CAUSE_BUSY;
502 } else {
503 /* Setup parameters */
504 if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
505 if (single)
506 ast_channel_make_compatible(o->chan, in);
507 ast_channel_inherit_variables(in, o->chan);
508 ast_channel_datastore_inherit(in, o->chan);
509 } else
510 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
512 if (!c) {
513 ast_clear_flag(o, DIAL_STILLGOING);
514 HANDLE_CAUSE(cause, in);
515 } else {
516 ast_rtp_make_compatible(c, in, single);
517 if (c->cid.cid_num)
518 free(c->cid.cid_num);
519 c->cid.cid_num = NULL;
520 if (c->cid.cid_name)
521 free(c->cid.cid_name);
522 c->cid.cid_name = NULL;
524 if (ast_test_flag(o, OPT_FORCECLID)) {
525 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
526 ast_string_field_set(c, accountcode, winner->accountcode);
527 c->cdrflags = winner->cdrflags;
528 } else {
529 c->cid.cid_num = ast_strdup(in->cid.cid_num);
530 c->cid.cid_name = ast_strdup(in->cid.cid_name);
531 ast_string_field_set(c, accountcode, in->accountcode);
532 c->cdrflags = in->cdrflags;
535 if (in->cid.cid_ani) {
536 if (c->cid.cid_ani)
537 free(c->cid.cid_ani);
538 c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
540 if (c->cid.cid_rdnis)
541 free(c->cid.cid_rdnis);
542 c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
543 if (ast_call(c, tmpchan, 0)) {
544 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
545 ast_clear_flag(o, DIAL_STILLGOING);
546 ast_hangup(c);
547 c = o->chan = NULL;
548 numnochan++;
549 } else {
550 senddialevent(in, c);
551 /* After calling, set callerid to extension */
552 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
553 char cidname[AST_MAX_EXTENSION] = "";
554 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
558 /* Hangup the original channel now, in case we needed it */
559 ast_hangup(winner);
560 continue;
562 f = ast_read(winner);
563 if (!f) {
564 in->hangupcause = c->hangupcause;
565 ast_hangup(c);
566 c = o->chan = NULL;
567 ast_clear_flag(o, DIAL_STILLGOING);
568 HANDLE_CAUSE(in->hangupcause, in);
569 continue;
571 if (f->frametype == AST_FRAME_CONTROL) {
572 switch(f->subclass) {
573 case AST_CONTROL_ANSWER:
574 /* This is our guy if someone answered. */
575 if (!peer) {
576 if (option_verbose > 2)
577 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
578 peer = c;
579 ast_copy_flags(peerflags, o,
580 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
581 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
582 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
583 OPT_CALLEE_PARK | OPT_CALLER_PARK |
584 DIAL_NOFORWARDHTML);
585 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
586 ast_copy_string(c->exten, "", sizeof(c->exten));
587 /* Setup RTP early bridge if appropriate */
588 if (CAN_EARLY_BRIDGE(peerflags))
589 ast_rtp_early_bridge(in, peer);
591 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
592 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
593 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
594 break;
595 case AST_CONTROL_BUSY:
596 if (option_verbose > 2)
597 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
598 in->hangupcause = c->hangupcause;
599 ast_hangup(c);
600 c = o->chan = NULL;
601 ast_clear_flag(o, DIAL_STILLGOING);
602 HANDLE_CAUSE(AST_CAUSE_BUSY, in);
603 break;
604 case AST_CONTROL_CONGESTION:
605 if (option_verbose > 2)
606 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
607 in->hangupcause = c->hangupcause;
608 ast_hangup(c);
609 c = o->chan = NULL;
610 ast_clear_flag(o, DIAL_STILLGOING);
611 HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
612 break;
613 case AST_CONTROL_RINGING:
614 if (option_verbose > 2)
615 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
616 /* Setup early media if appropriate */
617 if (single && CAN_EARLY_BRIDGE(peerflags))
618 ast_rtp_early_bridge(in, c);
619 if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
620 ast_indicate(in, AST_CONTROL_RINGING);
621 (*sentringing)++;
623 break;
624 case AST_CONTROL_PROGRESS:
625 if (option_verbose > 2)
626 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
627 /* Setup early media if appropriate */
628 if (single && CAN_EARLY_BRIDGE(peerflags))
629 ast_rtp_early_bridge(in, c);
630 if (!ast_test_flag(outgoing, OPT_RINGBACK))
631 ast_indicate(in, AST_CONTROL_PROGRESS);
632 break;
633 case AST_CONTROL_VIDUPDATE:
634 if (option_verbose > 2)
635 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
636 ast_indicate(in, AST_CONTROL_VIDUPDATE);
637 break;
638 case AST_CONTROL_SRCUPDATE:
639 if (option_verbose > 2)
640 ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
641 ast_indicate(in, AST_CONTROL_SRCUPDATE);
642 break;
643 case AST_CONTROL_PROCEEDING:
644 if (option_verbose > 2)
645 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
646 if (single && CAN_EARLY_BRIDGE(peerflags))
647 ast_rtp_early_bridge(in, c);
648 if (!ast_test_flag(outgoing, OPT_RINGBACK))
649 ast_indicate(in, AST_CONTROL_PROCEEDING);
650 break;
651 case AST_CONTROL_HOLD:
652 if (option_verbose > 2)
653 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
654 ast_indicate(in, AST_CONTROL_HOLD);
655 break;
656 case AST_CONTROL_UNHOLD:
657 if (option_verbose > 2)
658 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
659 ast_indicate(in, AST_CONTROL_UNHOLD);
660 break;
661 case AST_CONTROL_OFFHOOK:
662 case AST_CONTROL_FLASH:
663 /* Ignore going off hook and flash */
664 break;
665 case -1:
666 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
667 if (option_verbose > 2)
668 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
669 ast_indicate(in, -1);
670 (*sentringing) = 0;
672 break;
673 default:
674 if (option_debug)
675 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
677 } else if (single) {
678 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
679 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
680 if (ast_write(in, f))
681 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
682 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
683 if (ast_write(in, f))
684 ast_log(LOG_WARNING, "Unable to forward image\n");
685 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
686 if (ast_write(in, f))
687 ast_log(LOG_WARNING, "Unable to send text\n");
688 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
689 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
690 ast_log(LOG_WARNING, "Unable to send URL\n");
693 ast_frfree(f);
694 } /* end for */
695 if (winner == in) {
696 struct ast_frame *f = ast_read(in);
697 #if 0
698 if (f && (f->frametype != AST_FRAME_VOICE))
699 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
700 else if (!f || (f->frametype != AST_FRAME_VOICE))
701 printf("Hangup received on %s\n", in->name);
702 #endif
703 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
704 /* Got hung up */
705 *to = -1;
706 ast_cdr_noanswer(in->cdr);
707 strcpy(status, "CANCEL");
708 if (f)
709 ast_frfree(f);
710 return NULL;
713 if (f && (f->frametype == AST_FRAME_DTMF)) {
714 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
715 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
716 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
717 if (option_verbose > 2)
718 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
719 *to=0;
720 ast_cdr_noanswer(in->cdr);
721 *result = f->subclass;
722 strcpy(status, "CANCEL");
723 ast_frfree(f);
724 return NULL;
728 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
729 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
730 if (option_verbose > 2)
731 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
732 *to=0;
733 ast_cdr_noanswer(in->cdr);
734 strcpy(status, "CANCEL");
735 ast_frfree(f);
736 return NULL;
740 /* Forward HTML stuff */
741 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
742 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
743 ast_log(LOG_WARNING, "Unable to send URL\n");
746 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
747 if (ast_write(outgoing->chan, f))
748 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
750 if (single && (f->frametype == AST_FRAME_CONTROL) &&
751 ((f->subclass == AST_CONTROL_HOLD) ||
752 (f->subclass == AST_CONTROL_UNHOLD) ||
753 (f->subclass == AST_CONTROL_VIDUPDATE) ||
754 (f->subclass == AST_CONTROL_SRCUPDATE))) {
755 if (option_verbose > 2)
756 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
757 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
759 ast_frfree(f);
761 if (!*to && (option_verbose > 2))
762 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
763 if (!*to || ast_check_hangup(in)) {
764 ast_cdr_noanswer(in->cdr);
769 return peer;
772 static void replace_macro_delimiter(char *s)
774 for (; *s; s++)
775 if (*s == '^')
776 *s = '|';
780 /* returns true if there is a valid privacy reply */
781 static int valid_priv_reply(struct ast_flags *opts, int res)
783 if (res < '1')
784 return 0;
785 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
786 return 1;
787 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
788 return 1;
789 return 0;
792 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
794 int res = -1;
795 struct ast_module_user *u;
796 char *rest, *cur;
797 struct dial_localuser *outgoing = NULL;
798 struct ast_channel *peer;
799 int to;
800 int numbusy = 0;
801 int numcongestion = 0;
802 int numnochan = 0;
803 int cause;
804 char numsubst[256];
805 char cidname[AST_MAX_EXTENSION] = "";
806 int privdb_val = 0;
807 unsigned int calldurationlimit = 0;
808 long timelimit = 0;
809 long play_warning = 0;
810 long warning_freq = 0;
811 const char *warning_sound = NULL;
812 const char *end_sound = NULL;
813 const char *start_sound = NULL;
814 char *dtmfcalled = NULL, *dtmfcalling = NULL;
815 char status[256] = "INVALIDARGS";
816 int play_to_caller = 0, play_to_callee = 0;
817 int sentringing = 0, moh = 0;
818 const char *outbound_group = NULL;
819 int result = 0;
820 time_t start_time;
821 char privintro[1024];
822 char privcid[256];
823 char *parse;
824 int opermode = 0;
825 AST_DECLARE_APP_ARGS(args,
826 AST_APP_ARG(peers);
827 AST_APP_ARG(timeout);
828 AST_APP_ARG(options);
829 AST_APP_ARG(url);
831 struct ast_flags opts = { 0, };
832 char *opt_args[OPT_ARG_ARRAY_SIZE];
833 struct ast_datastore *datastore = NULL;
834 int fulldial = 0, num_dialed = 0;
836 if (ast_strlen_zero(data)) {
837 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
838 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
839 return -1;
842 u = ast_module_user_add(chan);
844 parse = ast_strdupa(data);
846 AST_STANDARD_APP_ARGS(args, parse);
848 if (!ast_strlen_zero(args.options) &&
849 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
850 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
851 goto done;
854 if (ast_strlen_zero(args.peers)) {
855 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
856 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
857 goto done;
860 if (ast_test_flag(&opts, OPT_OPERMODE)) {
861 if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
862 opermode = 1;
863 else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
864 if (option_verbose > 2)
865 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
868 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
869 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
870 if (!calldurationlimit) {
871 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
872 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
873 goto done;
875 if (option_verbose > 2)
876 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
879 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
880 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
881 dtmfcalled = strsep(&dtmfcalling, ":");
884 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
885 char *limit_str, *warning_str, *warnfreq_str;
886 const char *var;
888 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
889 limit_str = strsep(&warnfreq_str, ":");
890 warning_str = strsep(&warnfreq_str, ":");
892 timelimit = atol(limit_str);
893 if (warning_str)
894 play_warning = atol(warning_str);
895 if (warnfreq_str)
896 warning_freq = atol(warnfreq_str);
898 if (!timelimit) {
899 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
900 goto done;
901 } else if (play_warning > timelimit) {
902 /* If the first warning is requested _after_ the entire call would end,
903 and no warning frequency is requested, then turn off the warning. If
904 a warning frequency is requested, reduce the 'first warning' time by
905 that frequency until it falls within the call's total time limit.
908 if (!warning_freq) {
909 play_warning = 0;
910 } else {
911 /* XXX fix this!! */
912 while (play_warning > timelimit)
913 play_warning -= warning_freq;
914 if (play_warning < 1)
915 play_warning = warning_freq = 0;
919 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
920 play_to_caller = var ? ast_true(var) : 1;
922 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
923 play_to_callee = var ? ast_true(var) : 0;
925 if (!play_to_caller && !play_to_callee)
926 play_to_caller = 1;
928 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
929 warning_sound = S_OR(var, "timeleft");
931 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
932 end_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
934 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
935 start_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
937 /* undo effect of S(x) in case they are both used */
938 calldurationlimit = 0;
939 /* more efficient to do it like S(x) does since no advanced opts */
940 if (!play_warning && !start_sound && !end_sound && timelimit) {
941 calldurationlimit = timelimit / 1000;
942 if (option_verbose > 2)
943 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
944 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
945 } else if (option_verbose > 2) {
946 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
947 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
948 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
949 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
950 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
951 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
952 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
953 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
954 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
958 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
959 ast_cdr_reset(chan->cdr, NULL);
960 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
961 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
962 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
963 char callerid[60];
964 char *l = chan->cid.cid_num; /* XXX watch out, we are overwriting it */
965 if (!ast_strlen_zero(l)) {
966 ast_shrink_phone_number(l);
967 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
968 if (option_verbose > 2)
969 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
970 opt_args[OPT_ARG_PRIVACY], l);
971 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
973 else {
974 if (option_verbose > 2)
975 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
976 privdb_val = AST_PRIVACY_UNKNOWN;
978 } else {
979 char *tnam, *tn2;
981 tnam = ast_strdupa(chan->name);
982 /* clean the channel name so slashes don't try to end up in disk file name */
983 for(tn2 = tnam; *tn2; tn2++) {
984 if( *tn2=='/')
985 *tn2 = '='; /* any other chars to be afraid of? */
987 if (option_verbose > 2)
988 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
990 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
991 l = callerid;
992 privdb_val = AST_PRIVACY_UNKNOWN;
995 ast_copy_string(privcid,l,sizeof(privcid));
997 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 */
998 if (option_verbose > 2)
999 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
1000 privdb_val = AST_PRIVACY_ALLOW;
1002 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
1003 if (option_verbose > 2)
1004 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
1007 if(privdb_val == AST_PRIVACY_DENY ) {
1008 ast_copy_string(status, "NOANSWER", sizeof(status));
1009 if (option_verbose > 2)
1010 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1011 res=0;
1012 goto out;
1014 else if(privdb_val == AST_PRIVACY_KILL ) {
1015 ast_copy_string(status, "DONTCALL", sizeof(status));
1016 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1017 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
1019 res = 0;
1020 goto out; /* Is this right? */
1022 else if(privdb_val == AST_PRIVACY_TORTURE ) {
1023 ast_copy_string(status, "TORTURE", sizeof(status));
1024 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1025 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
1027 res = 0;
1028 goto out; /* is this right??? */
1030 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
1031 /* Get the user's intro, store it in priv-callerintros/$CID,
1032 unless it is already there-- this should be done before the
1033 call is actually dialed */
1035 /* make sure the priv-callerintros dir actually exists */
1036 snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1037 if (mkdir(privintro, 0755) && errno != EEXIST) {
1038 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
1039 res = -1;
1040 goto out;
1043 snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
1044 if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
1045 /* the DELUX version of this code would allow this caller the
1046 option to hear and retape their previously recorded intro.
1049 else {
1050 int duration; /* for feedback from play_and_wait */
1051 /* the file doesn't exist yet. Let the caller submit his
1052 vocal intro for posterity */
1053 /* priv-recordintro script:
1055 "At the tone, please say your name:"
1058 ast_answer(chan);
1059 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 */
1060 /* don't think we'll need a lock removed, we took care of
1061 conflicts by naming the privintro file */
1062 if (res == -1) {
1063 /* Delete the file regardless since they hung up during recording */
1064 ast_filedelete(privintro, NULL);
1065 if( ast_fileexists(privintro,NULL,NULL ) > 0 )
1066 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
1067 else if (option_verbose > 2)
1068 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1069 goto out;
1071 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
1072 ast_waitstream(chan, "");
1077 if (continue_exec)
1078 *continue_exec = 0;
1080 /* If a channel group has been specified, get it for use when we create peer channels */
1081 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1082 outbound_group = ast_strdupa(outbound_group);
1083 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1084 } else {
1085 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1088 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1089 /* loop through the list of dial destinations */
1090 rest = args.peers;
1091 while ((cur = strsep(&rest, "&")) ) {
1092 struct dial_localuser *tmp;
1093 /* Get a technology/[device:]number pair */
1094 char *number = cur;
1095 char *interface = ast_strdupa(number);
1096 char *tech = strsep(&number, "/");
1097 /* find if we already dialed this interface */
1098 struct ast_dialed_interface *di;
1099 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1100 num_dialed++;
1101 if (!number) {
1102 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1103 goto out;
1105 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1106 goto out;
1107 if (opts.flags) {
1108 ast_copy_flags(tmp, &opts,
1109 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1110 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1111 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1112 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1113 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1114 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
1116 ast_copy_string(numsubst, number, sizeof(numsubst));
1117 /* Request the peer */
1119 ast_channel_lock(chan);
1120 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1121 ast_channel_unlock(chan);
1123 if (datastore)
1124 dialed_interfaces = datastore->data;
1125 else {
1126 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
1127 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1128 free(tmp);
1129 goto out;
1132 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1134 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1135 free(tmp);
1136 goto out;
1139 datastore->data = dialed_interfaces;
1140 AST_LIST_HEAD_INIT(dialed_interfaces);
1142 ast_channel_lock(chan);
1143 ast_channel_datastore_add(chan, datastore);
1144 ast_channel_unlock(chan);
1147 AST_LIST_LOCK(dialed_interfaces);
1148 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1149 if (!strcasecmp(di->interface, interface)) {
1150 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1151 di->interface);
1152 break;
1155 AST_LIST_UNLOCK(dialed_interfaces);
1157 if (di) {
1158 fulldial++;
1159 free(tmp);
1160 continue;
1163 /* It is always ok to dial a Local interface. We only keep track of
1164 * which "real" interfaces have been dialed. The Local channel will
1165 * inherit this list so that if it ends up dialing a real interface,
1166 * it won't call one that has already been called. */
1167 if (strcasecmp(tech, "Local")) {
1168 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1169 AST_LIST_UNLOCK(dialed_interfaces);
1170 free(tmp);
1171 goto out;
1173 strcpy(di->interface, interface);
1175 AST_LIST_LOCK(dialed_interfaces);
1176 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1177 AST_LIST_UNLOCK(dialed_interfaces);
1180 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
1181 if (!tmp->chan) {
1182 /* If we can't, just go on to the next call */
1183 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
1184 HANDLE_CAUSE(cause, chan);
1185 if (!rest) /* we are on the last destination */
1186 chan->hangupcause = cause;
1187 free(tmp);
1188 continue;
1191 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
1193 /* Setup outgoing SDP to match incoming one */
1194 ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
1196 /* Inherit specially named variables from parent channel */
1197 ast_channel_inherit_variables(chan, tmp->chan);
1199 tmp->chan->appl = "AppDial";
1200 tmp->chan->data = "(Outgoing Line)";
1201 tmp->chan->whentohangup = 0;
1203 if (tmp->chan->cid.cid_num)
1204 free(tmp->chan->cid.cid_num);
1205 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
1207 if (tmp->chan->cid.cid_name)
1208 free(tmp->chan->cid.cid_name);
1209 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
1211 if (tmp->chan->cid.cid_ani)
1212 free(tmp->chan->cid.cid_ani);
1213 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
1215 /* Copy language from incoming to outgoing */
1216 ast_string_field_set(tmp->chan, language, chan->language);
1217 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1218 tmp->chan->cdrflags = chan->cdrflags;
1219 if (ast_strlen_zero(tmp->chan->musicclass))
1220 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1221 /* XXX don't we free previous values ? */
1222 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
1223 /* Pass callingpres setting */
1224 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1225 /* Pass type of number */
1226 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1227 /* Pass type of tns */
1228 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1229 /* Presense of ADSI CPE on outgoing channel follows ours */
1230 tmp->chan->adsicpe = chan->adsicpe;
1231 /* Pass the transfer capability */
1232 tmp->chan->transfercapability = chan->transfercapability;
1234 /* If we have an outbound group, set this peer channel to it */
1235 if (outbound_group)
1236 ast_app_group_set_channel(tmp->chan, outbound_group);
1238 /* Inherit context and extension */
1239 if (!ast_strlen_zero(chan->macrocontext))
1240 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
1241 else
1242 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
1243 if (!ast_strlen_zero(chan->macroexten))
1244 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
1245 else
1246 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
1248 /* Place the call, but don't wait on the answer */
1249 res = ast_call(tmp->chan, numsubst, 0);
1251 /* Save the info in cdr's that we called them */
1252 if (chan->cdr)
1253 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1255 /* check the results of ast_call */
1256 if (res) {
1257 /* Again, keep going even if there's an error */
1258 if (option_debug)
1259 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1260 if (option_verbose > 2)
1261 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1262 ast_hangup(tmp->chan);
1263 tmp->chan = NULL;
1264 free(tmp);
1265 continue;
1266 } else {
1267 senddialevent(chan, tmp->chan);
1268 if (option_verbose > 2)
1269 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1270 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1271 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1273 /* Put them in the list of outgoing thingies... We're ready now.
1274 XXX If we're forcibly removed, these outgoing calls won't get
1275 hung up XXX */
1276 ast_set_flag(tmp, DIAL_STILLGOING);
1277 tmp->next = outgoing;
1278 outgoing = tmp;
1279 /* If this line is up, don't try anybody else */
1280 if (outgoing->chan->_state == AST_STATE_UP)
1281 break;
1284 if (ast_strlen_zero(args.timeout)) {
1285 to = -1;
1286 } else {
1287 to = atoi(args.timeout);
1288 if (to > 0)
1289 to *= 1000;
1290 else
1291 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1294 if (!outgoing) {
1295 strcpy(status, "CHANUNAVAIL");
1296 if(fulldial == num_dialed) {
1297 res = -1;
1298 goto out;
1300 } else {
1301 /* Our status will at least be NOANSWER */
1302 strcpy(status, "NOANSWER");
1303 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1304 moh = 1;
1305 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1306 char *original_moh = ast_strdupa(chan->musicclass);
1307 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1308 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1309 ast_string_field_set(chan, musicclass, original_moh);
1310 } else {
1311 ast_moh_start(chan, NULL, NULL);
1313 ast_indicate(chan, AST_CONTROL_PROGRESS);
1314 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1315 ast_indicate(chan, AST_CONTROL_RINGING);
1316 sentringing++;
1320 time(&start_time);
1321 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1323 /* The ast_channel_datastore_remove() function could fail here if the
1324 * datastore was moved to another channel during a masquerade. If this is
1325 * the case, don't free the datastore here because later, when the channel
1326 * to which the datastore was moved hangs up, it will attempt to free this
1327 * datastore again, causing a crash
1329 if (!ast_channel_datastore_remove(chan, datastore))
1330 ast_channel_datastore_free(datastore);
1331 if (!peer) {
1332 if (result) {
1333 res = result;
1334 } else if (to) { /* Musta gotten hung up */
1335 res = -1;
1336 } else { /* Nobody answered, next please? */
1337 res = 0;
1339 /* almost done, although the 'else' block is 400 lines */
1340 } else {
1341 const char *number;
1342 time_t end_time, answer_time = time(NULL);
1344 strcpy(status, "ANSWER");
1345 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1346 we will always return with -1 so that it is hung up properly after the
1347 conversation. */
1348 hanguptree(outgoing, peer);
1349 outgoing = NULL;
1350 /* If appropriate, log that we have a destination channel */
1351 if (chan->cdr)
1352 ast_cdr_setdestchan(chan->cdr, peer->name);
1353 if (peer->name)
1354 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1356 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1357 if (!number)
1358 number = numsubst;
1359 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1360 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1361 if (option_debug)
1362 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1363 ast_channel_sendurl( peer, args.url );
1365 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
1366 int res2;
1367 int loopcount = 0;
1369 /* Get the user's intro, store it in priv-callerintros/$CID,
1370 unless it is already there-- this should be done before the
1371 call is actually dialed */
1373 /* all ring indications and moh for the caller has been halted as soon as the
1374 target extension was picked up. We are going to have to kill some
1375 time and make the caller believe the peer hasn't picked up yet */
1377 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1378 char *original_moh = ast_strdupa(chan->musicclass);
1379 ast_indicate(chan, -1);
1380 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1381 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1382 ast_string_field_set(chan, musicclass, original_moh);
1383 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1384 ast_indicate(chan, AST_CONTROL_RINGING);
1385 sentringing++;
1388 /* Start autoservice on the other chan ?? */
1389 res2 = ast_autoservice_start(chan);
1390 /* Now Stream the File */
1391 for (loopcount = 0; loopcount < 3; loopcount++) {
1392 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1393 break;
1394 if (!res2) /* on timeout, play the message again */
1395 res2 = ast_play_and_wait(peer,"priv-callpending");
1396 if (!valid_priv_reply(&opts, res2))
1397 res2 = 0;
1398 /* priv-callpending script:
1399 "I have a caller waiting, who introduces themselves as:"
1401 if (!res2)
1402 res2 = ast_play_and_wait(peer,privintro);
1403 if (!valid_priv_reply(&opts, res2))
1404 res2 = 0;
1405 /* now get input from the called party, as to their choice */
1406 if( !res2 ) {
1407 /* XXX can we have both, or they are mutually exclusive ? */
1408 if( ast_test_flag(&opts, OPT_PRIVACY) )
1409 res2 = ast_play_and_wait(peer,"priv-callee-options");
1410 if( ast_test_flag(&opts, OPT_SCREENING) )
1411 res2 = ast_play_and_wait(peer,"screen-callee-options");
1413 /*! \page DialPrivacy Dial Privacy scripts
1414 \par priv-callee-options script:
1415 "Dial 1 if you wish this caller to reach you directly in the future,
1416 and immediately connect to their incoming call
1417 Dial 2 if you wish to send this caller to voicemail now and
1418 forevermore.
1419 Dial 3 to send this caller to the torture menus, now and forevermore.
1420 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1421 Dial 5 to allow this caller to come straight thru to you in the future,
1422 but right now, just this once, send them to voicemail."
1423 \par screen-callee-options script:
1424 "Dial 1 if you wish to immediately connect to the incoming call
1425 Dial 2 if you wish to send this caller to voicemail.
1426 Dial 3 to send this caller to the torture menus.
1427 Dial 4 to send this caller to a simple "go away" menu.
1429 if (valid_priv_reply(&opts, res2))
1430 break;
1431 /* invalid option */
1432 res2 = ast_play_and_wait(peer, "vm-sorry");
1435 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1436 ast_moh_stop(chan);
1437 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1438 ast_indicate(chan, -1);
1439 sentringing=0;
1441 ast_autoservice_stop(chan);
1443 switch (res2) {
1444 case '1':
1445 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1446 if (option_verbose > 2)
1447 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1448 opt_args[OPT_ARG_PRIVACY], privcid);
1449 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1451 break;
1452 case '2':
1453 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1454 if (option_verbose > 2)
1455 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1456 opt_args[OPT_ARG_PRIVACY], privcid);
1457 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1459 ast_copy_string(status, "NOANSWER", sizeof(status));
1460 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1461 res=0;
1462 goto out;
1463 case '3':
1464 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1465 if (option_verbose > 2)
1466 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1467 opt_args[OPT_ARG_PRIVACY], privcid);
1468 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1470 ast_copy_string(status, "TORTURE", sizeof(status));
1472 res = 0;
1473 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1474 goto out; /* Is this right? */
1475 case '4':
1476 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1477 if (option_verbose > 2)
1478 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1479 opt_args[OPT_ARG_PRIVACY], privcid);
1480 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1483 ast_copy_string(status, "DONTCALL", sizeof(status));
1484 res = 0;
1485 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1486 goto out; /* Is this right? */
1487 case '5':
1488 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1489 if (option_verbose > 2)
1490 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1491 opt_args[OPT_ARG_PRIVACY], privcid);
1492 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1493 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1494 res=0;
1495 goto out;
1496 } /* if not privacy, then 5 is the same as "default" case */
1497 default: /* bad input or -1 if failure to start autoservice */
1498 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1499 /* well, there seems basically two choices. Just patch the caller thru immediately,
1500 or,... put 'em thru to voicemail. */
1501 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1502 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1503 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1504 res=0;
1505 goto out;
1508 /* XXX once again, this path is only taken in the case '1', so it could be
1509 * moved there, although i am not really sure that this is correct - maybe
1510 * the check applies to other cases as well.
1512 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1513 just clog things up, and it's not useful information, not being tied to a CID */
1514 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1515 ast_filedelete(privintro, NULL);
1516 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1517 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1518 else if (option_verbose > 2)
1519 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1522 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1523 res = 0;
1524 } else {
1525 int digit = 0;
1526 /* Start autoservice on the other chan */
1527 res = ast_autoservice_start(chan);
1528 /* Now Stream the File */
1529 if (!res)
1530 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1531 if (!res) {
1532 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1534 /* Ok, done. stop autoservice */
1535 res = ast_autoservice_stop(chan);
1536 if (digit > 0 && !res)
1537 res = ast_senddigit(chan, digit);
1538 else
1539 res = digit;
1543 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1544 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1545 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1546 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1547 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1548 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1549 peer->priority = chan->priority + 2;
1550 ast_pbx_start(peer);
1551 hanguptree(outgoing, NULL);
1552 if (continue_exec)
1553 *continue_exec = 1;
1554 res = 0;
1555 goto done;
1558 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1559 struct ast_app *theapp;
1560 const char *macro_result;
1562 res = ast_autoservice_start(chan);
1563 if (res) {
1564 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1565 res = -1;
1568 theapp = pbx_findapp("Macro");
1570 if (theapp && !res) { /* XXX why check res here ? */
1571 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1572 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1573 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1574 res = 0;
1575 } else {
1576 ast_log(LOG_ERROR, "Could not find application Macro\n");
1577 res = -1;
1580 if (ast_autoservice_stop(chan) < 0) {
1581 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1582 res = -1;
1585 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1586 char *macro_transfer_dest;
1588 if (!strcasecmp(macro_result, "BUSY")) {
1589 ast_copy_string(status, macro_result, sizeof(status));
1590 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1591 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1592 ast_set_flag(peerflags, OPT_GO_ON);
1594 } else
1595 ast_set_flag(peerflags, OPT_GO_ON);
1596 res = -1;
1597 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1598 ast_copy_string(status, macro_result, sizeof(status));
1599 ast_set_flag(peerflags, OPT_GO_ON);
1600 res = -1;
1601 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1602 /* hangup peer and keep chan alive assuming the macro has changed
1603 the context / exten / priority or perhaps
1604 the next priority in the current exten is desired.
1606 ast_set_flag(peerflags, OPT_GO_ON);
1607 res = -1;
1608 } else if (!strcasecmp(macro_result, "ABORT")) {
1609 /* Hangup both ends unless the caller has the g flag */
1610 res = -1;
1611 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1612 res = -1;
1613 /* perform a transfer to a new extension */
1614 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1615 replace_macro_delimiter(macro_transfer_dest);
1616 if (!ast_parseable_goto(chan, macro_transfer_dest))
1617 ast_set_flag(peerflags, OPT_GO_ON);
1624 if (!res) {
1625 if (calldurationlimit > 0) {
1626 peer->whentohangup = time(NULL) + calldurationlimit;
1628 if (!ast_strlen_zero(dtmfcalled)) {
1629 if (option_verbose > 2)
1630 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1631 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1633 if (!ast_strlen_zero(dtmfcalling)) {
1634 if (option_verbose > 2)
1635 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1636 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1640 if (!res) {
1641 struct ast_bridge_config config;
1643 memset(&config,0,sizeof(struct ast_bridge_config));
1644 if (play_to_caller)
1645 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1646 if (play_to_callee)
1647 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1648 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1649 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1650 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1651 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1652 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1653 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1654 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1655 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1656 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1657 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1658 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1659 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1660 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1661 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1662 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1663 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1665 config.timelimit = timelimit;
1666 config.play_warning = play_warning;
1667 config.warning_freq = warning_freq;
1668 config.warning_sound = warning_sound;
1669 config.end_sound = end_sound;
1670 config.start_sound = start_sound;
1671 if (moh) {
1672 moh = 0;
1673 ast_moh_stop(chan);
1674 } else if (sentringing) {
1675 sentringing = 0;
1676 ast_indicate(chan, -1);
1678 /* Be sure no generators are left on it */
1679 ast_deactivate_generator(chan);
1680 /* Make sure channels are compatible */
1681 res = ast_channel_make_compatible(chan, peer);
1682 if (res < 0) {
1683 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1684 ast_hangup(peer);
1685 res = -1;
1686 goto done;
1688 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
1689 (!strncmp(peer->name,"Zap",3)))
1691 struct oprmode oprmode;
1693 oprmode.peer = peer;
1694 oprmode.mode = opermode;
1696 ast_channel_setoption(chan,
1697 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1699 res = ast_bridge_call(chan,peer,&config);
1700 time(&end_time);
1702 char toast[80];
1703 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1704 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1706 } else {
1707 time(&end_time);
1708 res = -1;
1711 char toast[80];
1712 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1713 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1716 if (res != AST_PBX_NO_HANGUP_PEER) {
1717 if (!chan->_softhangup)
1718 chan->hangupcause = peer->hangupcause;
1719 ast_hangup(peer);
1722 out:
1723 if (moh) {
1724 moh = 0;
1725 ast_moh_stop(chan);
1726 } else if (sentringing) {
1727 sentringing = 0;
1728 ast_indicate(chan, -1);
1730 ast_rtp_early_bridge(chan, NULL);
1731 hanguptree(outgoing, NULL);
1732 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1733 if (option_debug)
1734 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1736 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
1737 if (calldurationlimit)
1738 chan->whentohangup = 0;
1739 res = 0;
1742 done:
1743 ast_module_user_remove(u);
1744 return res;
1747 static int dial_exec(struct ast_channel *chan, void *data)
1749 struct ast_flags peerflags;
1751 memset(&peerflags, 0, sizeof(peerflags));
1753 return dial_exec_full(chan, data, &peerflags, NULL);
1756 static int retrydial_exec(struct ast_channel *chan, void *data)
1758 char *announce = NULL, *dialdata = NULL;
1759 const char *context = NULL;
1760 int sleep = 0, loops = 0, res = -1;
1761 struct ast_module_user *u;
1762 struct ast_flags peerflags;
1764 if (ast_strlen_zero(data)) {
1765 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1766 return -1;
1769 u = ast_module_user_add(chan);
1771 announce = ast_strdupa(data);
1773 memset(&peerflags, 0, sizeof(peerflags));
1775 if ((dialdata = strchr(announce, '|'))) {
1776 *dialdata++ = '\0';
1777 if (sscanf(dialdata, "%d", &sleep) == 1) {
1778 sleep *= 1000;
1779 } else {
1780 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1781 goto done;
1783 if ((dialdata = strchr(dialdata, '|'))) {
1784 *dialdata++ = '\0';
1785 if (sscanf(dialdata, "%d", &loops) != 1) {
1786 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1787 goto done;
1792 if ((dialdata = strchr(dialdata, '|'))) {
1793 *dialdata++ = '\0';
1794 } else {
1795 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1796 goto done;
1799 if (sleep < 1000)
1800 sleep = 10000;
1802 if (!loops)
1803 loops = -1; /* run forever */
1805 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1807 res = 0;
1808 while (loops) {
1809 int continue_exec;
1811 chan->data = "Retrying";
1812 if (ast_test_flag(chan, AST_FLAG_MOH))
1813 ast_moh_stop(chan);
1815 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1816 if (continue_exec)
1817 break;
1819 if (res == 0) {
1820 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1821 if (!ast_strlen_zero(announce)) {
1822 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1823 if(!(res = ast_streamfile(chan, announce, chan->language)))
1824 ast_waitstream(chan, AST_DIGIT_ANY);
1825 } else
1826 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1828 if (!res && sleep) {
1829 if (!ast_test_flag(chan, AST_FLAG_MOH))
1830 ast_moh_start(chan, NULL, NULL);
1831 res = ast_waitfordigit(chan, sleep);
1833 } else {
1834 if (!ast_strlen_zero(announce)) {
1835 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1836 if (!(res = ast_streamfile(chan, announce, chan->language)))
1837 res = ast_waitstream(chan, "");
1838 } else
1839 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1841 if (sleep) {
1842 if (!ast_test_flag(chan, AST_FLAG_MOH))
1843 ast_moh_start(chan, NULL, NULL);
1844 if (!res)
1845 res = ast_waitfordigit(chan, sleep);
1850 if (res < 0)
1851 break;
1852 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1853 if (onedigit_goto(chan, context, (char) res, 1)) {
1854 res = 0;
1855 break;
1858 loops--;
1860 if (loops == 0)
1861 res = 0;
1862 else if (res == 1)
1863 res = 0;
1865 if (ast_test_flag(chan, AST_FLAG_MOH))
1866 ast_moh_stop(chan);
1867 done:
1868 ast_module_user_remove(u);
1869 return res;
1872 static int unload_module(void)
1874 int res;
1876 res = ast_unregister_application(app);
1877 res |= ast_unregister_application(rapp);
1879 ast_module_user_hangup_all();
1881 return res;
1884 static int load_module(void)
1886 int res;
1888 res = ast_register_application(app, dial_exec, synopsis, descrip);
1889 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1891 return res;
1894 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");