Fix a memory leak in func_curl. Every thread that used this function leaked
[asterisk-bristuff.git] / apps / app_dial.c
blobfb46e58372d6bbc2a208bcd701d434092cd16bad
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,chan,peer) (!ast_test_flag(flags, OPT_CALLEE_HANGUP | \
302 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
303 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK) && \
304 !chan->audiohooks && !peer->audiohooks)
306 /* We define a custom "local user" structure because we
307 use it not only for keeping track of what is in use but
308 also for keeping track of who we're dialing. */
310 struct dial_localuser {
311 struct ast_channel *chan;
312 unsigned int flags;
313 struct dial_localuser *next;
317 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
319 /* Hang up a tree of stuff */
320 struct dial_localuser *oo;
321 while (outgoing) {
322 /* Hangup any existing lines we have open */
323 if (outgoing->chan && (outgoing->chan != exception))
324 ast_hangup(outgoing->chan);
325 oo = outgoing;
326 outgoing=outgoing->next;
327 free(oo);
331 #define AST_MAX_WATCHERS 256
333 #define HANDLE_CAUSE(cause, chan) do { \
334 switch(cause) { \
335 case AST_CAUSE_BUSY: \
336 if (chan->cdr) \
337 ast_cdr_busy(chan->cdr); \
338 numbusy++; \
339 break; \
340 case AST_CAUSE_CONGESTION: \
341 if (chan->cdr) \
342 ast_cdr_failed(chan->cdr); \
343 numcongestion++; \
344 break; \
345 case AST_CAUSE_NO_ROUTE_DESTINATION: \
346 case AST_CAUSE_UNREGISTERED: \
347 if (chan->cdr) \
348 ast_cdr_failed(chan->cdr); \
349 numnochan++; \
350 break; \
351 case AST_CAUSE_NORMAL_CLEARING: \
352 break; \
353 default: \
354 numnochan++; \
355 break; \
357 } while (0)
360 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
362 char rexten[2] = { exten, '\0' };
364 if (context) {
365 if (!ast_goto_if_exists(chan, context, rexten, pri))
366 return 1;
367 } else {
368 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
369 return 1;
370 else if (!ast_strlen_zero(chan->macrocontext)) {
371 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
372 return 1;
375 return 0;
379 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
381 const char *context = S_OR(chan->macrocontext, chan->context);
382 const char *exten = S_OR(chan->macroexten, chan->exten);
384 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
387 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
389 /* XXX do we need also CallerIDnum ? */
390 manager_event(EVENT_FLAG_CALL, "Dial",
391 "Source: %s\r\n"
392 "Destination: %s\r\n"
393 "CallerID: %s\r\n"
394 "CallerIDName: %s\r\n"
395 "SrcUniqueID: %s\r\n"
396 "DestUniqueID: %s\r\n",
397 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
398 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
399 dst->uniqueid);
402 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
404 int numbusy = busystart;
405 int numcongestion = congestionstart;
406 int numnochan = nochanstart;
407 int prestart = busystart + congestionstart + nochanstart;
408 int orig = *to;
409 struct ast_channel *peer = NULL;
410 /* single is set if only one destination is enabled */
411 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
413 if (single) {
414 /* Turn off hold music, etc */
415 ast_deactivate_generator(in);
416 /* If we are calling a single channel, make them compatible for in-band tone purpose */
417 ast_channel_make_compatible(outgoing->chan, in);
421 while (*to && !peer) {
422 struct dial_localuser *o;
423 int pos = 0; /* how many channels do we handle */
424 int numlines = prestart;
425 struct ast_channel *winner;
426 struct ast_channel *watchers[AST_MAX_WATCHERS];
428 watchers[pos++] = in;
429 for (o = outgoing; o; o = o->next) {
430 /* Keep track of important channels */
431 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
432 watchers[pos++] = o->chan;
433 numlines++;
435 if (pos == 1) { /* only the input channel is available */
436 if (numlines == (numbusy + numcongestion + numnochan)) {
437 if (option_verbose > 2)
438 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
439 if (numbusy)
440 strcpy(status, "BUSY");
441 else if (numcongestion)
442 strcpy(status, "CONGESTION");
443 else if (numnochan)
444 strcpy(status, "CHANUNAVAIL");
445 if (ast_opt_priority_jumping || priority_jump)
446 ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
447 } else {
448 if (option_verbose > 2)
449 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
451 *to = 0;
452 return NULL;
454 winner = ast_waitfor_n(watchers, pos, to);
455 for (o = outgoing; o; o = o->next) {
456 struct ast_frame *f;
457 struct ast_channel *c = o->chan;
459 if (c == NULL)
460 continue;
461 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
462 if (!peer) {
463 if (option_verbose > 2)
464 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
465 peer = c;
466 ast_copy_flags(peerflags, o,
467 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
468 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
469 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
470 OPT_CALLEE_PARK | OPT_CALLER_PARK |
471 DIAL_NOFORWARDHTML);
472 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
473 ast_copy_string(c->exten, "", sizeof(c->exten));
475 continue;
477 if (c != winner)
478 continue;
479 if (!ast_strlen_zero(c->call_forward)) {
480 char tmpchan[256];
481 char *stuff;
482 char *tech;
483 int cause;
485 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
486 if ((stuff = strchr(tmpchan, '/'))) {
487 *stuff++ = '\0';
488 tech = tmpchan;
489 } else {
490 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
491 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
492 stuff = tmpchan;
493 tech = "Local";
495 /* Before processing channel, go ahead and check for forwarding */
496 if (option_verbose > 2)
497 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
498 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
499 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
500 if (option_verbose > 2)
501 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
502 c = o->chan = NULL;
503 cause = AST_CAUSE_BUSY;
504 } else {
505 /* Setup parameters */
506 if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
507 if (single)
508 ast_channel_make_compatible(o->chan, in);
509 ast_channel_inherit_variables(in, o->chan);
510 ast_channel_datastore_inherit(in, o->chan);
511 } else
512 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
514 if (!c) {
515 ast_clear_flag(o, DIAL_STILLGOING);
516 HANDLE_CAUSE(cause, in);
517 } else {
518 ast_rtp_make_compatible(c, in, single);
519 if (c->cid.cid_num)
520 free(c->cid.cid_num);
521 c->cid.cid_num = NULL;
522 if (c->cid.cid_name)
523 free(c->cid.cid_name);
524 c->cid.cid_name = NULL;
526 if (ast_test_flag(o, OPT_FORCECLID)) {
527 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
528 ast_string_field_set(c, accountcode, winner->accountcode);
529 c->cdrflags = winner->cdrflags;
530 } else {
531 c->cid.cid_num = ast_strdup(in->cid.cid_num);
532 c->cid.cid_name = ast_strdup(in->cid.cid_name);
533 ast_string_field_set(c, accountcode, in->accountcode);
534 c->cdrflags = in->cdrflags;
537 if (in->cid.cid_ani) {
538 if (c->cid.cid_ani)
539 free(c->cid.cid_ani);
540 c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
542 if (c->cid.cid_rdnis)
543 free(c->cid.cid_rdnis);
544 c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
545 if (ast_call(c, tmpchan, 0)) {
546 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
547 ast_clear_flag(o, DIAL_STILLGOING);
548 ast_hangup(c);
549 c = o->chan = NULL;
550 numnochan++;
551 } else {
552 senddialevent(in, c);
553 /* After calling, set callerid to extension */
554 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
555 char cidname[AST_MAX_EXTENSION] = "";
556 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
560 /* Hangup the original channel now, in case we needed it */
561 ast_hangup(winner);
562 continue;
564 f = ast_read(winner);
565 if (!f) {
566 in->hangupcause = c->hangupcause;
567 ast_hangup(c);
568 c = o->chan = NULL;
569 ast_clear_flag(o, DIAL_STILLGOING);
570 HANDLE_CAUSE(in->hangupcause, in);
571 continue;
573 if (f->frametype == AST_FRAME_CONTROL) {
574 switch(f->subclass) {
575 case AST_CONTROL_ANSWER:
576 /* This is our guy if someone answered. */
577 if (!peer) {
578 if (option_verbose > 2)
579 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
580 peer = c;
581 ast_copy_flags(peerflags, o,
582 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
583 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
584 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
585 OPT_CALLEE_PARK | OPT_CALLER_PARK |
586 DIAL_NOFORWARDHTML);
587 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
588 ast_copy_string(c->exten, "", sizeof(c->exten));
589 /* Setup RTP early bridge if appropriate */
590 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
591 ast_rtp_early_bridge(in, peer);
593 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
594 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
595 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
596 break;
597 case AST_CONTROL_BUSY:
598 if (option_verbose > 2)
599 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
600 in->hangupcause = c->hangupcause;
601 ast_hangup(c);
602 c = o->chan = NULL;
603 ast_clear_flag(o, DIAL_STILLGOING);
604 HANDLE_CAUSE(AST_CAUSE_BUSY, in);
605 break;
606 case AST_CONTROL_CONGESTION:
607 if (option_verbose > 2)
608 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
609 in->hangupcause = c->hangupcause;
610 ast_hangup(c);
611 c = o->chan = NULL;
612 ast_clear_flag(o, DIAL_STILLGOING);
613 HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
614 break;
615 case AST_CONTROL_RINGING:
616 if (option_verbose > 2)
617 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
618 /* Setup early media if appropriate */
619 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
620 ast_rtp_early_bridge(in, c);
621 if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
622 ast_indicate(in, AST_CONTROL_RINGING);
623 (*sentringing)++;
625 break;
626 case AST_CONTROL_PROGRESS:
627 if (option_verbose > 2)
628 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
629 /* Setup early media if appropriate */
630 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
631 ast_rtp_early_bridge(in, c);
632 if (!ast_test_flag(outgoing, OPT_RINGBACK))
633 ast_indicate(in, AST_CONTROL_PROGRESS);
634 break;
635 case AST_CONTROL_VIDUPDATE:
636 if (option_verbose > 2)
637 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
638 ast_indicate(in, AST_CONTROL_VIDUPDATE);
639 break;
640 case AST_CONTROL_SRCUPDATE:
641 if (option_verbose > 2)
642 ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
643 ast_indicate(in, AST_CONTROL_SRCUPDATE);
644 break;
645 case AST_CONTROL_PROCEEDING:
646 if (option_verbose > 2)
647 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
648 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
649 ast_rtp_early_bridge(in, c);
650 if (!ast_test_flag(outgoing, OPT_RINGBACK))
651 ast_indicate(in, AST_CONTROL_PROCEEDING);
652 break;
653 case AST_CONTROL_HOLD:
654 if (option_verbose > 2)
655 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
656 ast_indicate(in, AST_CONTROL_HOLD);
657 break;
658 case AST_CONTROL_UNHOLD:
659 if (option_verbose > 2)
660 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
661 ast_indicate(in, AST_CONTROL_UNHOLD);
662 break;
663 case AST_CONTROL_OFFHOOK:
664 case AST_CONTROL_FLASH:
665 /* Ignore going off hook and flash */
666 break;
667 case -1:
668 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
669 if (option_verbose > 2)
670 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
671 ast_indicate(in, -1);
672 (*sentringing) = 0;
674 break;
675 default:
676 if (option_debug)
677 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
679 } else if (single) {
680 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
681 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
682 if (ast_write(in, f))
683 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
684 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
685 if (ast_write(in, f))
686 ast_log(LOG_WARNING, "Unable to forward image\n");
687 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
688 if (ast_write(in, f))
689 ast_log(LOG_WARNING, "Unable to send text\n");
690 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
691 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
692 ast_log(LOG_WARNING, "Unable to send URL\n");
695 ast_frfree(f);
696 } /* end for */
697 if (winner == in) {
698 struct ast_frame *f = ast_read(in);
699 #if 0
700 if (f && (f->frametype != AST_FRAME_VOICE))
701 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
702 else if (!f || (f->frametype != AST_FRAME_VOICE))
703 printf("Hangup received on %s\n", in->name);
704 #endif
705 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
706 /* Got hung up */
707 *to = -1;
708 ast_cdr_noanswer(in->cdr);
709 strcpy(status, "CANCEL");
710 if (f)
711 ast_frfree(f);
712 return NULL;
715 if (f && (f->frametype == AST_FRAME_DTMF)) {
716 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
717 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
718 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
719 if (option_verbose > 2)
720 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
721 *to=0;
722 ast_cdr_noanswer(in->cdr);
723 *result = f->subclass;
724 strcpy(status, "CANCEL");
725 ast_frfree(f);
726 return NULL;
730 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
731 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
732 if (option_verbose > 2)
733 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
734 *to=0;
735 ast_cdr_noanswer(in->cdr);
736 strcpy(status, "CANCEL");
737 ast_frfree(f);
738 return NULL;
742 /* Forward HTML stuff */
743 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
744 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
745 ast_log(LOG_WARNING, "Unable to send URL\n");
748 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
749 if (ast_write(outgoing->chan, f))
750 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
752 if (single && (f->frametype == AST_FRAME_CONTROL) &&
753 ((f->subclass == AST_CONTROL_HOLD) ||
754 (f->subclass == AST_CONTROL_UNHOLD) ||
755 (f->subclass == AST_CONTROL_VIDUPDATE) ||
756 (f->subclass == AST_CONTROL_SRCUPDATE))) {
757 if (option_verbose > 2)
758 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
759 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
761 ast_frfree(f);
763 if (!*to && (option_verbose > 2))
764 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
765 if (!*to || ast_check_hangup(in)) {
766 ast_cdr_noanswer(in->cdr);
771 return peer;
774 static void replace_macro_delimiter(char *s)
776 for (; *s; s++)
777 if (*s == '^')
778 *s = '|';
782 /* returns true if there is a valid privacy reply */
783 static int valid_priv_reply(struct ast_flags *opts, int res)
785 if (res < '1')
786 return 0;
787 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
788 return 1;
789 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
790 return 1;
791 return 0;
794 static void set_dial_features(struct ast_flags *opts, struct ast_dial_features *features)
796 struct ast_flags perm_opts = {.flags = 0};
798 ast_copy_flags(&perm_opts, opts,
799 OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_HANGUP |
800 OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_HANGUP);
802 memset(features->options, 0, sizeof(features->options));
804 ast_app_options2str(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
805 if (ast_test_flag(&perm_opts, OPT_CALLEE_TRANSFER))
806 ast_set_flag(&(features->features_callee), AST_FEATURE_REDIRECT);
807 if (ast_test_flag(&perm_opts, OPT_CALLER_TRANSFER))
808 ast_set_flag(&(features->features_caller), AST_FEATURE_REDIRECT);
809 if (ast_test_flag(&perm_opts, OPT_CALLEE_HANGUP))
810 ast_set_flag(&(features->features_callee), AST_FEATURE_DISCONNECT);
811 if (ast_test_flag(&perm_opts, OPT_CALLER_HANGUP))
812 ast_set_flag(&(features->features_caller), AST_FEATURE_DISCONNECT);
813 if (ast_test_flag(&perm_opts, OPT_CALLEE_MONITOR))
814 ast_set_flag(&(features->features_callee), AST_FEATURE_AUTOMON);
815 if (ast_test_flag(&perm_opts, OPT_CALLER_MONITOR))
816 ast_set_flag(&(features->features_caller), AST_FEATURE_AUTOMON);
817 if (ast_test_flag(&perm_opts, OPT_CALLEE_PARK))
818 ast_set_flag(&(features->features_callee), AST_FEATURE_PARKCALL);
819 if (ast_test_flag(&perm_opts, OPT_CALLER_PARK))
820 ast_set_flag(&(features->features_caller), AST_FEATURE_PARKCALL);
823 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
825 int res = -1;
826 struct ast_module_user *u;
827 char *rest, *cur;
828 struct dial_localuser *outgoing = NULL;
829 struct ast_channel *peer;
830 int to;
831 int numbusy = 0;
832 int numcongestion = 0;
833 int numnochan = 0;
834 int cause;
835 char numsubst[256];
836 char cidname[AST_MAX_EXTENSION] = "";
837 int privdb_val = 0;
838 unsigned int calldurationlimit = 0;
839 long timelimit = 0;
840 long play_warning = 0;
841 long warning_freq = 0;
842 const char *warning_sound = NULL;
843 const char *end_sound = NULL;
844 const char *start_sound = NULL;
845 char *dtmfcalled = NULL, *dtmfcalling = NULL;
846 char status[256] = "INVALIDARGS";
847 int play_to_caller = 0, play_to_callee = 0;
848 int sentringing = 0, moh = 0;
849 const char *outbound_group = NULL;
850 int result = 0;
851 time_t start_time;
852 char privintro[1024];
853 char privcid[256];
854 char *parse;
855 int opermode = 0;
856 AST_DECLARE_APP_ARGS(args,
857 AST_APP_ARG(peers);
858 AST_APP_ARG(timeout);
859 AST_APP_ARG(options);
860 AST_APP_ARG(url);
862 struct ast_flags opts = { 0, };
863 char *opt_args[OPT_ARG_ARRAY_SIZE];
864 struct ast_datastore *datastore = NULL;
865 struct ast_datastore *ds_caller_features = NULL;
866 struct ast_datastore *ds_callee_features = NULL;
867 struct ast_dial_features *caller_features;
868 int fulldial = 0, num_dialed = 0;
870 if (ast_strlen_zero(data)) {
871 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
872 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
873 return -1;
876 u = ast_module_user_add(chan);
878 parse = ast_strdupa(data);
880 AST_STANDARD_APP_ARGS(args, parse);
882 if (!ast_strlen_zero(args.options) &&
883 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
884 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
885 goto done;
888 if (ast_strlen_zero(args.peers)) {
889 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
890 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
891 goto done;
894 if (ast_test_flag(&opts, OPT_OPERMODE)) {
895 if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
896 opermode = 1;
897 else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
898 if (option_verbose > 2)
899 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
902 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
903 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
904 if (!calldurationlimit) {
905 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
906 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
907 goto done;
909 if (option_verbose > 2)
910 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
913 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
914 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
915 dtmfcalled = strsep(&dtmfcalling, ":");
918 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
919 char *limit_str, *warning_str, *warnfreq_str;
920 const char *var;
922 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
923 limit_str = strsep(&warnfreq_str, ":");
924 warning_str = strsep(&warnfreq_str, ":");
926 timelimit = atol(limit_str);
927 if (warning_str)
928 play_warning = atol(warning_str);
929 if (warnfreq_str)
930 warning_freq = atol(warnfreq_str);
932 if (!timelimit) {
933 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
934 goto done;
935 } else if (play_warning > timelimit) {
936 /* If the first warning is requested _after_ the entire call would end,
937 and no warning frequency is requested, then turn off the warning. If
938 a warning frequency is requested, reduce the 'first warning' time by
939 that frequency until it falls within the call's total time limit.
942 if (!warning_freq) {
943 play_warning = 0;
944 } else {
945 /* XXX fix this!! */
946 while (play_warning > timelimit)
947 play_warning -= warning_freq;
948 if (play_warning < 1)
949 play_warning = warning_freq = 0;
953 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
954 play_to_caller = var ? ast_true(var) : 1;
956 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
957 play_to_callee = var ? ast_true(var) : 0;
959 if (!play_to_caller && !play_to_callee)
960 play_to_caller = 1;
962 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
963 warning_sound = S_OR(var, "timeleft");
965 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
966 end_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
968 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
969 start_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
971 /* undo effect of S(x) in case they are both used */
972 calldurationlimit = 0;
973 /* more efficient to do it like S(x) does since no advanced opts */
974 if (!play_warning && !start_sound && !end_sound && timelimit) {
975 calldurationlimit = timelimit / 1000;
976 if (option_verbose > 2)
977 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
978 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
979 } else if (option_verbose > 2) {
980 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
981 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
982 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
983 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
984 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
985 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
986 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
987 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
988 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
992 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
993 ast_cdr_reset(chan->cdr, NULL);
994 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
995 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
996 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
997 char callerid[60];
998 char *l = chan->cid.cid_num; /* XXX watch out, we are overwriting it */
999 if (!ast_strlen_zero(l)) {
1000 ast_shrink_phone_number(l);
1001 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1002 if (option_verbose > 2)
1003 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
1004 opt_args[OPT_ARG_PRIVACY], l);
1005 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1007 else {
1008 if (option_verbose > 2)
1009 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
1010 privdb_val = AST_PRIVACY_UNKNOWN;
1012 } else {
1013 char *tnam, *tn2;
1015 tnam = ast_strdupa(chan->name);
1016 /* clean the channel name so slashes don't try to end up in disk file name */
1017 for(tn2 = tnam; *tn2; tn2++) {
1018 if( *tn2=='/')
1019 *tn2 = '='; /* any other chars to be afraid of? */
1021 if (option_verbose > 2)
1022 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
1024 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1025 l = callerid;
1026 privdb_val = AST_PRIVACY_UNKNOWN;
1029 ast_copy_string(privcid,l,sizeof(privcid));
1031 if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */
1032 if (option_verbose > 2)
1033 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
1034 privdb_val = AST_PRIVACY_ALLOW;
1036 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
1037 if (option_verbose > 2)
1038 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
1041 if(privdb_val == AST_PRIVACY_DENY ) {
1042 ast_copy_string(status, "NOANSWER", sizeof(status));
1043 if (option_verbose > 2)
1044 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1045 res=0;
1046 goto out;
1048 else if(privdb_val == AST_PRIVACY_KILL ) {
1049 ast_copy_string(status, "DONTCALL", sizeof(status));
1050 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1051 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
1053 res = 0;
1054 goto out; /* Is this right? */
1056 else if(privdb_val == AST_PRIVACY_TORTURE ) {
1057 ast_copy_string(status, "TORTURE", sizeof(status));
1058 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1059 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
1061 res = 0;
1062 goto out; /* is this right??? */
1064 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
1065 /* Get the user's intro, store it in priv-callerintros/$CID,
1066 unless it is already there-- this should be done before the
1067 call is actually dialed */
1069 /* make sure the priv-callerintros dir actually exists */
1070 snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1071 if (mkdir(privintro, 0755) && errno != EEXIST) {
1072 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
1073 res = -1;
1074 goto out;
1077 snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
1078 if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
1079 /* the DELUX version of this code would allow this caller the
1080 option to hear and retape their previously recorded intro.
1083 else {
1084 int duration; /* for feedback from play_and_wait */
1085 /* the file doesn't exist yet. Let the caller submit his
1086 vocal intro for posterity */
1087 /* priv-recordintro script:
1089 "At the tone, please say your name:"
1092 ast_answer(chan);
1093 res = ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1094 /* don't think we'll need a lock removed, we took care of
1095 conflicts by naming the privintro file */
1096 if (res == -1) {
1097 /* Delete the file regardless since they hung up during recording */
1098 ast_filedelete(privintro, NULL);
1099 if( ast_fileexists(privintro,NULL,NULL ) > 0 )
1100 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
1101 else if (option_verbose > 2)
1102 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1103 goto out;
1105 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
1106 ast_waitstream(chan, "");
1111 if (continue_exec)
1112 *continue_exec = 0;
1114 /* If a channel group has been specified, get it for use when we create peer channels */
1115 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1116 outbound_group = ast_strdupa(outbound_group);
1117 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1118 } else {
1119 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1122 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1124 /* Create datastore for channel dial features for caller */
1125 if (!(ds_caller_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
1126 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1127 goto out;
1130 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
1131 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1132 goto out;
1135 ast_channel_lock(chan);
1136 caller_features->is_caller = 1;
1137 set_dial_features(&opts, caller_features);
1138 ds_caller_features->inheritance = -1;
1139 ds_caller_features->data = caller_features;
1140 ast_channel_datastore_add(chan, ds_caller_features);
1141 ast_channel_unlock(chan);
1143 /* loop through the list of dial destinations */
1144 rest = args.peers;
1145 while ((cur = strsep(&rest, "&")) ) {
1146 struct dial_localuser *tmp;
1147 /* Get a technology/[device:]number pair */
1148 char *number = cur;
1149 char *interface = ast_strdupa(number);
1150 char *tech = strsep(&number, "/");
1151 /* find if we already dialed this interface */
1152 struct ast_dialed_interface *di;
1153 struct ast_dial_features *callee_features;
1154 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1155 num_dialed++;
1156 if (!number) {
1157 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1158 goto out;
1160 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1161 goto out;
1162 if (opts.flags) {
1163 ast_copy_flags(tmp, &opts,
1164 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1165 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1166 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1167 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1168 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1169 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
1171 ast_copy_string(numsubst, number, sizeof(numsubst));
1172 /* Request the peer */
1174 ast_channel_lock(chan);
1175 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1176 ast_channel_unlock(chan);
1178 if (datastore)
1179 dialed_interfaces = datastore->data;
1180 else {
1181 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
1182 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1183 free(tmp);
1184 goto out;
1187 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1189 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1190 free(tmp);
1191 goto out;
1194 datastore->data = dialed_interfaces;
1195 AST_LIST_HEAD_INIT(dialed_interfaces);
1197 ast_channel_lock(chan);
1198 ast_channel_datastore_add(chan, datastore);
1199 ast_channel_unlock(chan);
1202 AST_LIST_LOCK(dialed_interfaces);
1203 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1204 if (!strcasecmp(di->interface, interface)) {
1205 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1206 di->interface);
1207 break;
1210 AST_LIST_UNLOCK(dialed_interfaces);
1212 if (di) {
1213 fulldial++;
1214 free(tmp);
1215 continue;
1218 /* It is always ok to dial a Local interface. We only keep track of
1219 * which "real" interfaces have been dialed. The Local channel will
1220 * inherit this list so that if it ends up dialing a real interface,
1221 * it won't call one that has already been called. */
1222 if (strcasecmp(tech, "Local")) {
1223 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1224 AST_LIST_UNLOCK(dialed_interfaces);
1225 free(tmp);
1226 goto out;
1228 strcpy(di->interface, interface);
1230 AST_LIST_LOCK(dialed_interfaces);
1231 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1232 AST_LIST_UNLOCK(dialed_interfaces);
1235 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
1236 if (!tmp->chan) {
1237 /* If we can't, just go on to the next call */
1238 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
1239 HANDLE_CAUSE(cause, chan);
1240 if (!rest) /* we are on the last destination */
1241 chan->hangupcause = cause;
1242 free(tmp);
1243 continue;
1246 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
1248 /* Setup outgoing SDP to match incoming one */
1249 ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
1251 /* Inherit specially named variables from parent channel */
1252 ast_channel_inherit_variables(chan, tmp->chan);
1254 tmp->chan->appl = "AppDial";
1255 tmp->chan->data = "(Outgoing Line)";
1256 tmp->chan->whentohangup = 0;
1258 if (tmp->chan->cid.cid_num)
1259 free(tmp->chan->cid.cid_num);
1260 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
1262 if (tmp->chan->cid.cid_name)
1263 free(tmp->chan->cid.cid_name);
1264 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
1266 if (tmp->chan->cid.cid_ani)
1267 free(tmp->chan->cid.cid_ani);
1268 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
1270 /* Copy language from incoming to outgoing */
1271 ast_string_field_set(tmp->chan, language, chan->language);
1272 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1273 tmp->chan->cdrflags = chan->cdrflags;
1274 if (ast_strlen_zero(tmp->chan->musicclass))
1275 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1276 /* XXX don't we free previous values ? */
1277 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
1278 /* Pass callingpres setting */
1279 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1280 /* Pass type of number */
1281 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1282 /* Pass type of tns */
1283 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1284 /* Presense of ADSI CPE on outgoing channel follows ours */
1285 tmp->chan->adsicpe = chan->adsicpe;
1286 /* Pass the transfer capability */
1287 tmp->chan->transfercapability = chan->transfercapability;
1289 /* If we have an outbound group, set this peer channel to it */
1290 if (outbound_group)
1291 ast_app_group_set_channel(tmp->chan, outbound_group);
1293 /* Inherit context and extension */
1294 if (!ast_strlen_zero(chan->macrocontext))
1295 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
1296 else
1297 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
1298 if (!ast_strlen_zero(chan->macroexten))
1299 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
1300 else
1301 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
1303 /* Save callee features */
1304 if (!(ds_callee_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
1305 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1306 ast_free(tmp);
1307 goto out;
1310 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
1311 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1312 ast_free(tmp);
1313 goto out;
1316 ast_channel_lock(tmp->chan);
1317 callee_features->is_caller = 0;
1318 set_dial_features(&opts, callee_features);
1319 ds_callee_features->inheritance = -1;
1320 ds_callee_features->data = callee_features;
1321 ast_channel_datastore_add(tmp->chan, ds_callee_features);
1322 ast_channel_unlock(tmp->chan);
1324 /* Place the call, but don't wait on the answer */
1325 res = ast_call(tmp->chan, numsubst, 0);
1327 /* Save the info in cdr's that we called them */
1328 if (chan->cdr)
1329 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1331 /* check the results of ast_call */
1332 if (res) {
1333 /* Again, keep going even if there's an error */
1334 if (option_debug)
1335 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1336 if (option_verbose > 2)
1337 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1338 ast_hangup(tmp->chan);
1339 tmp->chan = NULL;
1340 free(tmp);
1341 continue;
1342 } else {
1343 senddialevent(chan, tmp->chan);
1344 if (option_verbose > 2)
1345 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1346 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1347 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1349 /* Put them in the list of outgoing thingies... We're ready now.
1350 XXX If we're forcibly removed, these outgoing calls won't get
1351 hung up XXX */
1352 ast_set_flag(tmp, DIAL_STILLGOING);
1353 tmp->next = outgoing;
1354 outgoing = tmp;
1355 /* If this line is up, don't try anybody else */
1356 if (outgoing->chan->_state == AST_STATE_UP)
1357 break;
1360 if (ast_strlen_zero(args.timeout)) {
1361 to = -1;
1362 } else {
1363 to = atoi(args.timeout);
1364 if (to > 0)
1365 to *= 1000;
1366 else
1367 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1370 if (!outgoing) {
1371 strcpy(status, "CHANUNAVAIL");
1372 if(fulldial == num_dialed) {
1373 res = -1;
1374 goto out;
1376 } else {
1377 /* Our status will at least be NOANSWER */
1378 strcpy(status, "NOANSWER");
1379 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1380 moh = 1;
1381 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1382 char *original_moh = ast_strdupa(chan->musicclass);
1383 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1384 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1385 ast_string_field_set(chan, musicclass, original_moh);
1386 } else {
1387 ast_moh_start(chan, NULL, NULL);
1389 ast_indicate(chan, AST_CONTROL_PROGRESS);
1390 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1391 ast_indicate(chan, AST_CONTROL_RINGING);
1392 sentringing++;
1396 time(&start_time);
1397 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1399 /* The ast_channel_datastore_remove() function could fail here if the
1400 * datastore was moved to another channel during a masquerade. If this is
1401 * the case, don't free the datastore here because later, when the channel
1402 * to which the datastore was moved hangs up, it will attempt to free this
1403 * datastore again, causing a crash
1405 if (!ast_channel_datastore_remove(chan, datastore))
1406 ast_channel_datastore_free(datastore);
1407 if (!peer) {
1408 if (result) {
1409 res = result;
1410 } else if (to) { /* Musta gotten hung up */
1411 res = -1;
1412 } else { /* Nobody answered, next please? */
1413 res = 0;
1415 /* almost done, although the 'else' block is 400 lines */
1416 } else {
1417 const char *number;
1418 time_t end_time, answer_time = time(NULL);
1420 strcpy(status, "ANSWER");
1421 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1422 we will always return with -1 so that it is hung up properly after the
1423 conversation. */
1424 hanguptree(outgoing, peer);
1425 outgoing = NULL;
1426 /* If appropriate, log that we have a destination channel */
1427 if (chan->cdr)
1428 ast_cdr_setdestchan(chan->cdr, peer->name);
1429 if (peer->name)
1430 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1432 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1433 if (!number)
1434 number = numsubst;
1435 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1436 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1437 if (option_debug)
1438 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1439 ast_channel_sendurl( peer, args.url );
1441 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
1442 int res2;
1443 int loopcount = 0;
1445 /* Get the user's intro, store it in priv-callerintros/$CID,
1446 unless it is already there-- this should be done before the
1447 call is actually dialed */
1449 /* all ring indications and moh for the caller has been halted as soon as the
1450 target extension was picked up. We are going to have to kill some
1451 time and make the caller believe the peer hasn't picked up yet */
1453 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1454 char *original_moh = ast_strdupa(chan->musicclass);
1455 ast_indicate(chan, -1);
1456 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1457 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1458 ast_string_field_set(chan, musicclass, original_moh);
1459 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1460 ast_indicate(chan, AST_CONTROL_RINGING);
1461 sentringing++;
1464 /* Start autoservice on the other chan ?? */
1465 res2 = ast_autoservice_start(chan);
1466 /* Now Stream the File */
1467 for (loopcount = 0; loopcount < 3; loopcount++) {
1468 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1469 break;
1470 if (!res2) /* on timeout, play the message again */
1471 res2 = ast_play_and_wait(peer,"priv-callpending");
1472 if (!valid_priv_reply(&opts, res2))
1473 res2 = 0;
1474 /* priv-callpending script:
1475 "I have a caller waiting, who introduces themselves as:"
1477 if (!res2)
1478 res2 = ast_play_and_wait(peer,privintro);
1479 if (!valid_priv_reply(&opts, res2))
1480 res2 = 0;
1481 /* now get input from the called party, as to their choice */
1482 if( !res2 ) {
1483 /* XXX can we have both, or they are mutually exclusive ? */
1484 if( ast_test_flag(&opts, OPT_PRIVACY) )
1485 res2 = ast_play_and_wait(peer,"priv-callee-options");
1486 if( ast_test_flag(&opts, OPT_SCREENING) )
1487 res2 = ast_play_and_wait(peer,"screen-callee-options");
1489 /*! \page DialPrivacy Dial Privacy scripts
1490 \par priv-callee-options script:
1491 "Dial 1 if you wish this caller to reach you directly in the future,
1492 and immediately connect to their incoming call
1493 Dial 2 if you wish to send this caller to voicemail now and
1494 forevermore.
1495 Dial 3 to send this caller to the torture menus, now and forevermore.
1496 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1497 Dial 5 to allow this caller to come straight thru to you in the future,
1498 but right now, just this once, send them to voicemail."
1499 \par screen-callee-options script:
1500 "Dial 1 if you wish to immediately connect to the incoming call
1501 Dial 2 if you wish to send this caller to voicemail.
1502 Dial 3 to send this caller to the torture menus.
1503 Dial 4 to send this caller to a simple "go away" menu.
1505 if (valid_priv_reply(&opts, res2))
1506 break;
1507 /* invalid option */
1508 res2 = ast_play_and_wait(peer, "vm-sorry");
1511 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1512 ast_moh_stop(chan);
1513 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1514 ast_indicate(chan, -1);
1515 sentringing=0;
1517 ast_autoservice_stop(chan);
1519 switch (res2) {
1520 case '1':
1521 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1522 if (option_verbose > 2)
1523 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1524 opt_args[OPT_ARG_PRIVACY], privcid);
1525 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1527 break;
1528 case '2':
1529 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1530 if (option_verbose > 2)
1531 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1532 opt_args[OPT_ARG_PRIVACY], privcid);
1533 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1535 ast_copy_string(status, "NOANSWER", sizeof(status));
1536 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1537 res=0;
1538 goto out;
1539 case '3':
1540 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1541 if (option_verbose > 2)
1542 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1543 opt_args[OPT_ARG_PRIVACY], privcid);
1544 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1546 ast_copy_string(status, "TORTURE", sizeof(status));
1548 res = 0;
1549 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1550 goto out; /* Is this right? */
1551 case '4':
1552 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1553 if (option_verbose > 2)
1554 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1555 opt_args[OPT_ARG_PRIVACY], privcid);
1556 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1559 ast_copy_string(status, "DONTCALL", sizeof(status));
1560 res = 0;
1561 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1562 goto out; /* Is this right? */
1563 case '5':
1564 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1565 if (option_verbose > 2)
1566 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1567 opt_args[OPT_ARG_PRIVACY], privcid);
1568 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1569 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1570 res=0;
1571 goto out;
1572 } /* if not privacy, then 5 is the same as "default" case */
1573 default: /* bad input or -1 if failure to start autoservice */
1574 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1575 /* well, there seems basically two choices. Just patch the caller thru immediately,
1576 or,... put 'em thru to voicemail. */
1577 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1578 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1579 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1580 res=0;
1581 goto out;
1584 /* XXX once again, this path is only taken in the case '1', so it could be
1585 * moved there, although i am not really sure that this is correct - maybe
1586 * the check applies to other cases as well.
1588 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1589 just clog things up, and it's not useful information, not being tied to a CID */
1590 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1591 ast_filedelete(privintro, NULL);
1592 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1593 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1594 else if (option_verbose > 2)
1595 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1598 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1599 res = 0;
1600 } else {
1601 int digit = 0;
1602 /* Start autoservice on the other chan */
1603 res = ast_autoservice_start(chan);
1604 /* Now Stream the File */
1605 if (!res)
1606 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1607 if (!res) {
1608 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1610 /* Ok, done. stop autoservice */
1611 res = ast_autoservice_stop(chan);
1612 if (digit > 0 && !res)
1613 res = ast_senddigit(chan, digit);
1614 else
1615 res = digit;
1619 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1620 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1621 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1622 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1623 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1624 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1625 peer->priority = chan->priority + 2;
1626 ast_pbx_start(peer);
1627 hanguptree(outgoing, NULL);
1628 if (continue_exec)
1629 *continue_exec = 1;
1630 res = 0;
1631 goto done;
1634 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1635 struct ast_app *theapp;
1636 const char *macro_result;
1638 res = ast_autoservice_start(chan);
1639 if (res) {
1640 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1641 res = -1;
1644 theapp = pbx_findapp("Macro");
1646 if (theapp && !res) { /* XXX why check res here ? */
1647 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1648 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1649 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1650 res = 0;
1651 } else {
1652 ast_log(LOG_ERROR, "Could not find application Macro\n");
1653 res = -1;
1656 if (ast_autoservice_stop(chan) < 0) {
1657 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1658 res = -1;
1661 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1662 char *macro_transfer_dest;
1664 if (!strcasecmp(macro_result, "BUSY")) {
1665 ast_copy_string(status, macro_result, sizeof(status));
1666 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1667 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1668 ast_set_flag(peerflags, OPT_GO_ON);
1670 } else
1671 ast_set_flag(peerflags, OPT_GO_ON);
1672 res = -1;
1673 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1674 ast_copy_string(status, macro_result, sizeof(status));
1675 ast_set_flag(peerflags, OPT_GO_ON);
1676 res = -1;
1677 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1678 /* hangup peer and keep chan alive assuming the macro has changed
1679 the context / exten / priority or perhaps
1680 the next priority in the current exten is desired.
1682 ast_set_flag(peerflags, OPT_GO_ON);
1683 res = -1;
1684 } else if (!strcasecmp(macro_result, "ABORT")) {
1685 /* Hangup both ends unless the caller has the g flag */
1686 res = -1;
1687 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1688 res = -1;
1689 /* perform a transfer to a new extension */
1690 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1691 replace_macro_delimiter(macro_transfer_dest);
1692 if (!ast_parseable_goto(chan, macro_transfer_dest))
1693 ast_set_flag(peerflags, OPT_GO_ON);
1700 if (!res) {
1701 if (calldurationlimit > 0) {
1702 peer->whentohangup = time(NULL) + calldurationlimit;
1704 if (!ast_strlen_zero(dtmfcalled)) {
1705 if (option_verbose > 2)
1706 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1707 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1709 if (!ast_strlen_zero(dtmfcalling)) {
1710 if (option_verbose > 2)
1711 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1712 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1716 if (!res) {
1717 struct ast_bridge_config config;
1719 memset(&config,0,sizeof(struct ast_bridge_config));
1720 if (play_to_caller)
1721 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1722 if (play_to_callee)
1723 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1724 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1725 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1726 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1727 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1728 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1729 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1730 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1731 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1732 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1733 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1734 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1735 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1736 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1737 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1738 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1739 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1741 config.timelimit = timelimit;
1742 config.play_warning = play_warning;
1743 config.warning_freq = warning_freq;
1744 config.warning_sound = warning_sound;
1745 config.end_sound = end_sound;
1746 config.start_sound = start_sound;
1747 if (moh) {
1748 moh = 0;
1749 ast_moh_stop(chan);
1750 } else if (sentringing) {
1751 sentringing = 0;
1752 ast_indicate(chan, -1);
1754 /* Be sure no generators are left on it */
1755 ast_deactivate_generator(chan);
1756 /* Make sure channels are compatible */
1757 res = ast_channel_make_compatible(chan, peer);
1758 if (res < 0) {
1759 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1760 ast_hangup(peer);
1761 res = -1;
1762 goto done;
1764 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
1765 (!strncmp(peer->name,"Zap",3)))
1767 struct oprmode oprmode;
1769 oprmode.peer = peer;
1770 oprmode.mode = opermode;
1772 ast_channel_setoption(chan,
1773 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1775 res = ast_bridge_call(chan,peer,&config);
1776 time(&end_time);
1778 char toast[80];
1779 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1780 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1782 } else {
1783 time(&end_time);
1784 res = -1;
1787 char toast[80];
1788 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1789 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1792 if (res != AST_PBX_NO_HANGUP_PEER) {
1793 if (!chan->_softhangup)
1794 chan->hangupcause = peer->hangupcause;
1795 ast_hangup(peer);
1798 out:
1799 if (moh) {
1800 moh = 0;
1801 ast_moh_stop(chan);
1802 } else if (sentringing) {
1803 sentringing = 0;
1804 ast_indicate(chan, -1);
1806 ast_rtp_early_bridge(chan, NULL);
1807 hanguptree(outgoing, NULL);
1808 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1809 if (option_debug)
1810 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1812 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
1813 if (calldurationlimit)
1814 chan->whentohangup = 0;
1815 res = 0;
1818 done:
1819 ast_module_user_remove(u);
1820 return res;
1823 static int dial_exec(struct ast_channel *chan, void *data)
1825 struct ast_flags peerflags;
1827 memset(&peerflags, 0, sizeof(peerflags));
1829 return dial_exec_full(chan, data, &peerflags, NULL);
1832 static int retrydial_exec(struct ast_channel *chan, void *data)
1834 char *announce = NULL, *dialdata = NULL;
1835 const char *context = NULL;
1836 int sleep = 0, loops = 0, res = -1;
1837 struct ast_module_user *u;
1838 struct ast_flags peerflags;
1840 if (ast_strlen_zero(data)) {
1841 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1842 return -1;
1845 u = ast_module_user_add(chan);
1847 announce = ast_strdupa(data);
1849 memset(&peerflags, 0, sizeof(peerflags));
1851 if ((dialdata = strchr(announce, '|'))) {
1852 *dialdata++ = '\0';
1853 if (sscanf(dialdata, "%d", &sleep) == 1) {
1854 sleep *= 1000;
1855 } else {
1856 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1857 goto done;
1859 if ((dialdata = strchr(dialdata, '|'))) {
1860 *dialdata++ = '\0';
1861 if (sscanf(dialdata, "%d", &loops) != 1) {
1862 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1863 goto done;
1868 if ((dialdata = strchr(dialdata, '|'))) {
1869 *dialdata++ = '\0';
1870 } else {
1871 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1872 goto done;
1875 if (sleep < 1000)
1876 sleep = 10000;
1878 if (!loops)
1879 loops = -1; /* run forever */
1881 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1883 res = 0;
1884 while (loops) {
1885 int continue_exec;
1887 chan->data = "Retrying";
1888 if (ast_test_flag(chan, AST_FLAG_MOH))
1889 ast_moh_stop(chan);
1891 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1892 if (continue_exec)
1893 break;
1895 if (res == 0) {
1896 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1897 if (!ast_strlen_zero(announce)) {
1898 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1899 if(!(res = ast_streamfile(chan, announce, chan->language)))
1900 ast_waitstream(chan, AST_DIGIT_ANY);
1901 } else
1902 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1904 if (!res && sleep) {
1905 if (!ast_test_flag(chan, AST_FLAG_MOH))
1906 ast_moh_start(chan, NULL, NULL);
1907 res = ast_waitfordigit(chan, sleep);
1909 } else {
1910 if (!ast_strlen_zero(announce)) {
1911 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1912 if (!(res = ast_streamfile(chan, announce, chan->language)))
1913 res = ast_waitstream(chan, "");
1914 } else
1915 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1917 if (sleep) {
1918 if (!ast_test_flag(chan, AST_FLAG_MOH))
1919 ast_moh_start(chan, NULL, NULL);
1920 if (!res)
1921 res = ast_waitfordigit(chan, sleep);
1926 if (res < 0)
1927 break;
1928 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1929 if (onedigit_goto(chan, context, (char) res, 1)) {
1930 res = 0;
1931 break;
1934 loops--;
1936 if (loops == 0)
1937 res = 0;
1938 else if (res == 1)
1939 res = 0;
1941 if (ast_test_flag(chan, AST_FLAG_MOH))
1942 ast_moh_stop(chan);
1943 done:
1944 ast_module_user_remove(u);
1945 return res;
1948 static int unload_module(void)
1950 int res;
1952 res = ast_unregister_application(app);
1953 res |= ast_unregister_application(rapp);
1955 ast_module_user_hangup_all();
1957 return res;
1960 static int load_module(void)
1962 int res;
1964 res = ast_register_application(app, dial_exec, synopsis, descrip);
1965 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1967 return res;
1970 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");