Turn a NOTICE into a DEBUG message.
[asterisk-bristuff.git] / apps / app_dial.c
blob2d5bf093828b079b12b857b94e1e8a3c6f6312dd
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 retying the call. After 'retires' 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 ast_channel_datastore_remove(chan, datastore);
1324 ast_channel_datastore_free(datastore);
1325 if (!peer) {
1326 if (result) {
1327 res = result;
1328 } else if (to) { /* Musta gotten hung up */
1329 res = -1;
1330 } else { /* Nobody answered, next please? */
1331 res = 0;
1333 /* almost done, although the 'else' block is 400 lines */
1334 } else {
1335 const char *number;
1336 time_t end_time, answer_time = time(NULL);
1338 strcpy(status, "ANSWER");
1339 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1340 we will always return with -1 so that it is hung up properly after the
1341 conversation. */
1342 hanguptree(outgoing, peer);
1343 outgoing = NULL;
1344 /* If appropriate, log that we have a destination channel */
1345 if (chan->cdr)
1346 ast_cdr_setdestchan(chan->cdr, peer->name);
1347 if (peer->name)
1348 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1350 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1351 if (!number)
1352 number = numsubst;
1353 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1354 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1355 if (option_debug)
1356 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1357 ast_channel_sendurl( peer, args.url );
1359 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
1360 int res2;
1361 int loopcount = 0;
1363 /* Get the user's intro, store it in priv-callerintros/$CID,
1364 unless it is already there-- this should be done before the
1365 call is actually dialed */
1367 /* all ring indications and moh for the caller has been halted as soon as the
1368 target extension was picked up. We are going to have to kill some
1369 time and make the caller believe the peer hasn't picked up yet */
1371 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1372 char *original_moh = ast_strdupa(chan->musicclass);
1373 ast_indicate(chan, -1);
1374 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1375 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1376 ast_string_field_set(chan, musicclass, original_moh);
1377 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1378 ast_indicate(chan, AST_CONTROL_RINGING);
1379 sentringing++;
1382 /* Start autoservice on the other chan ?? */
1383 res2 = ast_autoservice_start(chan);
1384 /* Now Stream the File */
1385 for (loopcount = 0; loopcount < 3; loopcount++) {
1386 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1387 break;
1388 if (!res2) /* on timeout, play the message again */
1389 res2 = ast_play_and_wait(peer,"priv-callpending");
1390 if (!valid_priv_reply(&opts, res2))
1391 res2 = 0;
1392 /* priv-callpending script:
1393 "I have a caller waiting, who introduces themselves as:"
1395 if (!res2)
1396 res2 = ast_play_and_wait(peer,privintro);
1397 if (!valid_priv_reply(&opts, res2))
1398 res2 = 0;
1399 /* now get input from the called party, as to their choice */
1400 if( !res2 ) {
1401 /* XXX can we have both, or they are mutually exclusive ? */
1402 if( ast_test_flag(&opts, OPT_PRIVACY) )
1403 res2 = ast_play_and_wait(peer,"priv-callee-options");
1404 if( ast_test_flag(&opts, OPT_SCREENING) )
1405 res2 = ast_play_and_wait(peer,"screen-callee-options");
1407 /*! \page DialPrivacy Dial Privacy scripts
1408 \par priv-callee-options script:
1409 "Dial 1 if you wish this caller to reach you directly in the future,
1410 and immediately connect to their incoming call
1411 Dial 2 if you wish to send this caller to voicemail now and
1412 forevermore.
1413 Dial 3 to send this caller to the torture menus, now and forevermore.
1414 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1415 Dial 5 to allow this caller to come straight thru to you in the future,
1416 but right now, just this once, send them to voicemail."
1417 \par screen-callee-options script:
1418 "Dial 1 if you wish to immediately connect to the incoming call
1419 Dial 2 if you wish to send this caller to voicemail.
1420 Dial 3 to send this caller to the torture menus.
1421 Dial 4 to send this caller to a simple "go away" menu.
1423 if (valid_priv_reply(&opts, res2))
1424 break;
1425 /* invalid option */
1426 res2 = ast_play_and_wait(peer, "vm-sorry");
1429 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1430 ast_moh_stop(chan);
1431 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1432 ast_indicate(chan, -1);
1433 sentringing=0;
1435 ast_autoservice_stop(chan);
1437 switch (res2) {
1438 case '1':
1439 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1440 if (option_verbose > 2)
1441 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1442 opt_args[OPT_ARG_PRIVACY], privcid);
1443 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1445 break;
1446 case '2':
1447 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1448 if (option_verbose > 2)
1449 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1450 opt_args[OPT_ARG_PRIVACY], privcid);
1451 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1453 ast_copy_string(status, "NOANSWER", sizeof(status));
1454 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1455 res=0;
1456 goto out;
1457 case '3':
1458 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1459 if (option_verbose > 2)
1460 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1461 opt_args[OPT_ARG_PRIVACY], privcid);
1462 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1464 ast_copy_string(status, "TORTURE", sizeof(status));
1466 res = 0;
1467 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1468 goto out; /* Is this right? */
1469 case '4':
1470 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1471 if (option_verbose > 2)
1472 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1473 opt_args[OPT_ARG_PRIVACY], privcid);
1474 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1477 ast_copy_string(status, "DONTCALL", sizeof(status));
1478 res = 0;
1479 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1480 goto out; /* Is this right? */
1481 case '5':
1482 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1483 if (option_verbose > 2)
1484 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1485 opt_args[OPT_ARG_PRIVACY], privcid);
1486 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1487 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1488 res=0;
1489 goto out;
1490 } /* if not privacy, then 5 is the same as "default" case */
1491 default: /* bad input or -1 if failure to start autoservice */
1492 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1493 /* well, there seems basically two choices. Just patch the caller thru immediately,
1494 or,... put 'em thru to voicemail. */
1495 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1496 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1497 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1498 res=0;
1499 goto out;
1502 /* XXX once again, this path is only taken in the case '1', so it could be
1503 * moved there, although i am not really sure that this is correct - maybe
1504 * the check applies to other cases as well.
1506 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1507 just clog things up, and it's not useful information, not being tied to a CID */
1508 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1509 ast_filedelete(privintro, NULL);
1510 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1511 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1512 else if (option_verbose > 2)
1513 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1516 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1517 res = 0;
1518 } else {
1519 int digit = 0;
1520 /* Start autoservice on the other chan */
1521 res = ast_autoservice_start(chan);
1522 /* Now Stream the File */
1523 if (!res)
1524 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1525 if (!res) {
1526 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1528 /* Ok, done. stop autoservice */
1529 res = ast_autoservice_stop(chan);
1530 if (digit > 0 && !res)
1531 res = ast_senddigit(chan, digit);
1532 else
1533 res = digit;
1537 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1538 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1539 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1540 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1541 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1542 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1543 peer->priority = chan->priority + 2;
1544 ast_pbx_start(peer);
1545 hanguptree(outgoing, NULL);
1546 if (continue_exec)
1547 *continue_exec = 1;
1548 res = 0;
1549 goto done;
1552 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1553 struct ast_app *theapp;
1554 const char *macro_result;
1556 res = ast_autoservice_start(chan);
1557 if (res) {
1558 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1559 res = -1;
1562 theapp = pbx_findapp("Macro");
1564 if (theapp && !res) { /* XXX why check res here ? */
1565 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1566 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1567 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1568 res = 0;
1569 } else {
1570 ast_log(LOG_ERROR, "Could not find application Macro\n");
1571 res = -1;
1574 if (ast_autoservice_stop(chan) < 0) {
1575 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1576 res = -1;
1579 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1580 char *macro_transfer_dest;
1582 if (!strcasecmp(macro_result, "BUSY")) {
1583 ast_copy_string(status, macro_result, sizeof(status));
1584 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1585 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1586 ast_set_flag(peerflags, OPT_GO_ON);
1588 } else
1589 ast_set_flag(peerflags, OPT_GO_ON);
1590 res = -1;
1591 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1592 ast_copy_string(status, macro_result, sizeof(status));
1593 ast_set_flag(peerflags, OPT_GO_ON);
1594 res = -1;
1595 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1596 /* hangup peer and keep chan alive assuming the macro has changed
1597 the context / exten / priority or perhaps
1598 the next priority in the current exten is desired.
1600 ast_set_flag(peerflags, OPT_GO_ON);
1601 res = -1;
1602 } else if (!strcasecmp(macro_result, "ABORT")) {
1603 /* Hangup both ends unless the caller has the g flag */
1604 res = -1;
1605 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1606 res = -1;
1607 /* perform a transfer to a new extension */
1608 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1609 replace_macro_delimiter(macro_transfer_dest);
1610 if (!ast_parseable_goto(chan, macro_transfer_dest))
1611 ast_set_flag(peerflags, OPT_GO_ON);
1618 if (!res) {
1619 if (calldurationlimit > 0) {
1620 peer->whentohangup = time(NULL) + calldurationlimit;
1622 if (!ast_strlen_zero(dtmfcalled)) {
1623 if (option_verbose > 2)
1624 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1625 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1627 if (!ast_strlen_zero(dtmfcalling)) {
1628 if (option_verbose > 2)
1629 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1630 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1634 if (!res) {
1635 struct ast_bridge_config config;
1637 memset(&config,0,sizeof(struct ast_bridge_config));
1638 if (play_to_caller)
1639 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1640 if (play_to_callee)
1641 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1642 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1643 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1644 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1645 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1646 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1647 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1648 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1649 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1650 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1651 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1652 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1653 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1654 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1655 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1656 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1657 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1659 config.timelimit = timelimit;
1660 config.play_warning = play_warning;
1661 config.warning_freq = warning_freq;
1662 config.warning_sound = warning_sound;
1663 config.end_sound = end_sound;
1664 config.start_sound = start_sound;
1665 if (moh) {
1666 moh = 0;
1667 ast_moh_stop(chan);
1668 } else if (sentringing) {
1669 sentringing = 0;
1670 ast_indicate(chan, -1);
1672 /* Be sure no generators are left on it */
1673 ast_deactivate_generator(chan);
1674 /* Make sure channels are compatible */
1675 res = ast_channel_make_compatible(chan, peer);
1676 if (res < 0) {
1677 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1678 ast_hangup(peer);
1679 res = -1;
1680 goto done;
1682 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
1683 (!strncmp(peer->name,"Zap",3)))
1685 struct oprmode oprmode;
1687 oprmode.peer = peer;
1688 oprmode.mode = opermode;
1690 ast_channel_setoption(chan,
1691 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1693 res = ast_bridge_call(chan,peer,&config);
1694 time(&end_time);
1696 char toast[80];
1697 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1698 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1700 } else {
1701 time(&end_time);
1702 res = -1;
1705 char toast[80];
1706 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1707 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1710 if (res != AST_PBX_NO_HANGUP_PEER) {
1711 if (!chan->_softhangup)
1712 chan->hangupcause = peer->hangupcause;
1713 ast_hangup(peer);
1716 out:
1717 if (moh) {
1718 moh = 0;
1719 ast_moh_stop(chan);
1720 } else if (sentringing) {
1721 sentringing = 0;
1722 ast_indicate(chan, -1);
1724 ast_rtp_early_bridge(chan, NULL);
1725 hanguptree(outgoing, NULL);
1726 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1727 if (option_debug)
1728 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1730 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
1731 if (calldurationlimit)
1732 chan->whentohangup = 0;
1733 res = 0;
1736 done:
1737 ast_module_user_remove(u);
1738 return res;
1741 static int dial_exec(struct ast_channel *chan, void *data)
1743 struct ast_flags peerflags;
1745 memset(&peerflags, 0, sizeof(peerflags));
1747 return dial_exec_full(chan, data, &peerflags, NULL);
1750 static int retrydial_exec(struct ast_channel *chan, void *data)
1752 char *announce = NULL, *dialdata = NULL;
1753 const char *context = NULL;
1754 int sleep = 0, loops = 0, res = -1;
1755 struct ast_module_user *u;
1756 struct ast_flags peerflags;
1758 if (ast_strlen_zero(data)) {
1759 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1760 return -1;
1763 u = ast_module_user_add(chan);
1765 announce = ast_strdupa(data);
1767 memset(&peerflags, 0, sizeof(peerflags));
1769 if ((dialdata = strchr(announce, '|'))) {
1770 *dialdata++ = '\0';
1771 if (sscanf(dialdata, "%d", &sleep) == 1) {
1772 sleep *= 1000;
1773 } else {
1774 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1775 goto done;
1777 if ((dialdata = strchr(dialdata, '|'))) {
1778 *dialdata++ = '\0';
1779 if (sscanf(dialdata, "%d", &loops) != 1) {
1780 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1781 goto done;
1786 if ((dialdata = strchr(dialdata, '|'))) {
1787 *dialdata++ = '\0';
1788 } else {
1789 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1790 goto done;
1793 if (sleep < 1000)
1794 sleep = 10000;
1796 if (!loops)
1797 loops = -1; /* run forever */
1799 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1801 res = 0;
1802 while (loops) {
1803 int continue_exec;
1805 chan->data = "Retrying";
1806 if (ast_test_flag(chan, AST_FLAG_MOH))
1807 ast_moh_stop(chan);
1809 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1810 if (continue_exec)
1811 break;
1813 if (res == 0) {
1814 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1815 if (!ast_strlen_zero(announce)) {
1816 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1817 if(!(res = ast_streamfile(chan, announce, chan->language)))
1818 ast_waitstream(chan, AST_DIGIT_ANY);
1819 } else
1820 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1822 if (!res && sleep) {
1823 if (!ast_test_flag(chan, AST_FLAG_MOH))
1824 ast_moh_start(chan, NULL, NULL);
1825 res = ast_waitfordigit(chan, sleep);
1827 } else {
1828 if (!ast_strlen_zero(announce)) {
1829 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1830 if (!(res = ast_streamfile(chan, announce, chan->language)))
1831 res = ast_waitstream(chan, "");
1832 } else
1833 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1835 if (sleep) {
1836 if (!ast_test_flag(chan, AST_FLAG_MOH))
1837 ast_moh_start(chan, NULL, NULL);
1838 if (!res)
1839 res = ast_waitfordigit(chan, sleep);
1844 if (res < 0)
1845 break;
1846 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1847 if (onedigit_goto(chan, context, (char) res, 1)) {
1848 res = 0;
1849 break;
1852 loops--;
1854 if (loops == 0)
1855 res = 0;
1856 else if (res == 1)
1857 res = 0;
1859 if (ast_test_flag(chan, AST_FLAG_MOH))
1860 ast_moh_stop(chan);
1861 done:
1862 ast_module_user_remove(u);
1863 return res;
1866 static int unload_module(void)
1868 int res;
1870 res = ast_unregister_application(app);
1871 res |= ast_unregister_application(rapp);
1873 ast_module_user_hangup_all();
1875 return res;
1878 static int load_module(void)
1880 int res;
1882 res = ast_register_application(app, dial_exec, synopsis, descrip);
1883 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1885 return res;
1888 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");