2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33 #include <sys/signal.h>
35 #include <netinet/in.h>
37 #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
38 #include "asterisk/lock.h"
39 #include "asterisk/file.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/module.h"
43 #include "asterisk/translate.h"
44 #include "asterisk/say.h"
45 #include "asterisk/config.h"
46 #include "asterisk/features.h"
47 #include "asterisk/musiconhold.h"
48 #include "asterisk/callerid.h"
49 #include "asterisk/utils.h"
50 #include "asterisk/app.h"
51 #include "asterisk/causes.h"
52 #include "asterisk/rtp.h"
53 #include "asterisk/cdr.h"
54 #include "asterisk/manager.h"
55 #include "asterisk/privacy.h"
56 #include "asterisk/stringfields.h"
57 #include "asterisk/global_datastores.h"
59 static char *app = "Dial";
61 static char *synopsis = "Place a call and connect to the current channel";
63 static char *descrip =
64 " Dial(Technology/resource[&Tech2/resource2...][,timeout][,options][,URL]):\n"
65 "This application will place calls to one or more specified channels. As soon\n"
66 "as one of the requested channels answers, the originating channel will be\n"
67 "answered, if it has not already been answered. These two channels will then\n"
68 "be active in a bridged call. All other channels that were requested will then\n"
70 " Unless there is a timeout specified, the Dial application will wait\n"
71 "indefinitely until one of the called channels answers, the user hangs up, or\n"
72 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
73 "continue if no requested channels can be called, or if the timeout expires.\n\n"
74 " This application sets the following channel variables upon completion:\n"
75 " DIALEDTIME - This is the time from dialing a channel until when it\n"
77 " ANSWEREDTIME - This is the amount of time for actual call.\n"
78 " DIALSTATUS - This is the status of the call:\n"
79 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
80 " DONTCALL | TORTURE | INVALIDARGS\n"
81 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
82 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
83 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
84 "wants to send the caller to the 'torture' script.\n"
85 " This application will report normal termination if the originating channel\n"
86 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
88 " The optional URL will be sent to the called party if the channel supports it.\n"
89 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
90 "application will be put into that group (as in Set(GROUP()=...).\n"
91 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
92 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
93 "however, the variable will be unset after use.\n\n"
95 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
96 " C - Reset the CDR for this call.\n"
97 " c - If DIAL cancels this call, always set the flag to tell the channel\n"
98 " driver that the call is answered elsewhere.\n"
99 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
100 " a call to be answered. Exit to that extension if it exists in the\n"
101 " current context, or the context defined in the EXITCONTEXT variable,\n"
103 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
104 " party has answered, but before the call gets bridged. The 'called'\n"
105 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
106 " string is sent to the calling party. Both parameters can be used\n"
108 " e - execute the 'h' extension for peer after the call ends\n"
109 " f - Force the callerid of the *calling* channel to be set as the\n"
110 " extension associated with the channel using a dialplan 'hint'.\n"
111 " For example, some PSTNs do not allow CallerID to be set to anything\n"
112 " other than the number assigned to the caller.\n"
113 " g - Proceed with dialplan execution at the current extension if the\n"
114 " destination channel hangs up.\n"
115 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
116 " the specified priority and the called party to the specified priority+1.\n"
117 " Optionally, an extension, or extension and context may be specified. \n"
118 " Otherwise, the current extension is used. You cannot use any additional\n"
119 " action post answer options in conjunction with this option.\n"
120 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
121 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
122 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
124 " k - Allow the called party to enable parking of the call by sending\n"
125 " the DTMF sequence defined for call parking in features.conf.\n"
126 " K - Allow the calling party to enable parking of the call by sending\n"
127 " the DTMF sequence defined for call parking in features.conf.\n"
128 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
129 " left. Repeat the warning every 'z' ms. The following special\n"
130 " variables can be used with this option:\n"
131 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
132 " Play sounds to the caller.\n"
133 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
134 " Play sounds to the callee.\n"
135 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
136 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
137 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
138 " The default is to say the time remaining.\n"
139 " m([class]) - Provide hold music to the calling party until a requested\n"
140 " channel answers. A specific MusicOnHold class can be\n"
142 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
143 " to the calling channel. Arguments can be specified to the Macro\n"
144 " using '^' as a delimeter. The Macro can set the variable\n"
145 " MACRO_RESULT to specify the following actions after the Macro is\n"
146 " finished executing.\n"
147 " * ABORT Hangup both legs of the call.\n"
148 " * CONGESTION Behave as if line congestion was encountered.\n"
149 " * BUSY Behave as if a busy signal was encountered.\n"
150 " * CONTINUE Hangup the called party and allow the calling party\n"
151 " to continue dialplan execution at the next priority.\n"
152 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
153 " specified priority. Optionally, an extension, or\n"
154 " extension and priority can be specified.\n"
155 " You cannot use any additional action post answer options in conjunction\n"
156 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
157 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
158 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
159 " that no introductions are to be saved in the priv-callerintros\n"
161 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
162 " that if callerID is present, do not screen the call.\n"
163 " o - Specify that the CallerID that was present on the *calling* channel\n"
164 " be set as the CallerID on the *called* channel. This was the\n"
165 " behavior of Asterisk 1.0 and earlier.\n"
166 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
167 " only, if specified on non-Zaptel interface, it will be ignored).\n"
168 " When the destination answers (presumably an operator services\n"
169 " station), the originator no longer has control of their line.\n"
170 " They may hang up, but the switch will not release their line\n"
171 " until the destination party hangs up (the operator). Specified\n"
172 " without an arg, or with 1 as an arg, the originator hanging up\n"
173 " will cause the phone to ring back immediately. With a 2 specified,\n"
174 " when the \"operator\" flashes the trunk, it will ring their phone\n"
176 " p - This option enables screening mode. This is basically Privacy mode\n"
178 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
179 " it is provided. The current extension is used if a database\n"
180 " family/key is not specified.\n"
181 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
182 " party until the called channel has answered.\n"
183 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
184 " answered the call.\n"
185 " t - Allow the called party to transfer the calling party by sending the\n"
186 " DTMF sequence defined in features.conf.\n"
187 " T - Allow the calling party to transfer the called party by sending the\n"
188 " DTMF sequence defined in features.conf.\n"
189 " U(x[^arg]) - Execute via Gosub the routine 'x' for the *called* channel before connecting\n"
190 " to the calling channel. Arguments can be specified to the Gosub\n"
191 " using '^' as a delimeter. The Gosub routine can set the variable\n"
192 " GOSUB_RESULT to specify the following actions after the Gosub returns.\n"
193 " * ABORT Hangup both legs of the call.\n"
194 " * CONGESTION Behave as if line congestion was encountered.\n"
195 " * BUSY Behave as if a busy signal was encountered.\n"
196 " * CONTINUE Hangup the called party and allow the calling party\n"
197 " to continue dialplan execution at the next priority.\n"
198 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
199 " specified priority. Optionally, an extension, or\n"
200 " extension and priority can be specified.\n"
201 " You cannot use any additional action post answer options in conjunction\n"
202 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
203 " so you will not be able to set timeouts via the TIMEOUT() function in this routine.\n"
204 " w - Allow the called party to enable recording of the call by sending\n"
205 " the DTMF sequence defined for one-touch recording in features.conf.\n"
206 " W - Allow the calling party to enable recording of the call by sending\n"
207 " the DTMF sequence defined for one-touch recording in features.conf.\n"
208 " x - Allow the called party to enable recording of the call by sending\n"
209 " the DTMF sequence defined for one-touch automixmonitor in features.conf\n"
210 " X - Allow the calling party to enable recording of the call by sending\n"
211 " the DTMF sequence defined for one-touch automixmonitor in features.conf\n";
213 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
214 static char *rapp = "RetryDial";
215 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
216 static char *rdescrip =
217 " RetryDial(announce,sleep,retries,dialargs): This application will attempt to\n"
218 "place a call using the normal Dial application. If no channel can be reached,\n"
219 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
220 "seconds before retying the call. After 'retires' number of attempts, the\n"
221 "calling channel will continue at the next priority in the dialplan. If the\n"
222 "'retries' setting is set to 0, this application will retry endlessly.\n"
223 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
224 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
225 "one, The call will jump to that extension immediately.\n"
226 " The 'dialargs' are specified in the same format that arguments are provided\n"
227 "to the Dial application.\n";
230 OPT_ANNOUNCE = (1 << 0),
231 OPT_RESETCDR = (1 << 1),
232 OPT_DTMF_EXIT = (1 << 2),
233 OPT_SENDDTMF = (1 << 3),
234 OPT_FORCECLID = (1 << 4),
235 OPT_GO_ON = (1 << 5),
236 OPT_CALLEE_HANGUP = (1 << 6),
237 OPT_CALLER_HANGUP = (1 << 7),
238 OPT_DURATION_LIMIT = (1 << 9),
239 OPT_MUSICBACK = (1 << 10),
240 OPT_CALLEE_MACRO = (1 << 11),
241 OPT_SCREEN_NOINTRO = (1 << 12),
242 OPT_SCREEN_NOCLID = (1 << 13),
243 OPT_ORIGINAL_CLID = (1 << 14),
244 OPT_SCREENING = (1 << 15),
245 OPT_PRIVACY = (1 << 16),
246 OPT_RINGBACK = (1 << 17),
247 OPT_DURATION_STOP = (1 << 18),
248 OPT_CALLEE_TRANSFER = (1 << 19),
249 OPT_CALLER_TRANSFER = (1 << 20),
250 OPT_CALLEE_MONITOR = (1 << 21),
251 OPT_CALLER_MONITOR = (1 << 22),
252 OPT_GOTO = (1 << 23),
253 OPT_OPERMODE = (1 << 24),
254 OPT_CALLEE_PARK = (1 << 25),
255 OPT_CALLER_PARK = (1 << 26),
256 OPT_IGNORE_FORWARDING = (1 << 27),
257 OPT_CALLEE_GOSUB = (1 << 28),
258 OPT_CALLEE_MIXMONITOR = (1 << 29),
259 OPT_CALLER_MIXMONITOR = (1 << 30),
262 #define DIAL_STILLGOING (1 << 31)
263 #define DIAL_NOFORWARDHTML ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
264 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 33)
265 #define OPT_PEER_H ((uint64_t)1 << 34)
268 OPT_ARG_ANNOUNCE = 0,
271 OPT_ARG_DURATION_LIMIT,
273 OPT_ARG_CALLEE_MACRO,
274 OPT_ARG_CALLEE_GOSUB,
276 OPT_ARG_DURATION_STOP,
278 /* note: this entry _MUST_ be the last one in the enum */
282 AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
283 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
284 AST_APP_OPTION('C', OPT_RESETCDR),
285 AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
286 AST_APP_OPTION('d', OPT_DTMF_EXIT),
287 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
288 AST_APP_OPTION('e', OPT_PEER_H),
289 AST_APP_OPTION('f', OPT_FORCECLID),
290 AST_APP_OPTION('g', OPT_GO_ON),
291 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
292 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
293 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
294 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
295 AST_APP_OPTION('k', OPT_CALLEE_PARK),
296 AST_APP_OPTION('K', OPT_CALLER_PARK),
297 AST_APP_OPTION('k', OPT_CALLEE_PARK),
298 AST_APP_OPTION('K', OPT_CALLER_PARK),
299 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
300 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
301 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
302 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
303 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
304 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
305 AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
306 AST_APP_OPTION('p', OPT_SCREENING),
307 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
308 AST_APP_OPTION('r', OPT_RINGBACK),
309 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
310 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
311 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
312 AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
313 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
314 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
315 AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
316 AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
319 #define CAN_EARLY_BRIDGE(flags) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
320 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
321 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK))
324 * The list of active channels
327 struct chanlist *next;
328 struct ast_channel *chan;
333 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
335 /* Hang up a tree of stuff */
338 /* Hangup any existing lines we have open */
339 if (outgoing->chan && (outgoing->chan != exception)) {
340 if (answered_elsewhere)
341 ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
342 ast_hangup(outgoing->chan);
345 outgoing=outgoing->next;
350 #define AST_MAX_WATCHERS 256
353 * argument to handle_cause() and other functions.
356 struct ast_channel *chan;
362 static void handle_cause(int cause, struct cause_args *num)
364 struct ast_cdr *cdr = num->chan->cdr;
373 case AST_CAUSE_CONGESTION:
379 case AST_CAUSE_UNREGISTERED:
385 case AST_CAUSE_NORMAL_CLEARING:
394 /* free the buffer if allocated, and set the pointer to the second arg */
395 #define S_REPLACE(s, new_val) \
402 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
404 char rexten[2] = { exten, '\0' };
407 if (!ast_goto_if_exists(chan, context, rexten, pri))
410 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
412 else if (!ast_strlen_zero(chan->macrocontext)) {
413 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
421 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
423 const char *context = S_OR(chan->macrocontext, chan->context);
424 const char *exten = S_OR(chan->macroexten, chan->exten);
426 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
429 static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
431 manager_event(EVENT_FLAG_CALL, "Dial",
432 "SubEvent: Begin\r\n"
434 "Destination: %s\r\n"
435 "CallerIDNum: %s\r\n"
436 "CallerIDName: %s\r\n"
438 "DestUniqueID: %s\r\n"
439 "Dialstring: %s\r\n",
440 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
441 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
442 dst->uniqueid, dialstring ? dialstring : "");
445 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
447 manager_event(EVENT_FLAG_CALL, "Dial",
451 "DialStatus: %s\r\n",
452 src->name, src->uniqueid, dialstatus);
456 * helper function for wait_for_answer()
458 * XXX this code is highly suspicious, as it essentially overwrites
459 * the outgoing channel without properly deleting it.
461 static void do_forward(struct chanlist *o,
462 struct cause_args *num, struct ast_flags64 *peerflags, int single)
465 struct ast_channel *original = o->chan;
466 struct ast_channel *c = o->chan; /* the winner */
467 struct ast_channel *in = num->chan; /* the input channel */
472 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
473 if ((stuff = strchr(tmpchan, '/'))) {
477 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
478 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
482 /* Before processing channel, go ahead and check for forwarding */
483 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
484 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
485 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
486 ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
488 cause = AST_CAUSE_BUSY;
490 /* Setup parameters */
491 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
494 ast_channel_make_compatible(o->chan, in);
495 ast_channel_inherit_variables(in, o->chan);
496 ast_channel_datastore_inherit(in, o->chan);
498 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
501 ast_clear_flag64(o, DIAL_STILLGOING);
502 handle_cause(cause, num);
504 char *new_cid_num, *new_cid_name;
505 struct ast_channel *src;
507 ast_rtp_make_compatible(c, in, single);
508 if (ast_test_flag64(o, OPT_FORCECLID)) {
509 new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
510 new_cid_name = NULL; /* XXX no name ? */
511 src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
513 new_cid_num = ast_strdup(in->cid.cid_num);
514 new_cid_name = ast_strdup(in->cid.cid_name);
517 ast_string_field_set(c, accountcode, src->accountcode);
518 c->cdrflags = src->cdrflags;
519 S_REPLACE(c->cid.cid_num, new_cid_num);
520 S_REPLACE(c->cid.cid_name, new_cid_name);
522 if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
523 S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
525 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
526 if (ast_call(c, tmpchan, 0)) {
527 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
528 ast_clear_flag64(o, DIAL_STILLGOING);
529 ast_hangup(original);
533 senddialevent(in, c, stuff);
534 /* After calling, set callerid to extension */
535 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
536 char cidname[AST_MAX_EXTENSION] = "";
537 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
539 /* Hangup the original channel now, in case we needed it */
540 ast_hangup(original);
545 /* argument used for some functions. */
546 struct privacy_args {
550 char privintro[1024];
554 static struct ast_channel *wait_for_answer(struct ast_channel *in,
555 struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
556 struct privacy_args *pa,
557 const struct cause_args *num_in, int *result)
559 struct cause_args num = *num_in;
560 int prestart = num.busy + num.congestion + num.nochan;
562 struct ast_channel *peer = NULL;
563 /* single is set if only one destination is enabled */
564 int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
566 struct chanlist *epollo;
570 /* Turn off hold music, etc */
571 ast_deactivate_generator(in);
572 /* If we are calling a single channel, make them compatible for in-band tone purpose */
573 ast_channel_make_compatible(outgoing->chan, in);
577 for (epollo = outgoing; epollo; epollo = epollo->next)
578 ast_poll_channel_add(in, epollo->chan);
581 while (*to && !peer) {
583 int pos = 0; /* how many channels do we handle */
584 int numlines = prestart;
585 struct ast_channel *winner;
586 struct ast_channel *watchers[AST_MAX_WATCHERS];
588 watchers[pos++] = in;
589 for (o = outgoing; o; o = o->next) {
590 /* Keep track of important channels */
591 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
592 watchers[pos++] = o->chan;
595 if (pos == 1) { /* only the input channel is available */
596 if (numlines == (num.busy + num.congestion + num.nochan)) {
597 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
599 strcpy(pa->status, "BUSY");
600 else if (num.congestion)
601 strcpy(pa->status, "CONGESTION");
603 strcpy(pa->status, "CHANUNAVAIL");
605 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
610 winner = ast_waitfor_n(watchers, pos, to);
611 for (o = outgoing; o; o = o->next) {
613 struct ast_channel *c = o->chan;
617 if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
619 ast_verb(3, "%s answered %s\n", c->name, in->name);
621 ast_copy_flags64(peerflags, o,
622 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
623 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
624 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
625 OPT_CALLEE_PARK | OPT_CALLER_PARK |
626 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
628 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
629 ast_copy_string(c->exten, "", sizeof(c->exten));
635 /* here, o->chan == c == winner */
636 if (!ast_strlen_zero(c->call_forward)) {
637 do_forward(o, &num, peerflags, single);
640 f = ast_read(winner);
642 in->hangupcause = c->hangupcause;
644 ast_poll_channel_del(in, c);
648 ast_clear_flag64(o, DIAL_STILLGOING);
649 handle_cause(in->hangupcause, &num);
652 if (f->frametype == AST_FRAME_CONTROL) {
653 switch(f->subclass) {
654 case AST_CONTROL_ANSWER:
655 /* This is our guy if someone answered. */
657 ast_verb(3, "%s answered %s\n", c->name, in->name);
659 ast_copy_flags64(peerflags, o,
660 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
661 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
662 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
663 OPT_CALLEE_PARK | OPT_CALLER_PARK |
664 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
666 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
667 ast_copy_string(c->exten, "", sizeof(c->exten));
668 if (CAN_EARLY_BRIDGE(peerflags))
669 /* Setup early bridge if appropriate */
670 ast_channel_early_bridge(in, peer);
672 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
673 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
674 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
676 case AST_CONTROL_BUSY:
677 ast_verb(3, "%s is busy\n", c->name);
678 in->hangupcause = c->hangupcause;
681 ast_clear_flag64(o, DIAL_STILLGOING);
682 handle_cause(AST_CAUSE_BUSY, &num);
684 case AST_CONTROL_CONGESTION:
685 ast_verb(3, "%s is circuit-busy\n", c->name);
686 in->hangupcause = c->hangupcause;
689 ast_clear_flag64(o, DIAL_STILLGOING);
690 handle_cause(AST_CAUSE_CONGESTION, &num);
692 case AST_CONTROL_RINGING:
693 ast_verb(3, "%s is ringing\n", c->name);
694 /* Setup early media if appropriate */
695 if (single && CAN_EARLY_BRIDGE(peerflags))
696 ast_channel_early_bridge(in, c);
697 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
698 ast_indicate(in, AST_CONTROL_RINGING);
702 case AST_CONTROL_PROGRESS:
703 ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
704 /* Setup early media if appropriate */
705 if (single && CAN_EARLY_BRIDGE(peerflags))
706 ast_channel_early_bridge(in, c);
707 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
708 ast_indicate(in, AST_CONTROL_PROGRESS);
710 case AST_CONTROL_VIDUPDATE:
711 ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
712 ast_indicate(in, AST_CONTROL_VIDUPDATE);
714 case AST_CONTROL_PROCEEDING:
715 ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
716 if (single && CAN_EARLY_BRIDGE(peerflags))
717 ast_channel_early_bridge(in, c);
718 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
719 ast_indicate(in, AST_CONTROL_PROCEEDING);
721 case AST_CONTROL_HOLD:
722 ast_verb(3, "Call on %s placed on hold\n", c->name);
723 ast_indicate(in, AST_CONTROL_HOLD);
725 case AST_CONTROL_UNHOLD:
726 ast_verb(3, "Call on %s left from hold\n", c->name);
727 ast_indicate(in, AST_CONTROL_UNHOLD);
729 case AST_CONTROL_OFFHOOK:
730 case AST_CONTROL_FLASH:
731 /* Ignore going off hook and flash */
734 if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
735 ast_verb(3, "%s stopped sounds\n", c->name);
736 ast_indicate(in, -1);
741 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
744 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
745 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag64(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
746 if (ast_write(in, f))
747 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
748 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag64(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
749 if (ast_write(in, f))
750 ast_log(LOG_WARNING, "Unable to forward image\n");
751 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag64(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
752 if (ast_write(in, f))
753 ast_log(LOG_WARNING, "Unable to send text\n");
754 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)) {
755 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
756 ast_log(LOG_WARNING, "Unable to send URL\n");
762 struct ast_frame *f = ast_read(in);
764 if (f && (f->frametype != AST_FRAME_VOICE))
765 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
766 else if (!f || (f->frametype != AST_FRAME_VOICE))
767 printf("Hangup received on %s\n", in->name);
769 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
772 strcpy(pa->status, "CANCEL");
773 ast_cdr_noanswer(in->cdr);
779 /* now f is guaranteed non-NULL */
780 if (f->frametype == AST_FRAME_DTMF) {
781 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
782 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
783 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
784 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
786 ast_cdr_noanswer(in->cdr);
787 *result = f->subclass;
788 strcpy(pa->status, "CANCEL");
794 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
795 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
796 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
798 strcpy(pa->status, "CANCEL");
799 ast_cdr_noanswer(in->cdr);
805 /* Forward HTML stuff */
806 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
807 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
808 ast_log(LOG_WARNING, "Unable to send URL\n");
811 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
812 if (ast_write(outgoing->chan, f))
813 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
815 if (single && (f->frametype == AST_FRAME_CONTROL) &&
816 ((f->subclass == AST_CONTROL_HOLD) ||
817 (f->subclass == AST_CONTROL_UNHOLD) ||
818 (f->subclass == AST_CONTROL_VIDUPDATE))) {
819 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
820 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
825 ast_verb(3, "Nobody picked up in %d ms\n", orig);
826 if (!*to || ast_check_hangup(in)) {
827 ast_cdr_noanswer(in->cdr);
831 if (peer && !ast_cdr_log_unanswered()) {
832 /* suppress the CDR's that didn't win */
834 for (o = outgoing; o; o = o->next) {
835 struct ast_channel *c = o->chan;
836 if (c && c != peer && c->cdr) {
837 ast_set_flag(c->cdr, AST_CDR_FLAG_POST_DISABLED);
840 } else if (!peer && !ast_cdr_log_unanswered()) {
841 /* suppress the CDR's that didn't win */
843 for (o = outgoing; o; o = o->next) {
844 struct ast_channel *c = o->chan;
846 ast_set_flag(c->cdr, AST_CDR_FLAG_POST_DISABLED);
852 for (epollo = outgoing; epollo; epollo = epollo->next) {
854 ast_poll_channel_del(in, epollo->chan);
861 static void replace_macro_delimiter(char *s)
869 /* returns true if there is a valid privacy reply */
870 static int valid_priv_reply(struct ast_flags64 *opts, int res)
874 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
876 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
881 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
882 char *parse, unsigned int *calldurationlimit)
884 char *stringp = ast_strdupa(parse);
885 char *limit_str, *warning_str, *warnfreq_str;
887 int play_to_caller=0,play_to_callee=0;
890 limit_str = strsep(&stringp, ":");
891 warning_str = strsep(&stringp, ":");
892 warnfreq_str = strsep(&stringp, ":");
894 config->timelimit = atol(limit_str);
896 config->play_warning = atol(warning_str);
898 config->warning_freq = atol(warnfreq_str);
900 if (!config->timelimit) {
901 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
902 config->timelimit = config->play_warning = config->warning_freq = 0;
903 config->warning_sound = NULL;
904 return -1; /* error */
905 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
906 int w = config->warning_freq;
908 /* If the first warning is requested _after_ the entire call would end,
909 and no warning frequency is requested, then turn off the warning. If
910 a warning frequency is requested, reduce the 'first warning' time by
911 that frequency until it falls within the call's total time limit.
913 timelim->| delta |<-playwarning
914 0__________________|_________________|
917 so the number of intervals to cut is 1+(delta-1)/w
921 config->play_warning = 0;
923 config->play_warning -= w * ( 1 + (delta-1)/w );
924 if (config->play_warning < 1)
925 config->play_warning = config->warning_freq = 0;
929 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
930 play_to_caller = var ? ast_true(var) : 1;
932 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
933 play_to_callee = var ? ast_true(var) : 0;
935 if (!play_to_caller && !play_to_callee)
938 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
939 config->warning_sound = S_OR(var, "timeleft");
941 /* The code looking at config wants a NULL, not just "", to decide
942 * that the message should not be played, so we replace "" with NULL.
943 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
946 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
947 config->end_sound = S_OR(var, NULL);
948 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
949 config->start_sound = S_OR(var, NULL);
951 /* undo effect of S(x) in case they are both used */
952 *calldurationlimit = 0;
953 /* more efficient to do it like S(x) does since no advanced opts */
954 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
955 *calldurationlimit = config->timelimit / 1000;
956 ast_verb(3, "Setting call duration limit to %d seconds.\n",
958 config->timelimit = play_to_caller = play_to_callee =
959 config->play_warning = config->warning_freq = 0;
961 ast_verb(3, "Limit Data for this call:\n");
962 ast_verb(4, "timelimit = %ld\n", config->timelimit);
963 ast_verb(4, "play_warning = %ld\n", config->play_warning);
964 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
965 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
966 ast_verb(4, "warning_freq = %ld\n", config->warning_freq);
967 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
968 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
969 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
972 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
974 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
978 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
979 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
985 /* Get the user's intro, store it in priv-callerintros/$CID,
986 unless it is already there-- this should be done before the
987 call is actually dialed */
989 /* all ring indications and moh for the caller has been halted as soon as the
990 target extension was picked up. We are going to have to kill some
991 time and make the caller believe the peer hasn't picked up yet */
993 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
994 char *original_moh = ast_strdupa(chan->musicclass);
995 ast_indicate(chan, -1);
996 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
997 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
998 ast_string_field_set(chan, musicclass, original_moh);
999 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1000 ast_indicate(chan, AST_CONTROL_RINGING);
1004 /* Start autoservice on the other chan ?? */
1005 res2 = ast_autoservice_start(chan);
1006 /* Now Stream the File */
1007 for (loopcount = 0; loopcount < 3; loopcount++) {
1008 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1010 if (!res2) /* on timeout, play the message again */
1011 res2 = ast_play_and_wait(peer,"priv-callpending");
1012 if (!valid_priv_reply(opts, res2))
1014 /* priv-callpending script:
1015 "I have a caller waiting, who introduces themselves as:"
1018 res2 = ast_play_and_wait(peer, pa->privintro);
1019 if (!valid_priv_reply(opts, res2))
1021 /* now get input from the called party, as to their choice */
1023 /* XXX can we have both, or they are mutually exclusive ? */
1024 if( ast_test_flag64(opts, OPT_PRIVACY) )
1025 res2 = ast_play_and_wait(peer,"priv-callee-options");
1026 if( ast_test_flag64(opts, OPT_SCREENING) )
1027 res2 = ast_play_and_wait(peer,"screen-callee-options");
1029 /*! \page DialPrivacy Dial Privacy scripts
1030 \par priv-callee-options script:
1031 "Dial 1 if you wish this caller to reach you directly in the future,
1032 and immediately connect to their incoming call
1033 Dial 2 if you wish to send this caller to voicemail now and
1035 Dial 3 to send this caller to the torture menus, now and forevermore.
1036 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1037 Dial 5 to allow this caller to come straight thru to you in the future,
1038 but right now, just this once, send them to voicemail."
1039 \par screen-callee-options script:
1040 "Dial 1 if you wish to immediately connect to the incoming call
1041 Dial 2 if you wish to send this caller to voicemail.
1042 Dial 3 to send this caller to the torture menus.
1043 Dial 4 to send this caller to a simple "go away" menu.
1045 if (valid_priv_reply(opts, res2))
1047 /* invalid option */
1048 res2 = ast_play_and_wait(peer, "vm-sorry");
1051 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
1053 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1054 ast_indicate(chan, -1);
1057 ast_autoservice_stop(chan);
1058 if(ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1059 /* map keypresses to various things, the index is res2 - '1' */
1060 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1061 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1063 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
1064 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1065 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1071 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1074 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1077 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1080 /* XXX should we set status to DENY ? */
1081 if( ast_test_flag64(opts, OPT_PRIVACY) )
1083 /* if not privacy, then 5 is the same as "default" case */
1084 default: /* bad input or -1 if failure to start autoservice */
1085 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1086 /* well, there seems basically two choices. Just patch the caller thru immediately,
1087 or,... put 'em thru to voicemail. */
1088 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1089 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1090 /* XXX should we set status to DENY ? */
1091 /* XXX what about the privacy flags ? */
1095 if (res2 == '1') { /* the only case where we actually connect */
1096 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1097 just clog things up, and it's not useful information, not being tied to a CID */
1098 if( strncmp(pa->privcid,"NOCALLERID",10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO) ) {
1099 ast_filedelete(pa->privintro, NULL);
1100 if( ast_fileexists(pa->privintro, NULL, NULL ) > 0 )
1101 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1103 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1105 return 0; /* the good exit path */
1107 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1112 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1113 static int setup_privacy_args(struct privacy_args *pa,
1114 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
1120 if (!ast_strlen_zero(chan->cid.cid_num)) {
1121 l = ast_strdupa(chan->cid.cid_num);
1122 ast_shrink_phone_number(l);
1123 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1124 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n",
1125 opt_args[OPT_ARG_PRIVACY], l);
1126 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1128 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1129 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1134 tnam = ast_strdupa(chan->name);
1135 /* clean the channel name so slashes don't try to end up in disk file name */
1136 for (tn2 = tnam; *tn2; tn2++) {
1137 if (*tn2=='/') /* any other chars to be afraid of? */
1140 ast_verb(3, "Privacy-- callerid is empty\n");
1142 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1144 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1147 ast_copy_string(pa->privcid,l,sizeof(pa->privcid));
1149 if( strncmp(pa->privcid,"NOCALLERID",10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag64(&opts, OPT_SCREEN_NOCLID) is set also */
1150 if (option_verbose > 2)
1151 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1152 pa->privdb_val = AST_PRIVACY_ALLOW;
1153 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid,"NOCALLERID",10) == 0 ) {
1154 if (option_verbose > 2)
1155 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1158 if (pa->privdb_val == AST_PRIVACY_DENY ) {
1159 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1160 if (option_verbose > 2)
1161 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1163 } else if (pa->privdb_val == AST_PRIVACY_KILL ) {
1164 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1165 return 0; /* Is this right? */
1166 } else if (pa->privdb_val == AST_PRIVACY_TORTURE ) {
1167 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1168 return 0; /* is this right??? */
1169 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN ) {
1170 /* Get the user's intro, store it in priv-callerintros/$CID,
1171 unless it is already there-- this should be done before the
1172 call is actually dialed */
1174 /* make sure the priv-callerintros dir actually exists */
1175 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1176 if ((res = ast_mkdir(pa->privintro, 0755))) {
1177 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1181 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1182 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1183 /* the DELUX version of this code would allow this caller the
1184 option to hear and retape their previously recorded intro.
1187 int duration; /* for feedback from play_and_wait */
1188 /* the file doesn't exist yet. Let the caller submit his
1189 vocal intro for posterity */
1190 /* priv-recordintro script:
1192 "At the tone, please say your name:"
1196 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1197 /* don't think we'll need a lock removed, we took care of
1198 conflicts by naming the pa.privintro file */
1200 /* Delete the file regardless since they hung up during recording */
1201 ast_filedelete(pa->privintro, NULL);
1202 if (ast_fileexists(pa->privintro,NULL,NULL ) > 0 )
1203 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1205 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1208 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1209 ast_waitstream(chan, "");
1212 return 1; /* success */
1215 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
1217 int res = -1; /* default: error */
1218 char *rest, *cur; /* scan the list of destinations */
1219 struct chanlist *outgoing = NULL; /* list of destinations */
1220 struct ast_channel *peer;
1221 int to; /* timeout */
1222 struct cause_args num = { chan, 0, 0, 0 };
1225 char cidname[AST_MAX_EXTENSION] = "";
1227 struct ast_bridge_config config;
1228 unsigned int calldurationlimit = 0;
1229 char *dtmfcalled = NULL, *dtmfcalling = NULL;
1230 struct privacy_args pa = {
1233 .status = "INVALIDARGS",
1235 int sentringing = 0, moh = 0;
1236 const char *outbound_group = NULL;
1241 AST_DECLARE_APP_ARGS(args,
1243 AST_APP_ARG(timeout);
1244 AST_APP_ARG(options);
1247 struct ast_flags64 opts = { 0, };
1248 char *opt_args[OPT_ARG_ARRAY_SIZE];
1249 struct ast_datastore *datastore = NULL;
1250 int fulldial = 0, num_dialed = 0;
1252 if (ast_strlen_zero(data)) {
1253 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1254 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1258 parse = ast_strdupa(data);
1260 AST_STANDARD_APP_ARGS(args, parse);
1262 memset(&config,0,sizeof(struct ast_bridge_config));
1264 if (!ast_strlen_zero(args.options) &&
1265 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
1266 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1270 if (ast_strlen_zero(args.peers)) {
1271 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1272 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1276 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
1277 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1278 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
1281 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1282 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1283 if (!calldurationlimit) {
1284 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1285 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1288 ast_verb(3, "Setting call duration limit to %d seconds.\n", calldurationlimit);
1291 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1292 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
1293 dtmfcalled = strsep(&dtmfcalling, ":");
1296 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1297 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1301 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
1302 ast_cdr_reset(chan->cdr, NULL);
1303 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1304 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1306 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
1307 res = setup_privacy_args(&pa, &opts, opt_args, chan);
1310 res = -1; /* reset default */
1316 /* If a channel group has been specified, get it for use when we create peer channels */
1317 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1318 outbound_group = ast_strdupa(outbound_group);
1319 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1321 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1324 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1325 /* loop through the list of dial destinations */
1327 while ((cur = strsep(&rest, "&")) ) {
1328 struct chanlist *tmp;
1329 struct ast_channel *tc; /* channel for this destination */
1330 /* Get a technology/[device:]number pair */
1332 char *interface = ast_strdupa(number);
1333 char *tech = strsep(&number, "/");
1334 /* find if we already dialed this interface */
1336 struct ast_dialed_interface *di;
1337 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1340 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1343 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1346 ast_copy_flags64(tmp, &opts,
1347 OPT_CANCEL_ELSEWHERE |
1348 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1349 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1350 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1351 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1352 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1353 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1354 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
1356 ast_copy_string(numsubst, number, sizeof(numsubst));
1357 /* Request the peer */
1358 if (!(datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
1359 if(!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
1360 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1365 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1366 if((dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1367 datastore->data = dialed_interfaces;
1368 AST_LIST_HEAD_INIT(dialed_interfaces);
1369 ast_channel_datastore_add(chan, datastore);
1376 dialed_interfaces = datastore->data;
1377 AST_LIST_LOCK(dialed_interfaces);
1378 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1379 /* XXX case sensitive??? */
1380 if(!strcasecmp(di->interface, interface)) {
1385 if(!dialed && strcasecmp(tech, "Local")) {
1386 if(!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1387 AST_LIST_UNLOCK(dialed_interfaces);
1391 strcpy(di->interface, interface);
1392 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1393 } else if (dialed) {
1394 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n", di->interface);
1395 AST_LIST_UNLOCK(dialed_interfaces);
1400 AST_LIST_UNLOCK(dialed_interfaces);
1402 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
1404 /* If we can't, just go on to the next call */
1405 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1406 tech, cause, ast_cause2str(cause));
1407 handle_cause(cause, &num);
1408 if (!rest) /* we are on the last destination */
1409 chan->hangupcause = cause;
1413 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1415 /* Setup outgoing SDP to match incoming one */
1416 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
1418 /* Inherit specially named variables from parent channel */
1419 ast_channel_inherit_variables(chan, tc);
1421 tc->appl = "AppDial";
1422 tc->data = "(Outgoing Line)";
1423 tc->whentohangup = 0;
1425 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
1426 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
1427 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
1428 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
1430 /* Copy language from incoming to outgoing */
1431 ast_string_field_set(tc, language, chan->language);
1432 ast_string_field_set(tc, accountcode, chan->accountcode);
1433 tc->cdrflags = chan->cdrflags;
1434 if (ast_strlen_zero(tc->musicclass))
1435 ast_string_field_set(tc, musicclass, chan->musicclass);
1436 /* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
1437 tc->cid.cid_pres = chan->cid.cid_pres;
1438 tc->cid.cid_ton = chan->cid.cid_ton;
1439 tc->cid.cid_tns = chan->cid.cid_tns;
1440 tc->cid.cid_ani2 = chan->cid.cid_ani2;
1441 tc->adsicpe = chan->adsicpe;
1442 tc->transfercapability = chan->transfercapability;
1444 /* If we have an outbound group, set this peer channel to it */
1446 ast_app_group_set_channel(tc, outbound_group);
1448 /* Inherit context and extension */
1449 if (!ast_strlen_zero(chan->macrocontext))
1450 ast_copy_string(tc->dialcontext, chan->macrocontext, sizeof(tc->dialcontext));
1452 ast_copy_string(tc->dialcontext, chan->context, sizeof(tc->dialcontext));
1453 if (!ast_strlen_zero(chan->macroexten))
1454 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
1456 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
1458 res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
1460 /* Save the info in cdr's that we called them */
1462 ast_cdr_setdestchan(chan->cdr, tc->name);
1464 /* check the results of ast_call */
1466 /* Again, keep going even if there's an error */
1467 ast_debug(1, "ast call on peer returned %d\n", res);
1468 ast_verb(3, "Couldn't call %s\n", numsubst);
1474 senddialevent(chan, tc, numsubst);
1475 ast_verb(3, "Called %s\n", numsubst);
1476 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
1477 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1479 /* Put them in the list of outgoing thingies... We're ready now.
1480 XXX If we're forcibly removed, these outgoing calls won't get
1482 ast_set_flag64(tmp, DIAL_STILLGOING);
1484 tmp->next = outgoing;
1486 /* If this line is up, don't try anybody else */
1487 if (outgoing->chan->_state == AST_STATE_UP)
1491 if (ast_strlen_zero(args.timeout)) {
1494 to = atoi(args.timeout);
1498 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1502 strcpy(pa.status, "CHANUNAVAIL");
1503 if(fulldial == num_dialed) {
1508 /* Our status will at least be NOANSWER */
1509 strcpy(pa.status, "NOANSWER");
1510 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
1512 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1513 char *original_moh = ast_strdupa(chan->musicclass);
1514 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1515 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1516 ast_string_field_set(chan, musicclass, original_moh);
1518 ast_moh_start(chan, NULL, NULL);
1520 ast_indicate(chan, AST_CONTROL_PROGRESS);
1521 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
1522 ast_indicate(chan, AST_CONTROL_RINGING);
1528 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
1530 ast_channel_datastore_remove(chan, datastore);
1531 ast_channel_datastore_free(datastore);
1535 } else if (to) { /* Musta gotten hung up */
1537 } else { /* Nobody answered, next please? */
1540 /* almost done, although the 'else' block is 400 lines */
1543 time_t end_time, answer_time = time(NULL);
1544 char toast[80]; /* buffer to set variables */
1546 strcpy(pa.status, "ANSWER");
1547 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1548 we will always return with -1 so that it is hung up properly after the
1550 hanguptree(outgoing, peer, 1);
1552 /* If appropriate, log that we have a destination channel */
1554 ast_cdr_setdestchan(chan->cdr, peer->name);
1556 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1558 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1561 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1562 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1563 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
1564 ast_channel_sendurl( peer, args.url );
1566 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
1567 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
1572 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1576 /* Start autoservice on the other chan */
1577 res = ast_autoservice_start(chan);
1578 /* Now Stream the File */
1580 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1582 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1584 /* Ok, done. stop autoservice */
1585 res = ast_autoservice_stop(chan);
1586 if (digit > 0 && !res)
1587 res = ast_senddigit(chan, digit, 0);
1593 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1594 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1595 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1596 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1597 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1598 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1599 peer->priority = chan->priority + 2;
1600 ast_pbx_start(peer);
1601 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
1608 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1609 struct ast_app *theapp;
1610 const char *macro_result;
1612 res = ast_autoservice_start(chan);
1614 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1618 theapp = pbx_findapp("Macro");
1620 if (theapp && !res) { /* XXX why check res here ? */
1621 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1622 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1623 ast_debug(1, "Macro exited with status %d\n", res);
1626 ast_log(LOG_ERROR, "Could not find application Macro\n");
1630 if (ast_autoservice_stop(chan) < 0) {
1631 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1635 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1636 char *macro_transfer_dest;
1638 if (!strcasecmp(macro_result, "BUSY")) {
1639 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1640 ast_set_flag64(peerflags, OPT_GO_ON);
1642 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1643 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1644 ast_set_flag64(peerflags, OPT_GO_ON);
1646 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1647 /* hangup peer and keep chan alive assuming the macro has changed
1648 the context / exten / priority or perhaps
1649 the next priority in the current exten is desired.
1651 ast_set_flag64(peerflags, OPT_GO_ON);
1653 } else if (!strcasecmp(macro_result, "ABORT")) {
1654 /* Hangup both ends unless the caller has the g flag */
1656 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1658 /* perform a transfer to a new extension */
1659 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1660 replace_macro_delimiter(macro_transfer_dest);
1661 if (!ast_parseable_goto(chan, macro_transfer_dest))
1662 ast_set_flag64(peerflags, OPT_GO_ON);
1668 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
1669 struct ast_app *theapp;
1670 const char *gosub_result;
1671 char *gosub_args, *gosub_argstart;
1673 res = ast_autoservice_start(chan);
1675 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1679 theapp = pbx_findapp("Gosub");
1681 if (theapp && !res) { /* XXX why check res here ? */
1682 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
1684 /* Set where we came from */
1685 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
1686 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
1689 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], '|');
1690 if (gosub_argstart) {
1691 *gosub_argstart = 0;
1692 asprintf(&gosub_args, "%s|s|1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1);
1693 *gosub_argstart = '|';
1695 asprintf(&gosub_args, "%s|s|1", opt_args[OPT_ARG_CALLEE_GOSUB]);
1699 res = pbx_exec(peer, theapp, gosub_args);
1703 ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
1705 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
1709 ast_log(LOG_ERROR, "Could not find application Gosub\n");
1713 if (ast_autoservice_stop(chan) < 0) {
1714 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1718 if (!res && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
1719 char *gosub_transfer_dest;
1721 if (!strcasecmp(gosub_result, "BUSY")) {
1722 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1723 ast_set_flag64(peerflags, OPT_GO_ON);
1725 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
1726 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1727 ast_set_flag64(peerflags, OPT_GO_ON);
1729 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
1730 /* hangup peer and keep chan alive assuming the macro has changed
1731 the context / exten / priority or perhaps
1732 the next priority in the current exten is desired.
1734 ast_set_flag64(peerflags, OPT_GO_ON);
1736 } else if (!strcasecmp(gosub_result, "ABORT")) {
1737 /* Hangup both ends unless the caller has the g flag */
1739 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
1741 /* perform a transfer to a new extension */
1742 if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
1743 replace_macro_delimiter(gosub_transfer_dest);
1744 if (!ast_parseable_goto(chan, gosub_transfer_dest))
1745 ast_set_flag64(peerflags, OPT_GO_ON);
1752 if (calldurationlimit > 0) {
1753 peer->whentohangup = time(NULL) + calldurationlimit;
1755 if (!ast_strlen_zero(dtmfcalled)) {
1756 if (option_verbose > 2)
1757 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1758 res = ast_dtmf_stream(peer,chan,dtmfcalled,250,0);
1760 if (!ast_strlen_zero(dtmfcalling)) {
1761 if (option_verbose > 2)
1762 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1763 res = ast_dtmf_stream(chan,peer,dtmfcalling,250,0);
1767 if (res) { /* some error */
1769 end_time = time(NULL);
1771 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
1772 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1773 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
1774 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1775 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
1776 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1777 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
1778 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1779 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
1780 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1781 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
1782 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1783 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
1784 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1785 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
1786 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1787 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
1788 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
1789 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
1790 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
1795 } else if (sentringing) {
1797 ast_indicate(chan, -1);
1799 /* Be sure no generators are left on it */
1800 ast_deactivate_generator(chan);
1801 /* Make sure channels are compatible */
1802 res = ast_channel_make_compatible(chan, peer);
1804 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1809 if (opermode && !strncmp(chan->name,"Zap",3) && !strncmp(peer->name,"Zap",3)) {
1810 /* XXX what's this special handling for Zap <-> Zap ? */
1811 struct oprmode oprmode;
1813 oprmode.peer = peer;
1814 oprmode.mode = opermode;
1816 ast_channel_setoption(chan,
1817 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1819 res = ast_bridge_call(chan,peer,&config);
1820 end_time = time(NULL);
1821 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1822 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1825 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1826 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1829 if (ast_test_flag64(&opts, OPT_PEER_H)) {
1830 ast_log(LOG_NOTICE,"PEER context: %s; PEER exten: %s; PEER priority: %d\n",
1831 peer->context, peer->exten, peer->priority);
1834 strcpy(peer->context, chan->context);
1836 if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
1839 strcpy(peer->exten, "h");
1841 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
1842 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
1844 while ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found,1))) {
1848 /* Something bad happened, or a hangup has been requested. */
1849 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
1850 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
1852 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
1854 if (res != AST_PBX_NO_HANGUP_PEER) {
1855 if (!ast_check_hangup(chan))
1856 chan->hangupcause = peer->hangupcause;
1864 } else if (sentringing) {
1866 ast_indicate(chan, -1);
1868 ast_channel_early_bridge(chan, NULL);
1869 hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
1870 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1871 senddialendevent(chan, pa.status);
1872 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
1874 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE)) {
1875 if (calldurationlimit)
1876 chan->whentohangup = 0;
1884 static int dial_exec(struct ast_channel *chan, void *data)
1886 struct ast_flags64 peerflags;
1888 memset(&peerflags, 0, sizeof(peerflags));
1890 return dial_exec_full(chan, data, &peerflags, NULL);
1893 static int retrydial_exec(struct ast_channel *chan, void *data)
1896 const char *context = NULL;
1897 int sleep = 0, loops = 0, res = -1;
1898 struct ast_flags64 peerflags = { 0, };
1899 AST_DECLARE_APP_ARGS(args,
1900 AST_APP_ARG(announce);
1902 AST_APP_ARG(retries);
1903 AST_APP_ARG(dialdata);
1906 if (ast_strlen_zero(data)) {
1907 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1911 parse = ast_strdupa(data);
1912 AST_STANDARD_APP_ARGS(args, parse);
1914 if ((sleep = atoi(args.sleep))) {
1918 loops = atoi(args.retries);
1920 if (!args.dialdata) {
1921 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
1929 loops = -1; /* run forever */
1931 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1937 chan->data = "Retrying";
1938 if (ast_test_flag(chan, AST_FLAG_MOH))
1941 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
1946 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
1947 if (!ast_strlen_zero(args.announce)) {
1948 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
1949 if(!(res = ast_streamfile(chan, args.announce, chan->language)))
1950 ast_waitstream(chan, AST_DIGIT_ANY);
1952 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
1954 if (!res && sleep) {
1955 if (!ast_test_flag(chan, AST_FLAG_MOH))
1956 ast_moh_start(chan, NULL, NULL);
1957 res = ast_waitfordigit(chan, sleep);
1960 if (!ast_strlen_zero(args.announce)) {
1961 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
1962 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
1963 res = ast_waitstream(chan, "");
1965 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
1968 if (!ast_test_flag(chan, AST_FLAG_MOH))
1969 ast_moh_start(chan, NULL, NULL);
1971 res = ast_waitfordigit(chan, sleep);
1978 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1979 if (onedigit_goto(chan, context, (char) res, 1)) {
1991 if (ast_test_flag(chan, AST_FLAG_MOH))
1997 static int unload_module(void)
2000 struct ast_context *con;
2002 res = ast_unregister_application(app);
2003 res |= ast_unregister_application(rapp);
2005 if ((con = ast_context_find("app_dial_gosub_virtual_context")))
2007 ast_context_remove_extension2(con, "s", 1, NULL);
2008 ast_context_destroy(con, "app_dial"); /* leave nothing behind */
2014 static int load_module(void)
2017 struct ast_context *con;
2019 con = ast_context_find("app_dial_gosub_virtual_context");
2021 con = ast_context_create(NULL, "app_dial_gosub_virtual_context", "app_dial");
2023 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
2025 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_dial");
2027 res = ast_register_application(app, dial_exec, synopsis, descrip);
2028 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
2033 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");