Support for withheld or missing CID string
[asterisk-bristuff.git] / apps / app_dial.c
blob540a74e89de281bb91df5e2c1bcac2ecb64f9c63
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 if (peer->cdr) {
582 peer->cdr->answer = ast_tvnow();
583 peer->cdr->disposition = AST_CDR_ANSWERED;
585 ast_copy_flags(peerflags, o,
586 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
587 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
588 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
589 OPT_CALLEE_PARK | OPT_CALLER_PARK |
590 DIAL_NOFORWARDHTML);
591 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
592 ast_copy_string(c->exten, "", sizeof(c->exten));
593 /* Setup RTP early bridge if appropriate */
594 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
595 ast_rtp_early_bridge(in, peer);
597 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
598 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
599 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
600 break;
601 case AST_CONTROL_BUSY:
602 if (option_verbose > 2)
603 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
604 in->hangupcause = c->hangupcause;
605 ast_hangup(c);
606 c = o->chan = NULL;
607 ast_clear_flag(o, DIAL_STILLGOING);
608 HANDLE_CAUSE(AST_CAUSE_BUSY, in);
609 break;
610 case AST_CONTROL_CONGESTION:
611 if (option_verbose > 2)
612 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
613 in->hangupcause = c->hangupcause;
614 ast_hangup(c);
615 c = o->chan = NULL;
616 ast_clear_flag(o, DIAL_STILLGOING);
617 HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
618 break;
619 case AST_CONTROL_RINGING:
620 if (option_verbose > 2)
621 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
622 /* Setup early media if appropriate */
623 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
624 ast_rtp_early_bridge(in, c);
625 if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
626 ast_indicate(in, AST_CONTROL_RINGING);
627 (*sentringing)++;
629 break;
630 case AST_CONTROL_PROGRESS:
631 if (option_verbose > 2)
632 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
633 /* Setup early media if appropriate */
634 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
635 ast_rtp_early_bridge(in, c);
636 if (!ast_test_flag(outgoing, OPT_RINGBACK))
637 ast_indicate(in, AST_CONTROL_PROGRESS);
638 break;
639 case AST_CONTROL_VIDUPDATE:
640 if (option_verbose > 2)
641 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
642 ast_indicate(in, AST_CONTROL_VIDUPDATE);
643 break;
644 case AST_CONTROL_SRCUPDATE:
645 if (option_verbose > 2)
646 ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
647 ast_indicate(in, AST_CONTROL_SRCUPDATE);
648 break;
649 case AST_CONTROL_PROCEEDING:
650 if (option_verbose > 2)
651 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
652 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
653 ast_rtp_early_bridge(in, c);
654 if (!ast_test_flag(outgoing, OPT_RINGBACK))
655 ast_indicate(in, AST_CONTROL_PROCEEDING);
656 break;
657 case AST_CONTROL_HOLD:
658 if (option_verbose > 2)
659 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
660 ast_indicate(in, AST_CONTROL_HOLD);
661 break;
662 case AST_CONTROL_UNHOLD:
663 if (option_verbose > 2)
664 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
665 ast_indicate(in, AST_CONTROL_UNHOLD);
666 break;
667 case AST_CONTROL_OFFHOOK:
668 case AST_CONTROL_FLASH:
669 /* Ignore going off hook and flash */
670 break;
671 case -1:
672 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
673 if (option_verbose > 2)
674 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
675 ast_indicate(in, -1);
676 (*sentringing) = 0;
678 break;
679 default:
680 if (option_debug)
681 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
683 } else if (single) {
684 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
685 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
686 if (ast_write(in, f))
687 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
688 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
689 if (ast_write(in, f))
690 ast_log(LOG_WARNING, "Unable to forward image\n");
691 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
692 if (ast_write(in, f))
693 ast_log(LOG_WARNING, "Unable to send text\n");
694 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
695 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
696 ast_log(LOG_WARNING, "Unable to send URL\n");
699 ast_frfree(f);
700 } /* end for */
701 if (winner == in) {
702 struct ast_frame *f = ast_read(in);
703 #if 0
704 if (f && (f->frametype != AST_FRAME_VOICE))
705 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
706 else if (!f || (f->frametype != AST_FRAME_VOICE))
707 printf("Hangup received on %s\n", in->name);
708 #endif
709 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
710 /* Got hung up */
711 *to = -1;
712 ast_cdr_noanswer(in->cdr);
713 strcpy(status, "CANCEL");
714 if (f)
715 ast_frfree(f);
716 return NULL;
719 if (f && (f->frametype == AST_FRAME_DTMF)) {
720 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
721 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
722 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
723 if (option_verbose > 2)
724 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
725 *to=0;
726 ast_cdr_noanswer(in->cdr);
727 *result = f->subclass;
728 strcpy(status, "CANCEL");
729 ast_frfree(f);
730 return NULL;
734 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
735 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
736 if (option_verbose > 2)
737 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
738 *to=0;
739 ast_cdr_noanswer(in->cdr);
740 strcpy(status, "CANCEL");
741 ast_frfree(f);
742 return NULL;
746 /* Forward HTML stuff */
747 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
748 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
749 ast_log(LOG_WARNING, "Unable to send URL\n");
752 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
753 if (ast_write(outgoing->chan, f))
754 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
756 if (single && (f->frametype == AST_FRAME_CONTROL) &&
757 ((f->subclass == AST_CONTROL_HOLD) ||
758 (f->subclass == AST_CONTROL_UNHOLD) ||
759 (f->subclass == AST_CONTROL_VIDUPDATE) ||
760 (f->subclass == AST_CONTROL_SRCUPDATE))) {
761 if (option_verbose > 2)
762 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
763 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
765 ast_frfree(f);
767 if (!*to && (option_verbose > 2))
768 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
769 if (!*to || ast_check_hangup(in)) {
770 ast_cdr_noanswer(in->cdr);
775 return peer;
778 static void replace_macro_delimiter(char *s)
780 for (; *s; s++)
781 if (*s == '^')
782 *s = '|';
786 /* returns true if there is a valid privacy reply */
787 static int valid_priv_reply(struct ast_flags *opts, int res)
789 if (res < '1')
790 return 0;
791 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
792 return 1;
793 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
794 return 1;
795 return 0;
798 static void set_dial_features(struct ast_flags *opts, struct ast_dial_features *features)
800 struct ast_flags perm_opts = {.flags = 0};
802 ast_copy_flags(&perm_opts, opts,
803 OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_HANGUP |
804 OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_HANGUP);
806 memset(features->options, 0, sizeof(features->options));
808 ast_app_options2str(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
809 if (ast_test_flag(&perm_opts, OPT_CALLEE_TRANSFER))
810 ast_set_flag(&(features->features_callee), AST_FEATURE_REDIRECT);
811 if (ast_test_flag(&perm_opts, OPT_CALLER_TRANSFER))
812 ast_set_flag(&(features->features_caller), AST_FEATURE_REDIRECT);
813 if (ast_test_flag(&perm_opts, OPT_CALLEE_HANGUP))
814 ast_set_flag(&(features->features_callee), AST_FEATURE_DISCONNECT);
815 if (ast_test_flag(&perm_opts, OPT_CALLER_HANGUP))
816 ast_set_flag(&(features->features_caller), AST_FEATURE_DISCONNECT);
817 if (ast_test_flag(&perm_opts, OPT_CALLEE_MONITOR))
818 ast_set_flag(&(features->features_callee), AST_FEATURE_AUTOMON);
819 if (ast_test_flag(&perm_opts, OPT_CALLER_MONITOR))
820 ast_set_flag(&(features->features_caller), AST_FEATURE_AUTOMON);
821 if (ast_test_flag(&perm_opts, OPT_CALLEE_PARK))
822 ast_set_flag(&(features->features_callee), AST_FEATURE_PARKCALL);
823 if (ast_test_flag(&perm_opts, OPT_CALLER_PARK))
824 ast_set_flag(&(features->features_caller), AST_FEATURE_PARKCALL);
827 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
829 int res = -1;
830 struct ast_module_user *u;
831 char *rest, *cur;
832 struct dial_localuser *outgoing = NULL;
833 struct ast_channel *peer;
834 int to;
835 int numbusy = 0;
836 int numcongestion = 0;
837 int numnochan = 0;
838 int cause;
839 char numsubst[256];
840 char cidname[AST_MAX_EXTENSION] = "";
841 int privdb_val = 0;
842 unsigned int calldurationlimit = 0;
843 long timelimit = 0;
844 long play_warning = 0;
845 long warning_freq = 0;
846 const char *warning_sound = NULL;
847 const char *end_sound = NULL;
848 const char *start_sound = NULL;
849 char *dtmfcalled = NULL, *dtmfcalling = NULL;
850 char status[256] = "INVALIDARGS";
851 int play_to_caller = 0, play_to_callee = 0;
852 int sentringing = 0, moh = 0;
853 const char *outbound_group = NULL;
854 int result = 0;
855 time_t start_time;
856 char privintro[1024];
857 char privcid[256];
858 char *parse;
859 int opermode = 0;
860 AST_DECLARE_APP_ARGS(args,
861 AST_APP_ARG(peers);
862 AST_APP_ARG(timeout);
863 AST_APP_ARG(options);
864 AST_APP_ARG(url);
866 struct ast_flags opts = { 0, };
867 char *opt_args[OPT_ARG_ARRAY_SIZE];
868 struct ast_datastore *datastore = NULL;
869 struct ast_datastore *ds_caller_features = NULL;
870 struct ast_datastore *ds_callee_features = NULL;
871 struct ast_dial_features *caller_features;
872 int fulldial = 0, num_dialed = 0;
874 if (ast_strlen_zero(data)) {
875 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
876 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
877 return -1;
880 u = ast_module_user_add(chan);
882 parse = ast_strdupa(data);
884 AST_STANDARD_APP_ARGS(args, parse);
886 if (!ast_strlen_zero(args.options) &&
887 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
888 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
889 goto done;
892 if (ast_strlen_zero(args.peers)) {
893 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
894 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
895 goto done;
898 if (ast_test_flag(&opts, OPT_OPERMODE)) {
899 if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
900 opermode = 1;
901 else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
902 if (option_verbose > 2)
903 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
906 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
907 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
908 if (!calldurationlimit) {
909 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
910 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
911 goto done;
913 if (option_verbose > 2)
914 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
917 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
918 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
919 dtmfcalled = strsep(&dtmfcalling, ":");
922 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
923 char *limit_str, *warning_str, *warnfreq_str;
924 const char *var;
926 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
927 limit_str = strsep(&warnfreq_str, ":");
928 warning_str = strsep(&warnfreq_str, ":");
930 timelimit = atol(limit_str);
931 if (warning_str)
932 play_warning = atol(warning_str);
933 if (warnfreq_str)
934 warning_freq = atol(warnfreq_str);
936 if (!timelimit) {
937 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
938 goto done;
939 } else if (play_warning > timelimit) {
940 /* If the first warning is requested _after_ the entire call would end,
941 and no warning frequency is requested, then turn off the warning. If
942 a warning frequency is requested, reduce the 'first warning' time by
943 that frequency until it falls within the call's total time limit.
946 if (!warning_freq) {
947 play_warning = 0;
948 } else {
949 /* XXX fix this!! */
950 while (play_warning > timelimit)
951 play_warning -= warning_freq;
952 if (play_warning < 1)
953 play_warning = warning_freq = 0;
957 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
958 play_to_caller = var ? ast_true(var) : 1;
960 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
961 play_to_callee = var ? ast_true(var) : 0;
963 if (!play_to_caller && !play_to_callee)
964 play_to_caller = 1;
966 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
967 warning_sound = S_OR(var, "timeleft");
969 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
970 end_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
972 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
973 start_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
975 /* undo effect of S(x) in case they are both used */
976 calldurationlimit = 0;
977 /* more efficient to do it like S(x) does since no advanced opts */
978 if (!play_warning && !start_sound && !end_sound && timelimit) {
979 calldurationlimit = timelimit / 1000;
980 if (option_verbose > 2)
981 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
982 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
983 } else if (option_verbose > 2) {
984 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
985 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
986 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
987 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
988 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
989 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
990 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
991 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
992 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
996 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
997 ast_cdr_reset(chan->cdr, NULL);
998 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
999 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1000 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1001 char callerid[60];
1002 char *l = chan->cid.cid_num; /* XXX watch out, we are overwriting it */
1003 if (!ast_strlen_zero(l)) {
1004 ast_shrink_phone_number(l);
1005 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1006 if (option_verbose > 2)
1007 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
1008 opt_args[OPT_ARG_PRIVACY], l);
1009 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1011 else {
1012 if (option_verbose > 2)
1013 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
1014 privdb_val = AST_PRIVACY_UNKNOWN;
1016 } else {
1017 char *tnam, *tn2;
1019 tnam = ast_strdupa(chan->name);
1020 /* clean the channel name so slashes don't try to end up in disk file name */
1021 for(tn2 = tnam; *tn2; tn2++) {
1022 if( *tn2=='/')
1023 *tn2 = '='; /* any other chars to be afraid of? */
1025 if (option_verbose > 2)
1026 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
1028 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1029 l = callerid;
1030 privdb_val = AST_PRIVACY_UNKNOWN;
1033 ast_copy_string(privcid,l,sizeof(privcid));
1035 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 */
1036 if (option_verbose > 2)
1037 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
1038 privdb_val = AST_PRIVACY_ALLOW;
1040 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
1041 if (option_verbose > 2)
1042 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
1045 if(privdb_val == AST_PRIVACY_DENY ) {
1046 ast_copy_string(status, "NOANSWER", sizeof(status));
1047 if (option_verbose > 2)
1048 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1049 res=0;
1050 goto out;
1052 else if(privdb_val == AST_PRIVACY_KILL ) {
1053 ast_copy_string(status, "DONTCALL", sizeof(status));
1054 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1055 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
1057 res = 0;
1058 goto out; /* Is this right? */
1060 else if(privdb_val == AST_PRIVACY_TORTURE ) {
1061 ast_copy_string(status, "TORTURE", sizeof(status));
1062 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1063 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
1065 res = 0;
1066 goto out; /* is this right??? */
1068 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
1069 /* Get the user's intro, store it in priv-callerintros/$CID,
1070 unless it is already there-- this should be done before the
1071 call is actually dialed */
1073 /* make sure the priv-callerintros dir actually exists */
1074 snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1075 if (mkdir(privintro, 0755) && errno != EEXIST) {
1076 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
1077 res = -1;
1078 goto out;
1081 snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
1082 if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
1083 /* the DELUX version of this code would allow this caller the
1084 option to hear and retape their previously recorded intro.
1087 else {
1088 int duration; /* for feedback from play_and_wait */
1089 /* the file doesn't exist yet. Let the caller submit his
1090 vocal intro for posterity */
1091 /* priv-recordintro script:
1093 "At the tone, please say your name:"
1096 ast_answer(chan);
1097 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 */
1098 /* don't think we'll need a lock removed, we took care of
1099 conflicts by naming the privintro file */
1100 if (res == -1) {
1101 /* Delete the file regardless since they hung up during recording */
1102 ast_filedelete(privintro, NULL);
1103 if( ast_fileexists(privintro,NULL,NULL ) > 0 )
1104 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
1105 else if (option_verbose > 2)
1106 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1107 goto out;
1109 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
1110 ast_waitstream(chan, "");
1115 if (continue_exec)
1116 *continue_exec = 0;
1118 /* If a channel group has been specified, get it for use when we create peer channels */
1119 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1120 outbound_group = ast_strdupa(outbound_group);
1121 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1122 } else {
1123 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1126 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1128 /* Create datastore for channel dial features for caller */
1129 if (!(ds_caller_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
1130 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1131 goto out;
1134 if (!(caller_features = ast_calloc(1, sizeof(*caller_features)))) {
1135 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1136 goto out;
1139 ast_channel_lock(chan);
1140 caller_features->is_caller = 1;
1141 set_dial_features(&opts, caller_features);
1142 ds_caller_features->inheritance = -1;
1143 ds_caller_features->data = caller_features;
1144 ast_channel_datastore_add(chan, ds_caller_features);
1145 ast_channel_unlock(chan);
1147 /* loop through the list of dial destinations */
1148 rest = args.peers;
1149 while ((cur = strsep(&rest, "&")) ) {
1150 struct dial_localuser *tmp;
1151 /* Get a technology/[device:]number pair */
1152 char *number = cur;
1153 char *interface = ast_strdupa(number);
1154 char *tech = strsep(&number, "/");
1155 /* find if we already dialed this interface */
1156 struct ast_dialed_interface *di;
1157 struct ast_dial_features *callee_features;
1158 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1159 num_dialed++;
1160 if (!number) {
1161 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1162 goto out;
1164 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1165 goto out;
1166 if (opts.flags) {
1167 ast_copy_flags(tmp, &opts,
1168 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1169 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1170 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1171 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1172 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1173 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
1175 ast_copy_string(numsubst, number, sizeof(numsubst));
1176 /* Request the peer */
1178 ast_channel_lock(chan);
1179 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1180 ast_channel_unlock(chan);
1182 if (datastore)
1183 dialed_interfaces = datastore->data;
1184 else {
1185 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
1186 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1187 free(tmp);
1188 goto out;
1191 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1193 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1194 free(tmp);
1195 goto out;
1198 datastore->data = dialed_interfaces;
1199 AST_LIST_HEAD_INIT(dialed_interfaces);
1201 ast_channel_lock(chan);
1202 ast_channel_datastore_add(chan, datastore);
1203 ast_channel_unlock(chan);
1206 AST_LIST_LOCK(dialed_interfaces);
1207 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1208 if (!strcasecmp(di->interface, interface)) {
1209 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1210 di->interface);
1211 break;
1214 AST_LIST_UNLOCK(dialed_interfaces);
1216 if (di) {
1217 fulldial++;
1218 free(tmp);
1219 continue;
1222 /* It is always ok to dial a Local interface. We only keep track of
1223 * which "real" interfaces have been dialed. The Local channel will
1224 * inherit this list so that if it ends up dialing a real interface,
1225 * it won't call one that has already been called. */
1226 if (strcasecmp(tech, "Local")) {
1227 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1228 AST_LIST_UNLOCK(dialed_interfaces);
1229 free(tmp);
1230 goto out;
1232 strcpy(di->interface, interface);
1234 AST_LIST_LOCK(dialed_interfaces);
1235 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1236 AST_LIST_UNLOCK(dialed_interfaces);
1239 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
1240 if (!tmp->chan) {
1241 /* If we can't, just go on to the next call */
1242 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
1243 HANDLE_CAUSE(cause, chan);
1244 if (!rest) /* we are on the last destination */
1245 chan->hangupcause = cause;
1246 free(tmp);
1247 continue;
1250 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
1252 /* Setup outgoing SDP to match incoming one */
1253 ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
1255 /* Inherit specially named variables from parent channel */
1256 ast_channel_inherit_variables(chan, tmp->chan);
1258 tmp->chan->appl = "AppDial";
1259 tmp->chan->data = "(Outgoing Line)";
1260 tmp->chan->whentohangup = 0;
1262 if (tmp->chan->cid.cid_num)
1263 free(tmp->chan->cid.cid_num);
1264 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
1266 if (tmp->chan->cid.cid_name)
1267 free(tmp->chan->cid.cid_name);
1268 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
1270 if (tmp->chan->cid.cid_ani)
1271 free(tmp->chan->cid.cid_ani);
1272 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
1274 /* Copy language from incoming to outgoing */
1275 ast_string_field_set(tmp->chan, language, chan->language);
1276 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1277 tmp->chan->cdrflags = chan->cdrflags;
1278 if (ast_strlen_zero(tmp->chan->musicclass))
1279 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1280 /* XXX don't we free previous values ? */
1281 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
1282 /* Pass callingpres setting */
1283 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1284 /* Pass type of number */
1285 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1286 /* Pass type of tns */
1287 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1288 /* Presense of ADSI CPE on outgoing channel follows ours */
1289 tmp->chan->adsicpe = chan->adsicpe;
1290 /* Pass the transfer capability */
1291 tmp->chan->transfercapability = chan->transfercapability;
1293 /* If we have an outbound group, set this peer channel to it */
1294 if (outbound_group)
1295 ast_app_group_set_channel(tmp->chan, outbound_group);
1297 /* Inherit context and extension */
1298 if (!ast_strlen_zero(chan->macrocontext))
1299 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
1300 else
1301 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
1302 if (!ast_strlen_zero(chan->macroexten))
1303 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
1304 else
1305 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
1307 /* Save callee features */
1308 if (!(ds_callee_features = ast_channel_datastore_alloc(&dial_features_info, NULL))) {
1309 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1310 ast_free(tmp);
1311 goto out;
1314 if (!(callee_features = ast_calloc(1, sizeof(*callee_features)))) {
1315 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1316 ast_free(tmp);
1317 goto out;
1320 ast_channel_lock(tmp->chan);
1321 callee_features->is_caller = 0;
1322 set_dial_features(&opts, callee_features);
1323 ds_callee_features->inheritance = -1;
1324 ds_callee_features->data = callee_features;
1325 ast_channel_datastore_add(tmp->chan, ds_callee_features);
1326 ast_channel_unlock(tmp->chan);
1328 /* Place the call, but don't wait on the answer */
1329 res = ast_call(tmp->chan, numsubst, 0);
1331 /* Save the info in cdr's that we called them */
1332 if (chan->cdr)
1333 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1335 /* check the results of ast_call */
1336 if (res) {
1337 /* Again, keep going even if there's an error */
1338 if (option_debug)
1339 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1340 if (option_verbose > 2)
1341 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1342 ast_hangup(tmp->chan);
1343 tmp->chan = NULL;
1344 free(tmp);
1345 continue;
1346 } else {
1347 senddialevent(chan, tmp->chan);
1348 if (option_verbose > 2)
1349 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1350 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1351 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1353 /* Put them in the list of outgoing thingies... We're ready now.
1354 XXX If we're forcibly removed, these outgoing calls won't get
1355 hung up XXX */
1356 ast_set_flag(tmp, DIAL_STILLGOING);
1357 tmp->next = outgoing;
1358 outgoing = tmp;
1359 /* If this line is up, don't try anybody else */
1360 if (outgoing->chan->_state == AST_STATE_UP)
1361 break;
1364 if (ast_strlen_zero(args.timeout)) {
1365 to = -1;
1366 } else {
1367 to = atoi(args.timeout);
1368 if (to > 0)
1369 to *= 1000;
1370 else
1371 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1374 if (!outgoing) {
1375 strcpy(status, "CHANUNAVAIL");
1376 if(fulldial == num_dialed) {
1377 res = -1;
1378 goto out;
1380 } else {
1381 /* Our status will at least be NOANSWER */
1382 strcpy(status, "NOANSWER");
1383 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1384 moh = 1;
1385 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1386 char *original_moh = ast_strdupa(chan->musicclass);
1387 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1388 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1389 ast_string_field_set(chan, musicclass, original_moh);
1390 } else {
1391 ast_moh_start(chan, NULL, NULL);
1393 ast_indicate(chan, AST_CONTROL_PROGRESS);
1394 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1395 ast_indicate(chan, AST_CONTROL_RINGING);
1396 sentringing++;
1400 time(&start_time);
1401 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1403 /* The ast_channel_datastore_remove() function could fail here if the
1404 * datastore was moved to another channel during a masquerade. If this is
1405 * the case, don't free the datastore here because later, when the channel
1406 * to which the datastore was moved hangs up, it will attempt to free this
1407 * datastore again, causing a crash
1409 if (!ast_channel_datastore_remove(chan, datastore))
1410 ast_channel_datastore_free(datastore);
1411 if (!peer) {
1412 if (result) {
1413 res = result;
1414 } else if (to) { /* Musta gotten hung up */
1415 res = -1;
1416 } else { /* Nobody answered, next please? */
1417 res = 0;
1419 /* almost done, although the 'else' block is 400 lines */
1420 } else {
1421 const char *number;
1422 time_t end_time, answer_time = time(NULL);
1424 strcpy(status, "ANSWER");
1425 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1426 we will always return with -1 so that it is hung up properly after the
1427 conversation. */
1428 hanguptree(outgoing, peer);
1429 outgoing = NULL;
1430 /* If appropriate, log that we have a destination channel */
1431 if (chan->cdr)
1432 ast_cdr_setdestchan(chan->cdr, peer->name);
1433 if (peer->name)
1434 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1436 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1437 if (!number)
1438 number = numsubst;
1439 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1440 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1441 if (option_debug)
1442 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1443 ast_channel_sendurl( peer, args.url );
1445 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
1446 int res2;
1447 int loopcount = 0;
1449 /* Get the user's intro, store it in priv-callerintros/$CID,
1450 unless it is already there-- this should be done before the
1451 call is actually dialed */
1453 /* all ring indications and moh for the caller has been halted as soon as the
1454 target extension was picked up. We are going to have to kill some
1455 time and make the caller believe the peer hasn't picked up yet */
1457 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1458 char *original_moh = ast_strdupa(chan->musicclass);
1459 ast_indicate(chan, -1);
1460 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1461 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1462 ast_string_field_set(chan, musicclass, original_moh);
1463 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1464 ast_indicate(chan, AST_CONTROL_RINGING);
1465 sentringing++;
1468 /* Start autoservice on the other chan ?? */
1469 res2 = ast_autoservice_start(chan);
1470 /* Now Stream the File */
1471 for (loopcount = 0; loopcount < 3; loopcount++) {
1472 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1473 break;
1474 if (!res2) /* on timeout, play the message again */
1475 res2 = ast_play_and_wait(peer,"priv-callpending");
1476 if (!valid_priv_reply(&opts, res2))
1477 res2 = 0;
1478 /* priv-callpending script:
1479 "I have a caller waiting, who introduces themselves as:"
1481 if (!res2)
1482 res2 = ast_play_and_wait(peer,privintro);
1483 if (!valid_priv_reply(&opts, res2))
1484 res2 = 0;
1485 /* now get input from the called party, as to their choice */
1486 if( !res2 ) {
1487 /* XXX can we have both, or they are mutually exclusive ? */
1488 if( ast_test_flag(&opts, OPT_PRIVACY) )
1489 res2 = ast_play_and_wait(peer,"priv-callee-options");
1490 if( ast_test_flag(&opts, OPT_SCREENING) )
1491 res2 = ast_play_and_wait(peer,"screen-callee-options");
1493 /*! \page DialPrivacy Dial Privacy scripts
1494 \par priv-callee-options script:
1495 "Dial 1 if you wish this caller to reach you directly in the future,
1496 and immediately connect to their incoming call
1497 Dial 2 if you wish to send this caller to voicemail now and
1498 forevermore.
1499 Dial 3 to send this caller to the torture menus, now and forevermore.
1500 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1501 Dial 5 to allow this caller to come straight thru to you in the future,
1502 but right now, just this once, send them to voicemail."
1503 \par screen-callee-options script:
1504 "Dial 1 if you wish to immediately connect to the incoming call
1505 Dial 2 if you wish to send this caller to voicemail.
1506 Dial 3 to send this caller to the torture menus.
1507 Dial 4 to send this caller to a simple "go away" menu.
1509 if (valid_priv_reply(&opts, res2))
1510 break;
1511 /* invalid option */
1512 res2 = ast_play_and_wait(peer, "vm-sorry");
1515 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1516 ast_moh_stop(chan);
1517 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1518 ast_indicate(chan, -1);
1519 sentringing=0;
1521 ast_autoservice_stop(chan);
1523 switch (res2) {
1524 case '1':
1525 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1526 if (option_verbose > 2)
1527 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1528 opt_args[OPT_ARG_PRIVACY], privcid);
1529 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1531 break;
1532 case '2':
1533 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1534 if (option_verbose > 2)
1535 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1536 opt_args[OPT_ARG_PRIVACY], privcid);
1537 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1539 ast_copy_string(status, "NOANSWER", sizeof(status));
1540 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1541 res=0;
1542 goto out;
1543 case '3':
1544 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1545 if (option_verbose > 2)
1546 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1547 opt_args[OPT_ARG_PRIVACY], privcid);
1548 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1550 ast_copy_string(status, "TORTURE", sizeof(status));
1552 res = 0;
1553 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1554 goto out; /* Is this right? */
1555 case '4':
1556 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1557 if (option_verbose > 2)
1558 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1559 opt_args[OPT_ARG_PRIVACY], privcid);
1560 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1563 ast_copy_string(status, "DONTCALL", sizeof(status));
1564 res = 0;
1565 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1566 goto out; /* Is this right? */
1567 case '5':
1568 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1569 if (option_verbose > 2)
1570 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1571 opt_args[OPT_ARG_PRIVACY], privcid);
1572 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1573 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1574 res=0;
1575 goto out;
1576 } /* if not privacy, then 5 is the same as "default" case */
1577 default: /* bad input or -1 if failure to start autoservice */
1578 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1579 /* well, there seems basically two choices. Just patch the caller thru immediately,
1580 or,... put 'em thru to voicemail. */
1581 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1582 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1583 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1584 res=0;
1585 goto out;
1588 /* XXX once again, this path is only taken in the case '1', so it could be
1589 * moved there, although i am not really sure that this is correct - maybe
1590 * the check applies to other cases as well.
1592 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1593 just clog things up, and it's not useful information, not being tied to a CID */
1594 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1595 ast_filedelete(privintro, NULL);
1596 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1597 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1598 else if (option_verbose > 2)
1599 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1602 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1603 res = 0;
1604 } else {
1605 int digit = 0;
1606 /* Start autoservice on the other chan */
1607 res = ast_autoservice_start(chan);
1608 /* Now Stream the File */
1609 if (!res)
1610 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1611 if (!res) {
1612 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1614 /* Ok, done. stop autoservice */
1615 res = ast_autoservice_stop(chan);
1616 if (digit > 0 && !res)
1617 res = ast_senddigit(chan, digit);
1618 else
1619 res = digit;
1623 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1624 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1625 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1626 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1627 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1628 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1629 peer->priority = chan->priority + 2;
1630 ast_pbx_start(peer);
1631 hanguptree(outgoing, NULL);
1632 if (continue_exec)
1633 *continue_exec = 1;
1634 res = 0;
1635 goto done;
1638 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1639 struct ast_app *theapp;
1640 const char *macro_result;
1642 res = ast_autoservice_start(chan);
1643 if (res) {
1644 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1645 res = -1;
1648 theapp = pbx_findapp("Macro");
1650 if (theapp && !res) { /* XXX why check res here ? */
1651 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1652 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1653 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1654 res = 0;
1655 } else {
1656 ast_log(LOG_ERROR, "Could not find application Macro\n");
1657 res = -1;
1660 if (ast_autoservice_stop(chan) < 0) {
1661 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1662 res = -1;
1665 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1666 char *macro_transfer_dest;
1668 if (!strcasecmp(macro_result, "BUSY")) {
1669 ast_copy_string(status, macro_result, sizeof(status));
1670 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1671 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1672 ast_set_flag(peerflags, OPT_GO_ON);
1674 } else
1675 ast_set_flag(peerflags, OPT_GO_ON);
1676 res = -1;
1677 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1678 ast_copy_string(status, macro_result, sizeof(status));
1679 ast_set_flag(peerflags, OPT_GO_ON);
1680 res = -1;
1681 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1682 /* hangup peer and keep chan alive assuming the macro has changed
1683 the context / exten / priority or perhaps
1684 the next priority in the current exten is desired.
1686 ast_set_flag(peerflags, OPT_GO_ON);
1687 res = -1;
1688 } else if (!strcasecmp(macro_result, "ABORT")) {
1689 /* Hangup both ends unless the caller has the g flag */
1690 res = -1;
1691 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1692 res = -1;
1693 /* perform a transfer to a new extension */
1694 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1695 replace_macro_delimiter(macro_transfer_dest);
1696 if (!ast_parseable_goto(chan, macro_transfer_dest))
1697 ast_set_flag(peerflags, OPT_GO_ON);
1704 if (!res) {
1705 if (calldurationlimit > 0) {
1706 peer->whentohangup = time(NULL) + calldurationlimit;
1708 if (!ast_strlen_zero(dtmfcalled)) {
1709 if (option_verbose > 2)
1710 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1711 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1713 if (!ast_strlen_zero(dtmfcalling)) {
1714 if (option_verbose > 2)
1715 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1716 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1720 if (!res) {
1721 struct ast_bridge_config config;
1723 memset(&config,0,sizeof(struct ast_bridge_config));
1724 if (play_to_caller)
1725 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1726 if (play_to_callee)
1727 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1728 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1729 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1730 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1731 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1732 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1733 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1734 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1735 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1736 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1737 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1738 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1739 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1740 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1741 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1742 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1743 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1745 config.timelimit = timelimit;
1746 config.play_warning = play_warning;
1747 config.warning_freq = warning_freq;
1748 config.warning_sound = warning_sound;
1749 config.end_sound = end_sound;
1750 config.start_sound = start_sound;
1751 if (moh) {
1752 moh = 0;
1753 ast_moh_stop(chan);
1754 } else if (sentringing) {
1755 sentringing = 0;
1756 ast_indicate(chan, -1);
1758 /* Be sure no generators are left on it */
1759 ast_deactivate_generator(chan);
1760 /* Make sure channels are compatible */
1761 res = ast_channel_make_compatible(chan, peer);
1762 if (res < 0) {
1763 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1764 ast_hangup(peer);
1765 res = -1;
1766 goto done;
1768 if (opermode &&
1769 (((!strncasecmp(chan->name,"Zap",3)) && (!strncasecmp(peer->name,"Zap",3))) ||
1770 ((!strncasecmp(chan->name,"Dahdi",5)) && (!strncasecmp(peer->name,"Dahdi",5)))))
1772 struct oprmode oprmode;
1774 oprmode.peer = peer;
1775 oprmode.mode = opermode;
1777 ast_channel_setoption(chan,
1778 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1780 res = ast_bridge_call(chan,peer,&config);
1781 time(&end_time);
1783 char toast[80];
1784 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1785 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1787 } else {
1788 time(&end_time);
1789 res = -1;
1792 char toast[80];
1793 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1794 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1797 if (res != AST_PBX_NO_HANGUP_PEER) {
1798 if (!chan->_softhangup)
1799 chan->hangupcause = peer->hangupcause;
1800 ast_hangup(peer);
1803 out:
1804 if (moh) {
1805 moh = 0;
1806 ast_moh_stop(chan);
1807 } else if (sentringing) {
1808 sentringing = 0;
1809 ast_indicate(chan, -1);
1811 ast_rtp_early_bridge(chan, NULL);
1812 hanguptree(outgoing, NULL);
1813 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1814 if (option_debug)
1815 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1817 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
1818 if (calldurationlimit)
1819 chan->whentohangup = 0;
1820 res = 0;
1823 done:
1824 ast_module_user_remove(u);
1825 return res;
1828 static int dial_exec(struct ast_channel *chan, void *data)
1830 struct ast_flags peerflags;
1832 memset(&peerflags, 0, sizeof(peerflags));
1834 return dial_exec_full(chan, data, &peerflags, NULL);
1837 static int retrydial_exec(struct ast_channel *chan, void *data)
1839 char *announce = NULL, *dialdata = NULL;
1840 const char *context = NULL;
1841 int sleep = 0, loops = 0, res = -1;
1842 struct ast_module_user *u;
1843 struct ast_flags peerflags;
1845 if (ast_strlen_zero(data)) {
1846 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1847 return -1;
1850 u = ast_module_user_add(chan);
1852 announce = ast_strdupa(data);
1854 memset(&peerflags, 0, sizeof(peerflags));
1856 if ((dialdata = strchr(announce, '|'))) {
1857 *dialdata++ = '\0';
1858 if (sscanf(dialdata, "%d", &sleep) == 1) {
1859 sleep *= 1000;
1860 } else {
1861 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1862 goto done;
1864 if ((dialdata = strchr(dialdata, '|'))) {
1865 *dialdata++ = '\0';
1866 if (sscanf(dialdata, "%d", &loops) != 1) {
1867 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1868 goto done;
1873 if ((dialdata = strchr(dialdata, '|'))) {
1874 *dialdata++ = '\0';
1875 } else {
1876 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1877 goto done;
1880 if (sleep < 1000)
1881 sleep = 10000;
1883 if (!loops)
1884 loops = -1; /* run forever */
1886 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1888 res = 0;
1889 while (loops) {
1890 int continue_exec;
1892 chan->data = "Retrying";
1893 if (ast_test_flag(chan, AST_FLAG_MOH))
1894 ast_moh_stop(chan);
1896 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1897 if (continue_exec)
1898 break;
1900 if (res == 0) {
1901 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1902 if (!ast_strlen_zero(announce)) {
1903 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1904 if(!(res = ast_streamfile(chan, announce, chan->language)))
1905 ast_waitstream(chan, AST_DIGIT_ANY);
1906 } else
1907 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1909 if (!res && sleep) {
1910 if (!ast_test_flag(chan, AST_FLAG_MOH))
1911 ast_moh_start(chan, NULL, NULL);
1912 res = ast_waitfordigit(chan, sleep);
1914 } else {
1915 if (!ast_strlen_zero(announce)) {
1916 if (ast_fileexists(announce, NULL, chan->language) > 0) {
1917 if (!(res = ast_streamfile(chan, announce, chan->language)))
1918 res = ast_waitstream(chan, "");
1919 } else
1920 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
1922 if (sleep) {
1923 if (!ast_test_flag(chan, AST_FLAG_MOH))
1924 ast_moh_start(chan, NULL, NULL);
1925 if (!res)
1926 res = ast_waitfordigit(chan, sleep);
1931 if (res < 0)
1932 break;
1933 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1934 if (onedigit_goto(chan, context, (char) res, 1)) {
1935 res = 0;
1936 break;
1939 loops--;
1941 if (loops == 0)
1942 res = 0;
1943 else if (res == 1)
1944 res = 0;
1946 if (ast_test_flag(chan, AST_FLAG_MOH))
1947 ast_moh_stop(chan);
1948 done:
1949 ast_module_user_remove(u);
1950 return res;
1953 static int unload_module(void)
1955 int res;
1957 res = ast_unregister_application(app);
1958 res |= ast_unregister_application(rapp);
1960 ast_module_user_hangup_all();
1962 return res;
1965 static int load_module(void)
1967 int res;
1969 res = ast_register_application(app, dial_exec, synopsis, descrip);
1970 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1972 return res;
1975 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");