Creating tag for the release of asterisk-1.6.1-beta1
[asterisk-bristuff.git] / apps / app_dial.c
blob6a1022a7f0ab6da786ff032571ef51b656ebec61
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 <sys/time.h>
38 #include <sys/signal.h>
39 #include <sys/stat.h>
40 #include <netinet/in.h>
42 #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
43 #include "asterisk/lock.h"
44 #include "asterisk/file.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/module.h"
48 #include "asterisk/translate.h"
49 #include "asterisk/say.h"
50 #include "asterisk/config.h"
51 #include "asterisk/features.h"
52 #include "asterisk/musiconhold.h"
53 #include "asterisk/callerid.h"
54 #include "asterisk/utils.h"
55 #include "asterisk/app.h"
56 #include "asterisk/causes.h"
57 #include "asterisk/rtp.h"
58 #include "asterisk/cdr.h"
59 #include "asterisk/manager.h"
60 #include "asterisk/privacy.h"
61 #include "asterisk/stringfields.h"
62 #include "asterisk/global_datastores.h"
63 #include "asterisk/dsp.h"
65 static char *app = "Dial";
67 static char *synopsis = "Place a call and connect to the current channel";
69 static char *descrip =
70 " Dial(Technology/resource[&Tech2/resource2...][,timeout][,options][,URL]):\n"
71 "This application will place calls to one or more specified channels. As soon\n"
72 "as one of the requested channels answers, the originating channel will be\n"
73 "answered, if it has not already been answered. These two channels will then\n"
74 "be active in a bridged call. All other channels that were requested will then\n"
75 "be hung up.\n"
76 " Unless there is a timeout specified, the Dial application will wait\n"
77 "indefinitely until one of the called channels answers, the user hangs up, or\n"
78 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
79 "continue if no requested channels can be called, or if the timeout expires.\n\n"
80 " This application sets the following channel variables upon completion:\n"
81 " DIALEDTIME - This is the time from dialing a channel until when it\n"
82 " is disconnected.\n"
83 " ANSWEREDTIME - This is the amount of time for actual call.\n"
84 " DIALSTATUS - This is the status of the call:\n"
85 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
86 " DONTCALL | TORTURE | INVALIDARGS\n"
87 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
88 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
89 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
90 "wants to send the caller to the 'torture' script.\n"
91 " This application will report normal termination if the originating channel\n"
92 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
93 "ends the call.\n"
94 " The optional URL will be sent to the called party if the channel supports it.\n"
95 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
96 "application will be put into that group (as in Set(GROUP()=...).\n"
97 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
98 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
99 "however, the variable will be unset after use.\n\n"
100 " Options:\n"
101 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
102 " C - Reset the CDR for this call.\n"
103 " c - If DIAL cancels this call, always set the flag to tell the channel\n"
104 " driver that the call is answered elsewhere.\n"
105 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
106 " a call to be answered. Exit to that extension if it exists in the\n"
107 " current context, or the context defined in the EXITCONTEXT variable,\n"
108 " if it exists.\n"
109 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
110 " party has answered, but before the call gets bridged. The 'called'\n"
111 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
112 " string is sent to the calling party. Both parameters can be used\n"
113 " alone.\n"
114 " e - execute the 'h' extension for peer after the call ends\n"
115 " f - Force the callerid of the *calling* channel to be set as the\n"
116 " extension associated with the channel using a dialplan 'hint'.\n"
117 " For example, some PSTNs do not allow CallerID to be set to anything\n"
118 " other than the number assigned to the caller.\n"
119 " F(context^exten^pri) - When the caller hangs up, transfer the called party\n"
120 " to the specified context and extension and continue execution.\n"
121 " g - Proceed with dialplan execution at the current extension if the\n"
122 " destination channel hangs up.\n"
123 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
124 " the specified priority and the called party to the specified priority+1.\n"
125 " Optionally, an extension, or extension and context may be specified. \n"
126 " Otherwise, the current extension is used. You cannot use any additional\n"
127 " action post answer options in conjunction with this option.\n"
128 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
129 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
130 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
131 " dial attempt.\n"
132 " k - Allow the called party to enable parking of the call by sending\n"
133 " the DTMF sequence defined for call parking in features.conf.\n"
134 " K - Allow the calling party to enable parking of the call by sending\n"
135 " the DTMF sequence defined for call parking in features.conf.\n"
136 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
137 " left. Repeat the warning every 'z' ms. The following special\n"
138 " variables can be used with this option:\n"
139 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
140 " Play sounds to the caller.\n"
141 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
142 " Play sounds to the callee.\n"
143 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
144 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
145 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
146 " The default is to say the time remaining.\n"
147 " m([class]) - Provide hold music to the calling party until a requested\n"
148 " channel answers. A specific MusicOnHold class can be\n"
149 " specified.\n"
150 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
151 " to the calling channel. Arguments can be specified to the Macro\n"
152 " using '^' as a delimiter. The Macro can set the variable\n"
153 " MACRO_RESULT to specify the following actions after the Macro is\n"
154 " finished executing.\n"
155 " * ABORT Hangup both legs of the call.\n"
156 " * CONGESTION Behave as if line congestion was encountered.\n"
157 " * BUSY Behave as if a busy signal was encountered.\n"
158 " * CONTINUE Hangup the called party and allow the calling party\n"
159 " to continue dialplan execution at the next priority.\n"
160 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
161 " specified priority. Optionally, an extension, or\n"
162 " extension and priority can be specified.\n"
163 " You cannot use any additional action post answer options in conjunction\n"
164 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
165 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
166 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
167 " that no introductions are to be saved in the priv-callerintros\n"
168 " directory.\n"
169 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
170 " that if callerID is present, do not screen the call.\n"
171 " o - Specify that the CallerID that was present on the *calling* channel\n"
172 " be set as the CallerID on the *called* channel. This was the\n"
173 " behavior of Asterisk 1.0 and earlier.\n"
174 " O([x]) - \"Operator Services\" mode (DAHDI channel to DAHDI channel\n"
175 " only, if specified on non-DAHDI interface, it will be ignored).\n"
176 " When the destination answers (presumably an operator services\n"
177 " station), the originator no longer has control of their line.\n"
178 " They may hang up, but the switch will not release their line\n"
179 " until the destination party hangs up (the operator). Specified\n"
180 " without an arg, or with 1 as an arg, the originator hanging up\n"
181 " will cause the phone to ring back immediately. With a 2 specified,\n"
182 " when the \"operator\" flashes the trunk, it will ring their phone\n"
183 " back.\n"
184 " p - This option enables screening mode. This is basically Privacy mode\n"
185 " without memory.\n"
186 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
187 " it is provided. The current extension is used if a database\n"
188 " family/key is not specified.\n"
189 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
190 " party until the called channel has answered.\n"
191 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
192 " answered the call.\n"
193 " t - Allow the called party to transfer the calling party by sending the\n"
194 " DTMF sequence defined in features.conf.\n"
195 " T - Allow the calling party to transfer the called party by sending the\n"
196 " DTMF sequence defined in features.conf.\n"
197 " U(x[^arg]) - Execute via Gosub the routine 'x' for the *called* channel before connecting\n"
198 " to the calling channel. Arguments can be specified to the Gosub\n"
199 " using '^' as a delimiter. The Gosub routine can set the variable\n"
200 " GOSUB_RESULT to specify the following actions after the Gosub returns.\n"
201 " * ABORT Hangup both legs of the call.\n"
202 " * CONGESTION Behave as if line congestion was encountered.\n"
203 " * BUSY Behave as if a busy signal was encountered.\n"
204 " * CONTINUE Hangup the called party and allow the calling party\n"
205 " to continue dialplan execution at the next priority.\n"
206 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
207 " specified priority. Optionally, an extension, or\n"
208 " extension and priority can be specified.\n"
209 " You cannot use any additional action post answer options in conjunction\n"
210 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
211 " so you will not be able to set timeouts via the TIMEOUT() function in this routine.\n"
212 " w - Allow the called party to enable recording of the call by sending\n"
213 " the DTMF sequence defined for one-touch recording in features.conf.\n"
214 " W - Allow the calling party to enable recording of the call by sending\n"
215 " the DTMF sequence defined for one-touch recording in features.conf.\n"
216 " x - Allow the called party to enable recording of the call by sending\n"
217 " the DTMF sequence defined for one-touch automixmonitor in features.conf\n"
218 " X - Allow the calling party to enable recording of the call by sending\n"
219 " the DTMF sequence defined for one-touch automixmonitor in features.conf\n";
221 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
222 static char *rapp = "RetryDial";
223 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
224 static char *rdescrip =
225 " RetryDial(announce,sleep,retries,dialargs): This application will attempt to\n"
226 "place a call using the normal Dial application. If no channel can be reached,\n"
227 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
228 "seconds before retrying the call. After 'retries' number of attempts, the\n"
229 "calling channel will continue at the next priority in the dialplan. If the\n"
230 "'retries' setting is set to 0, this application will retry endlessly.\n"
231 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
232 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
233 "one, The call will jump to that extension immediately.\n"
234 " The 'dialargs' are specified in the same format that arguments are provided\n"
235 "to the Dial application.\n";
237 enum {
238 OPT_ANNOUNCE = (1 << 0),
239 OPT_RESETCDR = (1 << 1),
240 OPT_DTMF_EXIT = (1 << 2),
241 OPT_SENDDTMF = (1 << 3),
242 OPT_FORCECLID = (1 << 4),
243 OPT_GO_ON = (1 << 5),
244 OPT_CALLEE_HANGUP = (1 << 6),
245 OPT_CALLER_HANGUP = (1 << 7),
246 OPT_DURATION_LIMIT = (1 << 9),
247 OPT_MUSICBACK = (1 << 10),
248 OPT_CALLEE_MACRO = (1 << 11),
249 OPT_SCREEN_NOINTRO = (1 << 12),
250 OPT_SCREEN_NOCLID = (1 << 13),
251 OPT_ORIGINAL_CLID = (1 << 14),
252 OPT_SCREENING = (1 << 15),
253 OPT_PRIVACY = (1 << 16),
254 OPT_RINGBACK = (1 << 17),
255 OPT_DURATION_STOP = (1 << 18),
256 OPT_CALLEE_TRANSFER = (1 << 19),
257 OPT_CALLER_TRANSFER = (1 << 20),
258 OPT_CALLEE_MONITOR = (1 << 21),
259 OPT_CALLER_MONITOR = (1 << 22),
260 OPT_GOTO = (1 << 23),
261 OPT_OPERMODE = (1 << 24),
262 OPT_CALLEE_PARK = (1 << 25),
263 OPT_CALLER_PARK = (1 << 26),
264 OPT_IGNORE_FORWARDING = (1 << 27),
265 OPT_CALLEE_GOSUB = (1 << 28),
266 OPT_CALLEE_MIXMONITOR = (1 << 29),
267 OPT_CALLER_MIXMONITOR = (1 << 30),
270 #define DIAL_STILLGOING (1 << 31)
271 #define DIAL_NOFORWARDHTML ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
272 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 33)
273 #define OPT_PEER_H ((uint64_t)1 << 34)
274 #define OPT_CALLEE_GO_ON ((uint64_t)1 << 35)
276 enum {
277 OPT_ARG_ANNOUNCE = 0,
278 OPT_ARG_SENDDTMF,
279 OPT_ARG_GOTO,
280 OPT_ARG_DURATION_LIMIT,
281 OPT_ARG_MUSICBACK,
282 OPT_ARG_CALLEE_MACRO,
283 OPT_ARG_CALLEE_GOSUB,
284 OPT_ARG_CALLEE_GO_ON,
285 OPT_ARG_PRIVACY,
286 OPT_ARG_DURATION_STOP,
287 OPT_ARG_OPERMODE,
288 /* note: this entry _MUST_ be the last one in the enum */
289 OPT_ARG_ARRAY_SIZE,
292 AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
293 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
294 AST_APP_OPTION('C', OPT_RESETCDR),
295 AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
296 AST_APP_OPTION('d', OPT_DTMF_EXIT),
297 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
298 AST_APP_OPTION('e', OPT_PEER_H),
299 AST_APP_OPTION('f', OPT_FORCECLID),
300 AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
301 AST_APP_OPTION('g', OPT_GO_ON),
302 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
303 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
304 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
305 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
306 AST_APP_OPTION('k', OPT_CALLEE_PARK),
307 AST_APP_OPTION('K', OPT_CALLER_PARK),
308 AST_APP_OPTION('k', OPT_CALLEE_PARK),
309 AST_APP_OPTION('K', OPT_CALLER_PARK),
310 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
311 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
312 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
313 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
314 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
315 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
316 AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
317 AST_APP_OPTION('p', OPT_SCREENING),
318 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
319 AST_APP_OPTION('r', OPT_RINGBACK),
320 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
321 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
322 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
323 AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
324 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
325 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
326 AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
327 AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
328 END_OPTIONS );
330 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
331 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
332 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK) && \
333 !chan->audiohooks && !peer->audiohooks)
336 * The list of active channels
338 struct chanlist {
339 struct chanlist *next;
340 struct ast_channel *chan;
341 uint64_t flags;
345 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
347 /* Hang up a tree of stuff */
348 struct chanlist *oo;
349 while (outgoing) {
350 /* Hangup any existing lines we have open */
351 if (outgoing->chan && (outgoing->chan != exception)) {
352 if (answered_elsewhere)
353 ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
354 ast_hangup(outgoing->chan);
356 oo = outgoing;
357 outgoing = outgoing->next;
358 ast_free(oo);
362 #define AST_MAX_WATCHERS 256
365 * argument to handle_cause() and other functions.
367 struct cause_args {
368 struct ast_channel *chan;
369 int busy;
370 int congestion;
371 int nochan;
374 static void handle_cause(int cause, struct cause_args *num)
376 struct ast_cdr *cdr = num->chan->cdr;
378 switch(cause) {
379 case AST_CAUSE_BUSY:
380 if (cdr)
381 ast_cdr_busy(cdr);
382 num->busy++;
383 break;
385 case AST_CAUSE_CONGESTION:
386 if (cdr)
387 ast_cdr_failed(cdr);
388 num->congestion++;
389 break;
391 case AST_CAUSE_NO_ROUTE_DESTINATION:
392 case AST_CAUSE_UNREGISTERED:
393 if (cdr)
394 ast_cdr_failed(cdr);
395 num->nochan++;
396 break;
398 case AST_CAUSE_NORMAL_CLEARING:
399 break;
401 default:
402 num->nochan++;
403 break;
407 /* free the buffer if allocated, and set the pointer to the second arg */
408 #define S_REPLACE(s, new_val) \
409 do { \
410 if (s) \
411 ast_free(s); \
412 s = (new_val); \
413 } while (0)
415 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
417 char rexten[2] = { exten, '\0' };
419 if (context) {
420 if (!ast_goto_if_exists(chan, context, rexten, pri))
421 return 1;
422 } else {
423 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
424 return 1;
425 else if (!ast_strlen_zero(chan->macrocontext)) {
426 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
427 return 1;
430 return 0;
434 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
436 const char *context = S_OR(chan->macrocontext, chan->context);
437 const char *exten = S_OR(chan->macroexten, chan->exten);
439 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
442 static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
444 manager_event(EVENT_FLAG_CALL, "Dial",
445 "SubEvent: Begin\r\n"
446 "Channel: %s\r\n"
447 "Destination: %s\r\n"
448 "CallerIDNum: %s\r\n"
449 "CallerIDName: %s\r\n"
450 "UniqueID: %s\r\n"
451 "DestUniqueID: %s\r\n"
452 "Dialstring: %s\r\n",
453 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
454 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
455 dst->uniqueid, dialstring ? dialstring : "");
458 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
460 manager_event(EVENT_FLAG_CALL, "Dial",
461 "SubEvent: End\r\n"
462 "Channel: %s\r\n"
463 "UniqueID: %s\r\n"
464 "DialStatus: %s\r\n",
465 src->name, src->uniqueid, dialstatus);
469 * helper function for wait_for_answer()
471 * XXX this code is highly suspicious, as it essentially overwrites
472 * the outgoing channel without properly deleting it.
474 static void do_forward(struct chanlist *o,
475 struct cause_args *num, struct ast_flags64 *peerflags, int single)
477 char tmpchan[256];
478 struct ast_channel *original = o->chan;
479 struct ast_channel *c = o->chan; /* the winner */
480 struct ast_channel *in = num->chan; /* the input channel */
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;
491 ast_channel_lock(c);
492 forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
493 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
494 ast_channel_unlock(c);
495 stuff = tmpchan;
496 tech = "Local";
498 /* Before processing channel, go ahead and check for forwarding */
499 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
500 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
501 if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
502 ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
503 c = o->chan = NULL;
504 cause = AST_CAUSE_BUSY;
505 } else {
506 /* Setup parameters */
507 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
508 if (c) {
509 if (single)
510 ast_channel_make_compatible(o->chan, in);
511 ast_channel_inherit_variables(in, o->chan);
512 ast_channel_datastore_inherit(in, o->chan);
513 } else
514 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
516 if (!c) {
517 ast_clear_flag64(o, DIAL_STILLGOING);
518 handle_cause(cause, num);
519 } else {
520 char *new_cid_num, *new_cid_name;
521 struct ast_channel *src;
523 ast_rtp_make_compatible(c, in, single);
524 if (ast_test_flag64(o, OPT_FORCECLID)) {
525 new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
526 new_cid_name = NULL; /* XXX no name ? */
527 src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
528 } else {
529 new_cid_num = ast_strdup(in->cid.cid_num);
530 new_cid_name = ast_strdup(in->cid.cid_name);
531 src = in;
533 ast_string_field_set(c, accountcode, src->accountcode);
534 c->cdrflags = src->cdrflags;
535 S_REPLACE(c->cid.cid_num, new_cid_num);
536 S_REPLACE(c->cid.cid_name, new_cid_name);
538 if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
539 S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
541 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
542 if (ast_call(c, tmpchan, 0)) {
543 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
544 ast_clear_flag64(o, DIAL_STILLGOING);
545 ast_hangup(original);
546 c = o->chan = NULL;
547 num->nochan++;
548 } else {
549 senddialevent(in, c, stuff);
550 /* After calling, set callerid to extension */
551 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
552 char cidname[AST_MAX_EXTENSION] = "";
553 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
555 /* Hangup the original channel now, in case we needed it */
556 ast_hangup(original);
561 /* argument used for some functions. */
562 struct privacy_args {
563 int sentringing;
564 int privdb_val;
565 char privcid[256];
566 char privintro[1024];
567 char status[256];
570 static struct ast_channel *wait_for_answer(struct ast_channel *in,
571 struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
572 struct privacy_args *pa,
573 const struct cause_args *num_in, int *result)
575 struct cause_args num = *num_in;
576 int prestart = num.busy + num.congestion + num.nochan;
577 int orig = *to;
578 struct ast_channel *peer = NULL;
579 /* single is set if only one destination is enabled */
580 int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
581 #ifdef HAVE_EPOLL
582 struct chanlist *epollo;
583 #endif
585 if (single) {
586 /* Turn off hold music, etc */
587 ast_deactivate_generator(in);
588 /* If we are calling a single channel, make them compatible for in-band tone purpose */
589 ast_channel_make_compatible(outgoing->chan, in);
592 #ifdef HAVE_EPOLL
593 for (epollo = outgoing; epollo; epollo = epollo->next)
594 ast_poll_channel_add(in, epollo->chan);
595 #endif
597 while (*to && !peer) {
598 struct chanlist *o;
599 int pos = 0; /* how many channels do we handle */
600 int numlines = prestart;
601 struct ast_channel *winner;
602 struct ast_channel *watchers[AST_MAX_WATCHERS];
604 watchers[pos++] = in;
605 for (o = outgoing; o; o = o->next) {
606 /* Keep track of important channels */
607 if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
608 watchers[pos++] = o->chan;
609 numlines++;
611 if (pos == 1) { /* only the input channel is available */
612 if (numlines == (num.busy + num.congestion + num.nochan)) {
613 ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
614 if (num.busy)
615 strcpy(pa->status, "BUSY");
616 else if (num.congestion)
617 strcpy(pa->status, "CONGESTION");
618 else if (num.nochan)
619 strcpy(pa->status, "CHANUNAVAIL");
620 } else {
621 ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
623 *to = 0;
624 return NULL;
626 winner = ast_waitfor_n(watchers, pos, to);
627 for (o = outgoing; o; o = o->next) {
628 struct ast_frame *f;
629 struct ast_channel *c = o->chan;
631 if (c == NULL)
632 continue;
633 if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
634 if (!peer) {
635 ast_verb(3, "%s answered %s\n", c->name, in->name);
636 peer = c;
637 ast_copy_flags64(peerflags, o,
638 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
639 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
640 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
641 OPT_CALLEE_PARK | OPT_CALLER_PARK |
642 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
643 DIAL_NOFORWARDHTML);
644 ast_string_field_set(c, dialcontext, "");
645 ast_copy_string(c->exten, "", sizeof(c->exten));
647 continue;
649 if (c != winner)
650 continue;
651 /* here, o->chan == c == winner */
652 if (!ast_strlen_zero(c->call_forward)) {
653 do_forward(o, &num, peerflags, single);
654 continue;
656 f = ast_read(winner);
657 if (!f) {
658 in->hangupcause = c->hangupcause;
659 #ifdef HAVE_EPOLL
660 ast_poll_channel_del(in, c);
661 #endif
662 ast_hangup(c);
663 c = o->chan = NULL;
664 ast_clear_flag64(o, DIAL_STILLGOING);
665 handle_cause(in->hangupcause, &num);
666 continue;
668 if (f->frametype == AST_FRAME_CONTROL) {
669 switch(f->subclass) {
670 case AST_CONTROL_ANSWER:
671 /* This is our guy if someone answered. */
672 if (!peer) {
673 ast_verb(3, "%s answered %s\n", c->name, in->name);
674 peer = c;
675 if (peer->cdr) {
676 peer->cdr->answer = ast_tvnow();
677 peer->cdr->disposition = AST_CDR_ANSWERED;
679 ast_copy_flags64(peerflags, o,
680 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
681 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
682 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
683 OPT_CALLEE_PARK | OPT_CALLER_PARK |
684 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
685 DIAL_NOFORWARDHTML);
686 ast_string_field_set(c, dialcontext, "");
687 ast_copy_string(c->exten, "", sizeof(c->exten));
688 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
689 /* Setup early bridge if appropriate */
690 ast_channel_early_bridge(in, peer);
692 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
693 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
694 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
695 break;
696 case AST_CONTROL_BUSY:
697 ast_verb(3, "%s is busy\n", c->name);
698 in->hangupcause = c->hangupcause;
699 ast_hangup(c);
700 c = o->chan = NULL;
701 ast_clear_flag64(o, DIAL_STILLGOING);
702 handle_cause(AST_CAUSE_BUSY, &num);
703 break;
704 case AST_CONTROL_CONGESTION:
705 ast_verb(3, "%s is circuit-busy\n", c->name);
706 in->hangupcause = c->hangupcause;
707 ast_hangup(c);
708 c = o->chan = NULL;
709 ast_clear_flag64(o, DIAL_STILLGOING);
710 handle_cause(AST_CAUSE_CONGESTION, &num);
711 break;
712 case AST_CONTROL_RINGING:
713 ast_verb(3, "%s is ringing\n", c->name);
714 /* Setup early media if appropriate */
715 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
716 ast_channel_early_bridge(in, c);
717 if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
718 ast_indicate(in, AST_CONTROL_RINGING);
719 pa->sentringing++;
721 break;
722 case AST_CONTROL_PROGRESS:
723 ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
724 /* Setup early media if appropriate */
725 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
726 ast_channel_early_bridge(in, c);
727 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
728 ast_indicate(in, AST_CONTROL_PROGRESS);
729 break;
730 case AST_CONTROL_VIDUPDATE:
731 ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
732 ast_indicate(in, AST_CONTROL_VIDUPDATE);
733 break;
734 case AST_CONTROL_SRCUPDATE:
735 ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
736 ast_indicate(in, AST_CONTROL_SRCUPDATE);
737 break;
738 case AST_CONTROL_PROCEEDING:
739 ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
740 if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
741 ast_channel_early_bridge(in, c);
742 if (!ast_test_flag64(outgoing, OPT_RINGBACK))
743 ast_indicate(in, AST_CONTROL_PROCEEDING);
744 break;
745 case AST_CONTROL_HOLD:
746 ast_verb(3, "Call on %s placed on hold\n", c->name);
747 ast_indicate(in, AST_CONTROL_HOLD);
748 break;
749 case AST_CONTROL_UNHOLD:
750 ast_verb(3, "Call on %s left from hold\n", c->name);
751 ast_indicate(in, AST_CONTROL_UNHOLD);
752 break;
753 case AST_CONTROL_OFFHOOK:
754 case AST_CONTROL_FLASH:
755 /* Ignore going off hook and flash */
756 break;
757 case -1:
758 if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
759 ast_verb(3, "%s stopped sounds\n", c->name);
760 ast_indicate(in, -1);
761 pa->sentringing = 0;
763 break;
764 default:
765 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
767 } else if (single) {
768 switch (f->frametype) {
769 case AST_FRAME_VOICE:
770 case AST_FRAME_IMAGE:
771 case AST_FRAME_TEXT:
772 if (ast_write(in, f)) {
773 ast_log(LOG_WARNING, "Unable to write frame\n");
775 break;
776 case AST_FRAME_HTML:
777 if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass, f->data.ptr, f->datalen) == -1) {
778 ast_log(LOG_WARNING, "Unable to send URL\n");
780 break;
781 default:
782 break;
785 ast_frfree(f);
786 } /* end for */
787 if (winner == in) {
788 struct ast_frame *f = ast_read(in);
789 #if 0
790 if (f && (f->frametype != AST_FRAME_VOICE))
791 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
792 else if (!f || (f->frametype != AST_FRAME_VOICE))
793 printf("Hangup received on %s\n", in->name);
794 #endif
795 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
796 /* Got hung up */
797 *to = -1;
798 strcpy(pa->status, "CANCEL");
799 ast_cdr_noanswer(in->cdr);
800 if (f) {
801 if (f->data.uint32) {
802 in->hangupcause = f->data.uint32;
804 ast_frfree(f);
806 return NULL;
809 /* now f is guaranteed non-NULL */
810 if (f->frametype == AST_FRAME_DTMF) {
811 if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
812 const char *context;
813 ast_channel_lock(in);
814 context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
815 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
816 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
817 *to = 0;
818 ast_cdr_noanswer(in->cdr);
819 *result = f->subclass;
820 strcpy(pa->status, "CANCEL");
821 ast_frfree(f);
822 ast_channel_unlock(in);
823 return NULL;
825 ast_channel_unlock(in);
828 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
829 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
830 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
831 *to = 0;
832 strcpy(pa->status, "CANCEL");
833 ast_cdr_noanswer(in->cdr);
834 ast_frfree(f);
835 return NULL;
839 /* Forward HTML stuff */
840 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
841 if (ast_channel_sendhtml(outgoing->chan, f->subclass, f->data.ptr, f->datalen) == -1)
842 ast_log(LOG_WARNING, "Unable to send URL\n");
844 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
845 if (ast_write(outgoing->chan, f))
846 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
848 if (single && (f->frametype == AST_FRAME_CONTROL) &&
849 ((f->subclass == AST_CONTROL_HOLD) ||
850 (f->subclass == AST_CONTROL_UNHOLD) ||
851 (f->subclass == AST_CONTROL_VIDUPDATE) ||
852 (f->subclass == AST_CONTROL_SRCUPDATE))) {
853 ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
854 ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
856 ast_frfree(f);
858 if (!*to)
859 ast_verb(3, "Nobody picked up in %d ms\n", orig);
860 if (!*to || ast_check_hangup(in))
861 ast_cdr_noanswer(in->cdr);
864 #ifdef HAVE_EPOLL
865 for (epollo = outgoing; epollo; epollo = epollo->next) {
866 if (epollo->chan)
867 ast_poll_channel_del(in, epollo->chan);
869 #endif
871 return peer;
874 static void replace_macro_delimiter(char *s)
876 for (; *s; s++)
877 if (*s == '^')
878 *s = ',';
881 /* returns true if there is a valid privacy reply */
882 static int valid_priv_reply(struct ast_flags64 *opts, int res)
884 if (res < '1')
885 return 0;
886 if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
887 return 1;
888 if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
889 return 1;
890 return 0;
893 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
894 char *parse, unsigned int *calldurationlimit)
896 char *stringp = ast_strdupa(parse);
897 char *limit_str, *warning_str, *warnfreq_str;
898 const char *var;
899 int play_to_caller = 0, play_to_callee = 0;
900 int delta;
902 limit_str = strsep(&stringp, ":");
903 warning_str = strsep(&stringp, ":");
904 warnfreq_str = strsep(&stringp, ":");
906 config->timelimit = atol(limit_str);
907 if (warning_str)
908 config->play_warning = atol(warning_str);
909 if (warnfreq_str)
910 config->warning_freq = atol(warnfreq_str);
912 if (!config->timelimit) {
913 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
914 config->timelimit = config->play_warning = config->warning_freq = 0;
915 config->warning_sound = NULL;
916 return -1; /* error */
917 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
918 int w = config->warning_freq;
920 /* If the first warning is requested _after_ the entire call would end,
921 and no warning frequency is requested, then turn off the warning. If
922 a warning frequency is requested, reduce the 'first warning' time by
923 that frequency until it falls within the call's total time limit.
924 Graphically:
925 timelim->| delta |<-playwarning
926 0__________________|_________________|
927 | w | | | |
929 so the number of intervals to cut is 1+(delta-1)/w
932 if (w == 0) {
933 config->play_warning = 0;
934 } else {
935 config->play_warning -= w * ( 1 + (delta-1)/w );
936 if (config->play_warning < 1)
937 config->play_warning = config->warning_freq = 0;
941 ast_channel_lock(chan);
943 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
945 play_to_caller = var ? ast_true(var) : 1;
947 var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
948 play_to_callee = var ? ast_true(var) : 0;
950 if (!play_to_caller && !play_to_callee)
951 play_to_caller = 1;
953 var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
954 config->warning_sound = !ast_strlen_zero(var) ? ast_strdupa(var) : "timeleft";
956 /* The code looking at config wants a NULL, not just "", to decide
957 * that the message should not be played, so we replace "" with NULL.
958 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
959 * not found.
962 var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
963 config->end_sound = !ast_strlen_zero(var) ? ast_strdupa(var) : NULL;
965 var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
966 config->start_sound = !ast_strlen_zero(var) ? ast_strdupa(var) : NULL;
968 ast_channel_unlock(chan);
970 /* undo effect of S(x) in case they are both used */
971 *calldurationlimit = 0;
972 /* more efficient to do it like S(x) does since no advanced opts */
973 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
974 *calldurationlimit = config->timelimit / 1000;
975 ast_verb(3, "Setting call duration limit to %d seconds.\n",
976 *calldurationlimit);
977 config->timelimit = play_to_caller = play_to_callee =
978 config->play_warning = config->warning_freq = 0;
979 } else {
980 ast_verb(3, "Limit Data for this call:\n");
981 ast_verb(4, "timelimit = %ld\n", config->timelimit);
982 ast_verb(4, "play_warning = %ld\n", config->play_warning);
983 ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
984 ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
985 ast_verb(4, "warning_freq = %ld\n", config->warning_freq);
986 ast_verb(4, "start_sound = %s\n", S_OR(config->start_sound, ""));
987 ast_verb(4, "warning_sound = %s\n", config->warning_sound);
988 ast_verb(4, "end_sound = %s\n", S_OR(config->end_sound, ""));
990 if (play_to_caller)
991 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
992 if (play_to_callee)
993 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
994 return 0;
997 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
998 struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
1001 int res2;
1002 int loopcount = 0;
1004 /* Get the user's intro, store it in priv-callerintros/$CID,
1005 unless it is already there-- this should be done before the
1006 call is actually dialed */
1008 /* all ring indications and moh for the caller has been halted as soon as the
1009 target extension was picked up. We are going to have to kill some
1010 time and make the caller believe the peer hasn't picked up yet */
1012 if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1013 char *original_moh = ast_strdupa(chan->musicclass);
1014 ast_indicate(chan, -1);
1015 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1016 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1017 ast_string_field_set(chan, musicclass, original_moh);
1018 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1019 ast_indicate(chan, AST_CONTROL_RINGING);
1020 pa->sentringing++;
1023 /* Start autoservice on the other chan ?? */
1024 res2 = ast_autoservice_start(chan);
1025 /* Now Stream the File */
1026 for (loopcount = 0; loopcount < 3; loopcount++) {
1027 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1028 break;
1029 if (!res2) /* on timeout, play the message again */
1030 res2 = ast_play_and_wait(peer, "priv-callpending");
1031 if (!valid_priv_reply(opts, res2))
1032 res2 = 0;
1033 /* priv-callpending script:
1034 "I have a caller waiting, who introduces themselves as:"
1036 if (!res2)
1037 res2 = ast_play_and_wait(peer, pa->privintro);
1038 if (!valid_priv_reply(opts, res2))
1039 res2 = 0;
1040 /* now get input from the called party, as to their choice */
1041 if (!res2) {
1042 /* XXX can we have both, or they are mutually exclusive ? */
1043 if (ast_test_flag64(opts, OPT_PRIVACY))
1044 res2 = ast_play_and_wait(peer, "priv-callee-options");
1045 if (ast_test_flag64(opts, OPT_SCREENING))
1046 res2 = ast_play_and_wait(peer, "screen-callee-options");
1048 /*! \page DialPrivacy Dial Privacy scripts
1049 \par priv-callee-options script:
1050 "Dial 1 if you wish this caller to reach you directly in the future,
1051 and immediately connect to their incoming call
1052 Dial 2 if you wish to send this caller to voicemail now and
1053 forevermore.
1054 Dial 3 to send this caller to the torture menus, now and forevermore.
1055 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1056 Dial 5 to allow this caller to come straight thru to you in the future,
1057 but right now, just this once, send them to voicemail."
1058 \par screen-callee-options script:
1059 "Dial 1 if you wish to immediately connect to the incoming call
1060 Dial 2 if you wish to send this caller to voicemail.
1061 Dial 3 to send this caller to the torture menus.
1062 Dial 4 to send this caller to a simple "go away" menu.
1064 if (valid_priv_reply(opts, res2))
1065 break;
1066 /* invalid option */
1067 res2 = ast_play_and_wait(peer, "vm-sorry");
1070 if (ast_test_flag64(opts, OPT_MUSICBACK)) {
1071 ast_moh_stop(chan);
1072 } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1073 ast_indicate(chan, -1);
1074 pa->sentringing = 0;
1076 ast_autoservice_stop(chan);
1077 if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1078 /* map keypresses to various things, the index is res2 - '1' */
1079 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1080 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1081 int i = res2 - '1';
1082 ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
1083 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1084 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1086 switch (res2) {
1087 case '1':
1088 break;
1089 case '2':
1090 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1091 break;
1092 case '3':
1093 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1094 break;
1095 case '4':
1096 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1097 break;
1098 case '5':
1099 /* XXX should we set status to DENY ? */
1100 if (ast_test_flag64(opts, OPT_PRIVACY))
1101 break;
1102 /* if not privacy, then 5 is the same as "default" case */
1103 default: /* bad input or -1 if failure to start autoservice */
1104 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1105 /* well, there seems basically two choices. Just patch the caller thru immediately,
1106 or,... put 'em thru to voicemail. */
1107 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1108 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1109 /* XXX should we set status to DENY ? */
1110 /* XXX what about the privacy flags ? */
1111 break;
1114 if (res2 == '1') { /* the only case where we actually connect */
1115 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1116 just clog things up, and it's not useful information, not being tied to a CID */
1117 if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
1118 ast_filedelete(pa->privintro, NULL);
1119 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1120 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1121 else
1122 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1124 return 0; /* the good exit path */
1125 } else {
1126 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1127 return -1;
1131 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1132 static int setup_privacy_args(struct privacy_args *pa,
1133 struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
1135 char callerid[60];
1136 int res;
1137 char *l;
1138 int silencethreshold;
1140 if (!ast_strlen_zero(chan->cid.cid_num)) {
1141 l = ast_strdupa(chan->cid.cid_num);
1142 ast_shrink_phone_number(l);
1143 if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1144 ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
1145 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1146 } else {
1147 ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1148 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1150 } else {
1151 char *tnam, *tn2;
1153 tnam = ast_strdupa(chan->name);
1154 /* clean the channel name so slashes don't try to end up in disk file name */
1155 for (tn2 = tnam; *tn2; tn2++) {
1156 if (*tn2 == '/') /* any other chars to be afraid of? */
1157 *tn2 = '=';
1159 ast_verb(3, "Privacy-- callerid is empty\n");
1161 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1162 l = callerid;
1163 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1166 ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
1168 if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID)) {
1169 /* if callerid is set and OPT_SCREEN_NOCLID is set also */
1170 ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1171 pa->privdb_val = AST_PRIVACY_ALLOW;
1172 } else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
1173 ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1176 if (pa->privdb_val == AST_PRIVACY_DENY) {
1177 ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1178 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1179 return 0;
1180 } else if (pa->privdb_val == AST_PRIVACY_KILL) {
1181 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1182 return 0; /* Is this right? */
1183 } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
1184 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1185 return 0; /* is this right??? */
1186 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
1187 /* Get the user's intro, store it in priv-callerintros/$CID,
1188 unless it is already there-- this should be done before the
1189 call is actually dialed */
1191 /* make sure the priv-callerintros dir actually exists */
1192 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1193 if ((res = ast_mkdir(pa->privintro, 0755))) {
1194 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1195 return -1;
1198 snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1199 if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1200 /* the DELUX version of this code would allow this caller the
1201 option to hear and retape their previously recorded intro.
1203 } else {
1204 int duration; /* for feedback from play_and_wait */
1205 /* the file doesn't exist yet. Let the caller submit his
1206 vocal intro for posterity */
1207 /* priv-recordintro script:
1209 "At the tone, please say your name:"
1212 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
1213 ast_answer(chan);
1214 res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1215 /* don't think we'll need a lock removed, we took care of
1216 conflicts by naming the pa.privintro file */
1217 if (res == -1) {
1218 /* Delete the file regardless since they hung up during recording */
1219 ast_filedelete(pa->privintro, NULL);
1220 if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1221 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1222 else
1223 ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1224 return -1;
1226 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1227 ast_waitstream(chan, "");
1230 return 1; /* success */
1233 static void set_dial_features(struct ast_flags64 *opts, struct ast_dial_features *features)
1235 struct ast_flags64 perm_opts = {.flags = 0};
1237 ast_copy_flags64(&perm_opts, opts,
1238 OPT_CALLER_TRANSFER | OPT_CALLER_PARK | OPT_CALLER_MONITOR | OPT_CALLER_MIXMONITOR | OPT_CALLER_HANGUP |
1239 OPT_CALLEE_TRANSFER | OPT_CALLEE_PARK | OPT_CALLEE_MONITOR | OPT_CALLEE_MIXMONITOR | OPT_CALLEE_HANGUP);
1241 memset(features->options, 0, sizeof(features->options));
1243 ast_app_options2str64(dial_exec_options, &perm_opts, features->options, sizeof(features->options));
1246 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
1248 int res = -1; /* default: error */
1249 char *rest, *cur; /* scan the list of destinations */
1250 struct chanlist *outgoing = NULL; /* list of destinations */
1251 struct ast_channel *peer;
1252 int to; /* timeout */
1253 struct cause_args num = { chan, 0, 0, 0 };
1254 int cause;
1255 char numsubst[256];
1256 char cidname[AST_MAX_EXTENSION] = "";
1258 struct ast_bridge_config config = { { 0, } };
1259 unsigned int calldurationlimit = 0;
1260 char *dtmfcalled = NULL, *dtmfcalling = NULL;
1261 struct privacy_args pa = {
1262 .sentringing = 0,
1263 .privdb_val = 0,
1264 .status = "INVALIDARGS",
1266 int sentringing = 0, moh = 0;
1267 const char *outbound_group = NULL;
1268 int result = 0;
1269 time_t start_time;
1270 char *parse;
1271 int opermode = 0;
1272 AST_DECLARE_APP_ARGS(args,
1273 AST_APP_ARG(peers);
1274 AST_APP_ARG(timeout);
1275 AST_APP_ARG(options);
1276 AST_APP_ARG(url);
1278 struct ast_flags64 opts = { 0, };
1279 char *opt_args[OPT_ARG_ARRAY_SIZE];
1280 struct ast_datastore *datastore = NULL;
1281 struct ast_datastore *ds_caller_features = NULL;
1282 struct ast_datastore *ds_callee_features = NULL;
1283 struct ast_dial_features *caller_features;
1284 int fulldial = 0, num_dialed = 0;
1286 if (ast_strlen_zero(data)) {
1287 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1288 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1289 return -1;
1292 parse = ast_strdupa(data);
1294 AST_STANDARD_APP_ARGS(args, parse);
1296 if (!ast_strlen_zero(args.options) &&
1297 ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
1298 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1299 goto done;
1302 if (ast_strlen_zero(args.peers)) {
1303 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1304 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1305 goto done;
1308 if (ast_test_flag64(&opts, OPT_OPERMODE)) {
1309 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1310 ast_verb(3, "Setting operator services mode to %d.\n", opermode);
1313 if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1314 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1315 if (!calldurationlimit) {
1316 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1317 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1318 goto done;
1320 ast_verb(3, "Setting call duration limit to %d seconds.\n", calldurationlimit);
1323 if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1324 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
1325 dtmfcalled = strsep(&dtmfcalling, ":");
1328 if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1329 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1330 goto done;
1333 if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
1334 ast_cdr_reset(chan->cdr, NULL);
1335 if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1336 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1338 if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
1339 res = setup_privacy_args(&pa, &opts, opt_args, chan);
1340 if (res <= 0)
1341 goto out;
1342 res = -1; /* reset default */
1345 if (continue_exec)
1346 *continue_exec = 0;
1348 /* If a channel group has been specified, get it for use when we create peer channels */
1350 ast_channel_lock(chan);
1351 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1352 outbound_group = ast_strdupa(outbound_group);
1353 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1354 } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
1355 outbound_group = ast_strdupa(outbound_group);
1357 ast_channel_unlock(chan);
1358 ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1360 /* Create datastore for channel dial features for caller */
1361 if (!(ds_caller_features = ast_datastore_alloc(&dial_features_info, NULL))) {
1362 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1363 goto out;
1366 if (!(caller_features = ast_malloc(sizeof(*caller_features)))) {
1367 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1368 goto out;
1371 ast_copy_flags(&(caller_features->features_callee), &(config.features_caller), AST_FLAGS_ALL);
1372 caller_features->is_caller = 1;
1373 set_dial_features(&opts, caller_features);
1375 ds_caller_features->inheritance = DATASTORE_INHERIT_FOREVER;
1376 ds_caller_features->data = caller_features;
1378 ast_channel_lock(chan);
1379 ast_channel_datastore_add(chan, ds_caller_features);
1380 ast_channel_unlock(chan);
1382 /* loop through the list of dial destinations */
1383 rest = args.peers;
1384 while ((cur = strsep(&rest, "&")) ) {
1385 struct chanlist *tmp;
1386 struct ast_channel *tc; /* channel for this destination */
1387 /* Get a technology/[device:]number pair */
1388 char *number = cur;
1389 char *interface = ast_strdupa(number);
1390 char *tech = strsep(&number, "/");
1391 /* find if we already dialed this interface */
1392 struct ast_dialed_interface *di;
1393 struct ast_dial_features *callee_features;
1394 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1395 num_dialed++;
1396 if (!number) {
1397 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1398 goto out;
1400 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1401 goto out;
1402 if (opts.flags) {
1403 ast_copy_flags64(tmp, &opts,
1404 OPT_CANCEL_ELSEWHERE |
1405 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1406 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1407 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1408 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1409 OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1410 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1411 ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
1413 ast_copy_string(numsubst, number, sizeof(numsubst));
1414 /* Request the peer */
1416 ast_channel_lock(chan);
1417 datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1418 ast_channel_unlock(chan);
1420 if (datastore)
1421 dialed_interfaces = datastore->data;
1422 else {
1423 if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
1424 ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1425 ast_free(tmp);
1426 goto out;
1429 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1431 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1432 ast_free(tmp);
1433 goto out;
1436 datastore->data = dialed_interfaces;
1437 AST_LIST_HEAD_INIT(dialed_interfaces);
1439 ast_channel_lock(chan);
1440 ast_channel_datastore_add(chan, datastore);
1441 ast_channel_unlock(chan);
1444 AST_LIST_LOCK(dialed_interfaces);
1445 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1446 if (!strcasecmp(di->interface, interface)) {
1447 ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1448 di->interface);
1449 break;
1452 AST_LIST_UNLOCK(dialed_interfaces);
1454 if (di) {
1455 fulldial++;
1456 ast_free(tmp);
1457 continue;
1460 /* It is always ok to dial a Local interface. We only keep track of
1461 * which "real" interfaces have been dialed. The Local channel will
1462 * inherit this list so that if it ends up dialing a real interface,
1463 * it won't call one that has already been called. */
1464 if (strcasecmp(tech, "Local")) {
1465 if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1466 AST_LIST_UNLOCK(dialed_interfaces);
1467 ast_free(tmp);
1468 goto out;
1470 strcpy(di->interface, interface);
1472 AST_LIST_LOCK(dialed_interfaces);
1473 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1474 AST_LIST_UNLOCK(dialed_interfaces);
1477 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
1478 if (!tc) {
1479 /* If we can't, just go on to the next call */
1480 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1481 tech, cause, ast_cause2str(cause));
1482 handle_cause(cause, &num);
1483 if (!rest) /* we are on the last destination */
1484 chan->hangupcause = cause;
1485 ast_free(tmp);
1486 continue;
1488 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1490 /* Setup outgoing SDP to match incoming one */
1491 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
1493 /* Inherit specially named variables from parent channel */
1494 ast_channel_inherit_variables(chan, tc);
1495 ast_channel_datastore_inherit(chan, tc);
1497 tc->appl = "AppDial";
1498 tc->data = "(Outgoing Line)";
1499 memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
1501 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
1502 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
1503 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
1504 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
1506 ast_string_field_set(tc, accountcode, chan->accountcode);
1507 tc->cdrflags = chan->cdrflags;
1508 if (ast_strlen_zero(tc->musicclass))
1509 ast_string_field_set(tc, musicclass, chan->musicclass);
1510 /* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
1511 tc->cid.cid_pres = chan->cid.cid_pres;
1512 tc->cid.cid_ton = chan->cid.cid_ton;
1513 tc->cid.cid_tns = chan->cid.cid_tns;
1514 tc->cid.cid_ani2 = chan->cid.cid_ani2;
1515 tc->adsicpe = chan->adsicpe;
1516 tc->transfercapability = chan->transfercapability;
1518 /* If we have an outbound group, set this peer channel to it */
1519 if (outbound_group)
1520 ast_app_group_set_channel(tc, outbound_group);
1522 /* Inherit context and extension */
1523 ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
1524 if (!ast_strlen_zero(chan->macroexten))
1525 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
1526 else
1527 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
1529 /* Save callee features */
1530 if (!(ds_callee_features = ast_datastore_alloc(&dial_features_info, NULL))) {
1531 ast_log(LOG_WARNING, "Unable to create channel datastore for dial features. Aborting!\n");
1532 ast_free(tmp);
1533 goto out;
1536 if (!(callee_features = ast_malloc(sizeof(*callee_features)))) {
1537 ast_log(LOG_WARNING, "Unable to allocate memory for feature flags. Aborting!\n");
1538 ast_free(tmp);
1539 goto out;
1542 ast_copy_flags(&(callee_features->features_callee), &(config.features_callee), AST_FLAGS_ALL);
1543 callee_features->is_caller = 0;
1544 set_dial_features(&opts, callee_features);
1546 ds_callee_features->inheritance = DATASTORE_INHERIT_FOREVER;
1547 ds_callee_features->data = callee_features;
1549 ast_channel_lock(chan);
1550 ast_channel_datastore_add(tc, ds_callee_features);
1551 ast_channel_unlock(chan);
1553 res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
1555 /* Save the info in cdr's that we called them */
1556 if (chan->cdr)
1557 ast_cdr_setdestchan(chan->cdr, tc->name);
1559 /* check the results of ast_call */
1560 if (res) {
1561 /* Again, keep going even if there's an error */
1562 ast_debug(1, "ast call on peer returned %d\n", res);
1563 ast_verb(3, "Couldn't call %s\n", numsubst);
1564 ast_hangup(tc);
1565 tc = NULL;
1566 ast_free(tmp);
1567 continue;
1568 } else {
1569 senddialevent(chan, tc, numsubst);
1570 ast_verb(3, "Called %s\n", numsubst);
1571 if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
1572 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1574 /* Put them in the list of outgoing thingies... We're ready now.
1575 XXX If we're forcibly removed, these outgoing calls won't get
1576 hung up XXX */
1577 ast_set_flag64(tmp, DIAL_STILLGOING);
1578 tmp->chan = tc;
1579 tmp->next = outgoing;
1580 outgoing = tmp;
1581 /* If this line is up, don't try anybody else */
1582 if (outgoing->chan->_state == AST_STATE_UP)
1583 break;
1586 if (ast_strlen_zero(args.timeout)) {
1587 to = -1;
1588 } else {
1589 to = atoi(args.timeout);
1590 if (to > 0)
1591 to *= 1000;
1592 else
1593 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1596 if (!outgoing) {
1597 strcpy(pa.status, "CHANUNAVAIL");
1598 if (fulldial == num_dialed) {
1599 res = -1;
1600 goto out;
1602 } else {
1603 /* Our status will at least be NOANSWER */
1604 strcpy(pa.status, "NOANSWER");
1605 if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
1606 moh = 1;
1607 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1608 char *original_moh = ast_strdupa(chan->musicclass);
1609 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1610 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1611 ast_string_field_set(chan, musicclass, original_moh);
1612 } else {
1613 ast_moh_start(chan, NULL, NULL);
1615 ast_indicate(chan, AST_CONTROL_PROGRESS);
1616 } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
1617 ast_indicate(chan, AST_CONTROL_RINGING);
1618 sentringing++;
1622 time(&start_time);
1623 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
1625 /* The ast_channel_datastore_remove() function could fail here if the
1626 * datastore was moved to another channel during a masquerade. If this is
1627 * the case, don't free the datastore here because later, when the channel
1628 * to which the datastore was moved hangs up, it will attempt to free this
1629 * datastore again, causing a crash
1631 if (!ast_channel_datastore_remove(chan, datastore))
1632 ast_datastore_free(datastore);
1633 if (!peer) {
1634 if (result) {
1635 res = result;
1636 } else if (to) { /* Musta gotten hung up */
1637 res = -1;
1638 } else { /* Nobody answered, next please? */
1639 res = 0;
1642 /* SIP, in particular, sends back this error code to indicate an
1643 * overlap dialled number needs more digits. */
1644 if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
1645 res = AST_PBX_INCOMPLETE;
1648 /* almost done, although the 'else' block is 400 lines */
1649 } else {
1650 const char *number;
1651 time_t end_time, answer_time = time(NULL);
1652 char toast[80]; /* buffer to set variables */
1654 strcpy(pa.status, "ANSWER");
1655 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1656 we will always return with -1 so that it is hung up properly after the
1657 conversation. */
1658 hanguptree(outgoing, peer, 1);
1659 outgoing = NULL;
1660 /* If appropriate, log that we have a destination channel */
1661 if (chan->cdr)
1662 ast_cdr_setdestchan(chan->cdr, peer->name);
1663 if (peer->name)
1664 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1666 ast_channel_lock(peer);
1667 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1668 if (!number)
1669 number = numsubst;
1670 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1671 ast_channel_unlock(peer);
1673 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1674 ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
1675 ast_channel_sendurl( peer, args.url );
1677 if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
1678 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
1679 res = 0;
1680 goto out;
1683 if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1684 res = 0;
1685 } else {
1686 int digit = 0;
1687 /* Start autoservice on the other chan */
1688 res = ast_autoservice_start(chan);
1689 /* Now Stream the File */
1690 if (!res)
1691 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1692 if (!res) {
1693 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1695 /* Ok, done. stop autoservice */
1696 res = ast_autoservice_stop(chan);
1697 if (digit > 0 && !res)
1698 res = ast_senddigit(chan, digit, 0);
1699 else
1700 res = digit;
1704 if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1705 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1706 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1707 /* peer goes to the same context and extension as chan, so just copy info from chan*/
1708 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
1709 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
1710 peer->priority = chan->priority + 2;
1711 ast_pbx_start(peer);
1712 hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
1713 if (continue_exec)
1714 *continue_exec = 1;
1715 res = 0;
1716 goto done;
1719 if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1720 struct ast_app *theapp;
1721 const char *macro_result;
1723 res = ast_autoservice_start(chan);
1724 if (res) {
1725 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1726 res = -1;
1729 theapp = pbx_findapp("Macro");
1731 if (theapp && !res) { /* XXX why check res here ? */
1732 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1733 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1734 ast_debug(1, "Macro exited with status %d\n", res);
1735 res = 0;
1736 } else {
1737 ast_log(LOG_ERROR, "Could not find application Macro\n");
1738 res = -1;
1741 if (ast_autoservice_stop(chan) < 0) {
1742 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1743 res = -1;
1746 ast_channel_lock(peer);
1748 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1749 char *macro_transfer_dest;
1751 if (!strcasecmp(macro_result, "BUSY")) {
1752 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1753 ast_set_flag64(peerflags, OPT_GO_ON);
1754 res = -1;
1755 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1756 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1757 ast_set_flag64(peerflags, OPT_GO_ON);
1758 res = -1;
1759 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1760 /* hangup peer and keep chan alive assuming the macro has changed
1761 the context / exten / priority or perhaps
1762 the next priority in the current exten is desired.
1764 ast_set_flag64(peerflags, OPT_GO_ON);
1765 res = -1;
1766 } else if (!strcasecmp(macro_result, "ABORT")) {
1767 /* Hangup both ends unless the caller has the g flag */
1768 res = -1;
1769 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1770 res = -1;
1771 /* perform a transfer to a new extension */
1772 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1773 replace_macro_delimiter(macro_transfer_dest);
1774 if (!ast_parseable_goto(chan, macro_transfer_dest))
1775 ast_set_flag64(peerflags, OPT_GO_ON);
1780 ast_channel_unlock(peer);
1783 if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
1784 struct ast_app *theapp;
1785 const char *gosub_result;
1786 char *gosub_args, *gosub_argstart;
1788 res = ast_autoservice_start(chan);
1789 if (res) {
1790 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1791 res = -1;
1794 theapp = pbx_findapp("Gosub");
1796 if (theapp && !res) {
1797 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
1799 /* Set where we came from */
1800 ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
1801 ast_copy_string(peer->exten, "s", sizeof(peer->exten));
1802 peer->priority = 0;
1804 gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
1805 if (gosub_argstart) {
1806 *gosub_argstart = 0;
1807 asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1);
1808 *gosub_argstart = ',';
1809 } else {
1810 asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]);
1813 if (gosub_args) {
1814 res = pbx_exec(peer, theapp, gosub_args);
1815 ast_pbx_run(peer);
1816 ast_free(gosub_args);
1817 if (option_debug)
1818 ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
1819 } else
1820 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
1822 res = 0;
1823 } else if (!res) {
1824 ast_log(LOG_ERROR, "Could not find application Gosub\n");
1825 res = -1;
1828 if (ast_autoservice_stop(chan) < 0) {
1829 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1830 res = -1;
1833 ast_channel_lock(peer);
1835 if (!res && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
1836 char *gosub_transfer_dest;
1838 if (!strcasecmp(gosub_result, "BUSY")) {
1839 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1840 ast_set_flag64(peerflags, OPT_GO_ON);
1841 res = -1;
1842 } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
1843 ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
1844 ast_set_flag64(peerflags, OPT_GO_ON);
1845 res = -1;
1846 } else if (!strcasecmp(gosub_result, "CONTINUE")) {
1847 /* hangup peer and keep chan alive assuming the macro has changed
1848 the context / exten / priority or perhaps
1849 the next priority in the current exten is desired.
1851 ast_set_flag64(peerflags, OPT_GO_ON);
1852 res = -1;
1853 } else if (!strcasecmp(gosub_result, "ABORT")) {
1854 /* Hangup both ends unless the caller has the g flag */
1855 res = -1;
1856 } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
1857 res = -1;
1858 /* perform a transfer to a new extension */
1859 if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
1860 replace_macro_delimiter(gosub_transfer_dest);
1861 if (!ast_parseable_goto(chan, gosub_transfer_dest))
1862 ast_set_flag64(peerflags, OPT_GO_ON);
1867 ast_channel_unlock(peer);
1870 if (!res) {
1871 if (calldurationlimit > 0) {
1872 struct timeval whentohangup = { calldurationlimit, 0 };
1873 peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
1875 if (!ast_strlen_zero(dtmfcalled)) {
1876 ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1877 res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
1879 if (!ast_strlen_zero(dtmfcalling)) {
1880 ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1881 res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
1885 if (res) { /* some error */
1886 res = -1;
1887 end_time = time(NULL);
1888 } else {
1889 if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
1890 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1891 if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
1892 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1893 if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
1894 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1895 if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
1896 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1897 if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
1898 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1899 if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
1900 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1901 if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
1902 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1903 if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
1904 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1905 if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
1906 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
1907 if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
1908 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
1909 if (ast_test_flag64(peerflags, OPT_GO_ON))
1910 ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
1912 if (moh) {
1913 moh = 0;
1914 ast_moh_stop(chan);
1915 } else if (sentringing) {
1916 sentringing = 0;
1917 ast_indicate(chan, -1);
1919 /* Be sure no generators are left on it */
1920 ast_deactivate_generator(chan);
1921 /* Make sure channels are compatible */
1922 res = ast_channel_make_compatible(chan, peer);
1923 if (res < 0) {
1924 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1925 ast_hangup(peer);
1926 res = -1;
1927 goto done;
1929 if (opermode && !strncmp(chan->tech->type, "DAHDI", 3) && !strncmp(peer->name, "DAHDI", 3)) {
1930 /* what's this special handling for dahdi <-> dahdi ?
1931 * A: dahdi to dahdi calls are natively bridged at the kernel driver
1932 * level, so we need to ensure that this mode gets propagated
1933 * all the way down. */
1934 struct oprmode oprmode;
1936 oprmode.peer = peer;
1937 oprmode.mode = opermode;
1939 ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
1941 res = ast_bridge_call(chan, peer, &config);
1942 end_time = time(NULL);
1943 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1944 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1947 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1948 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1950 if (ast_test_flag64(&opts, OPT_PEER_H)) {
1951 ast_log(LOG_NOTICE, "PEER context: %s; PEER exten: %s; PEER priority: %d\n",
1952 peer->context, peer->exten, peer->priority);
1955 strcpy(peer->context, chan->context);
1957 if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
1958 int autoloopflag;
1959 int found;
1960 strcpy(peer->exten, "h");
1961 peer->priority = 1;
1962 autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
1963 ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
1965 while ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
1966 peer->priority++;
1968 if (found && res) {
1969 /* Something bad happened, or a hangup has been requested. */
1970 ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
1971 ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
1973 ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
1975 if (res != AST_PBX_NO_HANGUP_PEER) {
1976 if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
1977 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
1978 ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
1979 ast_pbx_start(peer);
1980 } else {
1981 if (!ast_check_hangup(chan))
1982 chan->hangupcause = peer->hangupcause;
1983 ast_hangup(peer);
1987 out:
1988 if (moh) {
1989 moh = 0;
1990 ast_moh_stop(chan);
1991 } else if (sentringing) {
1992 sentringing = 0;
1993 ast_indicate(chan, -1);
1995 ast_channel_early_bridge(chan, NULL);
1996 hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
1997 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1998 senddialendevent(chan, pa.status);
1999 ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
2001 if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE) && (res != AST_PBX_INCOMPLETE)) {
2002 if (calldurationlimit)
2003 memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
2004 res = 0;
2007 done:
2008 return res;
2011 static int dial_exec(struct ast_channel *chan, void *data)
2013 struct ast_flags64 peerflags;
2015 memset(&peerflags, 0, sizeof(peerflags));
2017 return dial_exec_full(chan, data, &peerflags, NULL);
2020 static int retrydial_exec(struct ast_channel *chan, void *data)
2022 char *parse;
2023 const char *context = NULL;
2024 int sleepms = 0, loops = 0, res = -1;
2025 struct ast_flags64 peerflags = { 0, };
2026 AST_DECLARE_APP_ARGS(args,
2027 AST_APP_ARG(announce);
2028 AST_APP_ARG(sleep);
2029 AST_APP_ARG(retries);
2030 AST_APP_ARG(dialdata);
2033 if (ast_strlen_zero(data)) {
2034 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
2035 return -1;
2038 parse = ast_strdupa(data);
2039 AST_STANDARD_APP_ARGS(args, parse);
2041 if ((sleepms = atoi(args.sleep)))
2042 sleepms *= 1000;
2044 loops = atoi(args.retries);
2046 if (!args.dialdata) {
2047 ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
2048 goto done;
2051 if (sleepms < 1000)
2052 sleepms = 10000;
2054 if (!loops)
2055 loops = -1; /* run forever */
2057 ast_channel_lock(chan);
2058 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
2059 context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
2060 ast_channel_unlock(chan);
2062 res = 0;
2063 while (loops) {
2064 int continue_exec;
2066 chan->data = "Retrying";
2067 if (ast_test_flag(chan, AST_FLAG_MOH))
2068 ast_moh_stop(chan);
2070 res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
2071 if (continue_exec)
2072 break;
2074 if (res == 0) {
2075 if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
2076 if (!ast_strlen_zero(args.announce)) {
2077 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
2078 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
2079 ast_waitstream(chan, AST_DIGIT_ANY);
2080 } else
2081 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
2083 if (!res && sleepms) {
2084 if (!ast_test_flag(chan, AST_FLAG_MOH))
2085 ast_moh_start(chan, NULL, NULL);
2086 res = ast_waitfordigit(chan, sleepms);
2088 } else {
2089 if (!ast_strlen_zero(args.announce)) {
2090 if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
2091 if (!(res = ast_streamfile(chan, args.announce, chan->language)))
2092 res = ast_waitstream(chan, "");
2093 } else
2094 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
2096 if (sleepms) {
2097 if (!ast_test_flag(chan, AST_FLAG_MOH))
2098 ast_moh_start(chan, NULL, NULL);
2099 if (!res)
2100 res = ast_waitfordigit(chan, sleepms);
2105 if (res < 0 || res == AST_PBX_INCOMPLETE) {
2106 break;
2107 } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
2108 if (onedigit_goto(chan, context, (char) res, 1)) {
2109 res = 0;
2110 break;
2113 loops--;
2115 if (loops == 0)
2116 res = 0;
2117 else if (res == 1)
2118 res = 0;
2120 if (ast_test_flag(chan, AST_FLAG_MOH))
2121 ast_moh_stop(chan);
2122 done:
2123 return res;
2126 static int unload_module(void)
2128 int res;
2129 struct ast_context *con;
2131 res = ast_unregister_application(app);
2132 res |= ast_unregister_application(rapp);
2134 if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
2135 ast_context_remove_extension2(con, "s", 1, NULL, 0);
2136 ast_context_destroy(con, "app_dial"); /* leave nothing behind */
2139 return res;
2142 static int load_module(void)
2144 int res;
2145 struct ast_context *con;
2147 con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
2148 if (!con)
2149 ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
2150 else
2151 ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_dial");
2153 res = ast_register_application(app, dial_exec, synopsis, descrip);
2154 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
2156 return res;
2159 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");