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$")
39 #include <sys/signal.h>
41 #include <netinet/in.h>
43 #include "asterisk/lock.h"
44 #include "asterisk/file.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/pbx.h"
48 #include "asterisk/options.h"
49 #include "asterisk/module.h"
50 #include "asterisk/translate.h"
51 #include "asterisk/say.h"
52 #include "asterisk/config.h"
53 #include "asterisk/features.h"
54 #include "asterisk/musiconhold.h"
55 #include "asterisk/callerid.h"
56 #include "asterisk/utils.h"
57 #include "asterisk/app.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/rtp.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/privacy.h"
62 #include "asterisk/stringfields.h"
64 static char *app = "Dial";
66 static char *synopsis = "Place a call and connect to the current channel";
68 static char *descrip =
69 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
70 "This application will place calls to one or more specified channels. As soon\n"
71 "as one of the requested channels answers, the originating channel will be\n"
72 "answered, if it has not already been answered. These two channels will then\n"
73 "be active in a bridged call. All other channels that were requested will then\n"
75 " Unless there is a timeout specified, the Dial application will wait\n"
76 "indefinitely until one of the called channels answers, the user hangs up, or\n"
77 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
78 "continue if no requested channels can be called, or if the timeout expires.\n\n"
79 " This application sets the following channel variables upon completion:\n"
80 " DIALEDTIME - This is the time from dialing a channel until when it\n"
82 " ANSWEREDTIME - This is the amount of time for actual call.\n"
83 " DIALSTATUS - This is the status of the call:\n"
84 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
85 " DONTCALL | TORTURE | INVALIDARGS\n"
86 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
87 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
88 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
89 "wants to send the caller to the 'torture' script.\n"
90 " This application will report normal termination if the originating channel\n"
91 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
93 " The optional URL will be sent to the called party if the channel supports it.\n"
94 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
95 "application will be put into that group (as in Set(GROUP()=...).\n\n"
97 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
98 " C - Reset the CDR for this call.\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 " f - Force the callerid of the *calling* channel to be set as the\n"
109 " extension associated with the channel using a dialplan 'hint'.\n"
110 " For example, some PSTNs do not allow CallerID to be set to anything\n"
111 " other than the number assigned to the caller.\n"
112 " g - Proceed with dialplan execution at the current extension if the\n"
113 " destination channel hangs up.\n"
114 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
115 " the specified priority and the called party to the specified priority+1.\n"
116 " Optionally, an extension, or extension and context may be specified. \n"
117 " Otherwise, the current extension is used. You cannot use any additional\n"
118 " action post answer options in conjunction with this option.\n"
119 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
120 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
121 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
123 " j - Jump to priority n+101 if all of the requested channels were busy.\n"
124 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
125 " left. Repeat the warning every 'z' ms. The following special\n"
126 " variables can be used with this option:\n"
127 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
128 " Play sounds to the caller.\n"
129 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
130 " Play sounds to the callee.\n"
131 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
132 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
133 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
134 " The default is to say the time remaining.\n"
135 " m([class]) - Provide hold music to the calling party until a requested\n"
136 " channel answers. A specific MusicOnHold class can be\n"
138 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
139 " to the calling channel. Arguments can be specified to the Macro\n"
140 " using '^' as a delimeter. The Macro can set the variable\n"
141 " MACRO_RESULT to specify the following actions after the Macro is\n"
142 " finished executing.\n"
143 " * ABORT Hangup both legs of the call.\n"
144 " * CONGESTION Behave as if line congestion was encountered.\n"
145 " * BUSY Behave as if a busy signal was encountered. This will also\n"
146 " have the application jump to priority n+101 if the\n"
147 " 'j' option is set.\n"
148 " * CONTINUE Hangup the called party and allow the calling party\n"
149 " to continue dialplan execution at the next priority.\n"
150 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
151 " specified priority. Optionally, an extension, or\n"
152 " extension and priority can be specified.\n"
153 " You cannot use any additional action post answer options in conjunction\n"
154 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
155 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
156 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
157 " that no introductions are to be saved in the priv-callerintros\n"
159 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
160 " that if callerID is present, do not screen the call.\n"
161 " o - Specify that the CallerID that was present on the *calling* channel\n"
162 " be set as the CallerID on the *called* channel. This was the\n"
163 " behavior of Asterisk 1.0 and earlier.\n"
164 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
165 " only, if specified on non-Zaptel interface, it will be ignored).\n"
166 " When the destination answers (presumably an operator services\n"
167 " station), the originator no longer has control of their line.\n"
168 " They may hang up, but the switch will not release their line\n"
169 " until the destination party hangs up (the operator). Specified\n"
170 " without an arg, or with 1 as an arg, the originator hanging up\n"
171 " will cause the phone to ring back immediately. With a 2 specified,\n"
172 " when the \"operator\" flashes the trunk, it will ring their phone\n"
174 " p - This option enables screening mode. This is basically Privacy mode\n"
176 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
177 " it is provided. The current extension is used if a database\n"
178 " family/key is not specified.\n"
179 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
180 " party until the called channel has answered.\n"
181 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
182 " answered the call.\n"
183 " t - Allow the called party to transfer the calling party by sending the\n"
184 " DTMF sequence defined in features.conf.\n"
185 " T - Allow the calling party to transfer the called party by sending the\n"
186 " DTMF sequence defined in features.conf.\n"
187 " w - Allow the called party to enable recording of the call by sending\n"
188 " the DTMF sequence defined for one-touch recording in features.conf.\n"
189 " W - Allow the calling party to enable recording of the call by sending\n"
190 " the DTMF sequence defined for one-touch recording in features.conf.\n"
191 " k - Allow the called party to enable parking of the call by sending\n"
192 " the DTMF sequence defined for call parking in features.conf.\n"
193 " K - Allow the calling party to enable parking of the call by sending\n"
194 " the DTMF sequence defined for call parking in features.conf.\n";
196 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
197 static char *rapp = "RetryDial";
198 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
199 static char *rdescrip =
200 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
201 "place a call using the normal Dial application. If no channel can be reached,\n"
202 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
203 "seconds before retying the call. After 'retires' number of attempts, the\n"
204 "calling channel will continue at the next priority in the dialplan. If the\n"
205 "'retries' setting is set to 0, this application will retry endlessly.\n"
206 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
207 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
208 "one, The call will jump to that extension immediately.\n"
209 " The 'dialargs' are specified in the same format that arguments are provided\n"
210 "to the Dial application.\n";
213 OPT_ANNOUNCE = (1 << 0),
214 OPT_RESETCDR = (1 << 1),
215 OPT_DTMF_EXIT = (1 << 2),
216 OPT_SENDDTMF = (1 << 3),
217 OPT_FORCECLID = (1 << 4),
218 OPT_GO_ON = (1 << 5),
219 OPT_CALLEE_HANGUP = (1 << 6),
220 OPT_CALLER_HANGUP = (1 << 7),
221 OPT_PRIORITY_JUMP = (1 << 8),
222 OPT_DURATION_LIMIT = (1 << 9),
223 OPT_MUSICBACK = (1 << 10),
224 OPT_CALLEE_MACRO = (1 << 11),
225 OPT_SCREEN_NOINTRO = (1 << 12),
226 OPT_SCREEN_NOCLID = (1 << 13),
227 OPT_ORIGINAL_CLID = (1 << 14),
228 OPT_SCREENING = (1 << 15),
229 OPT_PRIVACY = (1 << 16),
230 OPT_RINGBACK = (1 << 17),
231 OPT_DURATION_STOP = (1 << 18),
232 OPT_CALLEE_TRANSFER = (1 << 19),
233 OPT_CALLER_TRANSFER = (1 << 20),
234 OPT_CALLEE_MONITOR = (1 << 21),
235 OPT_CALLER_MONITOR = (1 << 22),
236 OPT_GOTO = (1 << 23),
237 OPT_OPERMODE = (1 << 24),
238 OPT_CALLEE_PARK = (1 << 25),
239 OPT_CALLER_PARK = (1 << 26),
240 OPT_IGNORE_FORWARDING = (1 << 27),
241 } dial_exec_option_flags;
243 #define DIAL_STILLGOING (1 << 30)
244 #define DIAL_NOFORWARDHTML (1 << 31)
247 OPT_ARG_ANNOUNCE = 0,
250 OPT_ARG_DURATION_LIMIT,
252 OPT_ARG_CALLEE_MACRO,
254 OPT_ARG_DURATION_STOP,
256 /* note: this entry _MUST_ be the last one in the enum */
258 } dial_exec_option_args;
260 AST_APP_OPTIONS(dial_exec_options, {
261 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
262 AST_APP_OPTION('C', OPT_RESETCDR),
263 AST_APP_OPTION('d', OPT_DTMF_EXIT),
264 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
265 AST_APP_OPTION('f', OPT_FORCECLID),
266 AST_APP_OPTION('g', OPT_GO_ON),
267 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
268 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
269 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
270 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
271 AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
272 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
273 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
274 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
275 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
276 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
277 AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
278 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
279 AST_APP_OPTION('p', OPT_SCREENING),
280 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
281 AST_APP_OPTION('r', OPT_RINGBACK),
282 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
283 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
284 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
285 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
286 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
287 AST_APP_OPTION('k', OPT_CALLEE_PARK),
288 AST_APP_OPTION('K', OPT_CALLER_PARK),
292 * The list of active channels
295 struct chanlist *next;
296 struct ast_channel *chan;
302 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception)
304 /* Hang up a tree of stuff */
307 /* Hangup any existing lines we have open */
308 if (outgoing->chan && (outgoing->chan != exception))
309 ast_hangup(outgoing->chan);
311 outgoing=outgoing->next;
316 #define AST_MAX_FORWARDS 8
318 #define AST_MAX_WATCHERS 256
321 * argument to handle_cause() and other functions.
324 struct ast_channel *chan;
330 static void handle_cause(int cause, struct cause_args *num)
332 struct ast_cdr *cdr = num->chan->cdr;
341 case AST_CAUSE_CONGESTION:
347 case AST_CAUSE_UNREGISTERED:
353 case AST_CAUSE_NORMAL_CLEARING:
362 /* free the buffer if allocated, and set the pointer to the second arg */
363 #define S_REPLACE(s, new_val) \
370 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
372 char rexten[2] = { exten, '\0' };
375 if (!ast_goto_if_exists(chan, context, rexten, pri))
378 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
380 else if (!ast_strlen_zero(chan->macrocontext)) {
381 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
389 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
391 const char *context = S_OR(chan->macrocontext, chan->context);
392 const char *exten = S_OR(chan->macroexten, chan->exten);
394 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
397 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
399 manager_event(EVENT_FLAG_CALL, "Dial",
400 "SubEvent: Begin\r\n"
402 "Destination: %s\r\n"
403 "CallerIDNum: %s\r\n"
404 "CallerIDName: %s\r\n"
405 "SrcUniqueID: %s\r\n"
406 "DestUniqueID: %s\r\n",
407 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
408 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
412 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
414 manager_event(EVENT_FLAG_CALL, "Dial",
417 "DialStatus: %s\r\n",
418 src->name, dialstatus);
422 * helper function for wait_for_answer()
424 * XXX this code is highly suspicious, as it essentially overwrites
425 * the outgoing channel without properly deleting it.
427 static void do_forward(struct chanlist *o,
428 struct cause_args *num, struct ast_flags *peerflags, int single)
431 struct ast_channel *original = o->chan;
432 struct ast_channel *c = o->chan; /* the winner */
433 struct ast_channel *in = num->chan; /* the input channel */
438 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
439 if ((stuff = strchr(tmpchan, '/'))) {
443 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
444 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
448 /* Before processing channel, go ahead and check for forwarding */
450 if (o->forwards < AST_MAX_FORWARDS) {
451 if (option_verbose > 2)
452 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
453 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
454 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
455 if (option_verbose > 2)
456 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
458 cause = AST_CAUSE_BUSY;
460 /* Setup parameters */
461 c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
464 ast_channel_make_compatible(o->chan, in);
465 ast_channel_inherit_variables(in, o->chan);
467 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
470 if (option_verbose > 2)
471 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
472 cause = AST_CAUSE_CONGESTION;
476 ast_clear_flag(o, DIAL_STILLGOING);
477 handle_cause(cause, num);
479 char *new_cid_num, *new_cid_name;
480 struct ast_channel *src;
482 ast_rtp_make_compatible(c, in, single);
483 if (ast_test_flag(o, OPT_FORCECLID)) {
484 new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
485 new_cid_name = NULL; /* XXX no name ? */
486 src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
488 new_cid_num = ast_strdup(in->cid.cid_num);
489 new_cid_name = ast_strdup(in->cid.cid_name);
492 ast_string_field_set(c, accountcode, src->accountcode);
493 c->cdrflags = src->cdrflags;
494 S_REPLACE(c->cid.cid_num, new_cid_num);
495 S_REPLACE(c->cid.cid_name, new_cid_name);
497 if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
498 S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
500 S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
501 if (ast_call(c, tmpchan, 0)) {
502 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
503 ast_clear_flag(o, DIAL_STILLGOING);
504 ast_hangup(original);
508 senddialevent(in, c);
509 /* After calling, set callerid to extension */
510 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
511 char cidname[AST_MAX_EXTENSION];
512 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
514 /* Hangup the original channel now, in case we needed it */
515 ast_hangup(original);
520 /* argument used for some functions. */
521 struct privacy_args {
525 char privintro[1024];
529 static struct ast_channel *wait_for_answer(struct ast_channel *in,
530 struct chanlist *outgoing, int *to, struct ast_flags *peerflags,
531 struct privacy_args *pa,
532 const struct cause_args *num_in, int priority_jump, int *result)
534 struct cause_args num = *num_in;
535 int prestart = num.busy + num.congestion + num.nochan;
537 struct ast_channel *peer = NULL;
538 /* single is set if only one destination is enabled */
539 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
542 /* Turn off hold music, etc */
543 ast_deactivate_generator(in);
544 /* If we are calling a single channel, make them compatible for in-band tone purpose */
545 ast_channel_make_compatible(outgoing->chan, in);
549 while (*to && !peer) {
551 int pos = 0; /* how many channels do we handle */
552 int numlines = prestart;
553 struct ast_channel *winner;
554 struct ast_channel *watchers[AST_MAX_WATCHERS];
556 watchers[pos++] = in;
557 for (o = outgoing; o; o = o->next) {
558 /* Keep track of important channels */
559 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
560 watchers[pos++] = o->chan;
563 if (pos == 1) { /* only the input channel is available */
564 if (numlines == (num.busy + num.congestion + num.nochan)) {
565 if (option_verbose > 2)
566 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
568 strcpy(pa->status, "BUSY");
569 else if (num.congestion)
570 strcpy(pa->status, "CONGESTION");
572 strcpy(pa->status, "CHANUNAVAIL");
573 if (ast_opt_priority_jumping || priority_jump)
574 ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
576 if (option_verbose > 2)
577 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
582 winner = ast_waitfor_n(watchers, pos, to);
583 for (o = outgoing; o; o = o->next) {
585 struct ast_channel *c = o->chan;
589 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
591 if (option_verbose > 2)
592 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
594 ast_copy_flags(peerflags, o,
595 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
596 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
597 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
598 OPT_CALLEE_PARK | OPT_CALLER_PARK |
600 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
601 ast_copy_string(c->exten, "", sizeof(c->exten));
607 /* here, o->chan == c == winner */
608 if (!ast_strlen_zero(c->call_forward)) {
609 do_forward(o, &num, peerflags, single);
612 f = ast_read(winner);
614 in->hangupcause = c->hangupcause;
617 ast_clear_flag(o, DIAL_STILLGOING);
618 handle_cause(in->hangupcause, &num);
621 if (f->frametype == AST_FRAME_CONTROL) {
622 switch(f->subclass) {
623 case AST_CONTROL_ANSWER:
624 /* This is our guy if someone answered. */
626 if (option_verbose > 2)
627 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
629 ast_copy_flags(peerflags, o,
630 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
631 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
632 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
633 OPT_CALLEE_PARK | OPT_CALLER_PARK |
635 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
636 ast_copy_string(c->exten, "", sizeof(c->exten));
637 /* Setup early bridge if appropriate */
638 ast_channel_early_bridge(in, peer);
640 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
641 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
642 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
644 case AST_CONTROL_BUSY:
645 if (option_verbose > 2)
646 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
647 in->hangupcause = c->hangupcause;
650 ast_clear_flag(o, DIAL_STILLGOING);
651 handle_cause(AST_CAUSE_BUSY, &num);
653 case AST_CONTROL_CONGESTION:
654 if (option_verbose > 2)
655 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
656 in->hangupcause = c->hangupcause;
659 ast_clear_flag(o, DIAL_STILLGOING);
660 handle_cause(AST_CAUSE_CONGESTION, &num);
662 case AST_CONTROL_RINGING:
663 if (option_verbose > 2)
664 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
665 /* Setup early media if appropriate */
667 ast_channel_early_bridge(in, c);
668 if (!(pa->sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
669 ast_indicate(in, AST_CONTROL_RINGING);
673 case AST_CONTROL_PROGRESS:
674 if (option_verbose > 2)
675 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
676 /* Setup early media if appropriate */
678 ast_channel_early_bridge(in, c);
679 if (!ast_test_flag(outgoing, OPT_RINGBACK))
680 ast_indicate(in, AST_CONTROL_PROGRESS);
682 case AST_CONTROL_VIDUPDATE:
683 if (option_verbose > 2)
684 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
685 ast_indicate(in, AST_CONTROL_VIDUPDATE);
687 case AST_CONTROL_PROCEEDING:
688 if (option_verbose > 2)
689 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
691 ast_channel_early_bridge(in, c);
692 if (!ast_test_flag(outgoing, OPT_RINGBACK))
693 ast_indicate(in, AST_CONTROL_PROCEEDING);
695 case AST_CONTROL_HOLD:
696 if (option_verbose > 2)
697 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
698 ast_indicate(in, AST_CONTROL_HOLD);
700 case AST_CONTROL_UNHOLD:
701 if (option_verbose > 2)
702 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
703 ast_indicate(in, AST_CONTROL_UNHOLD);
705 case AST_CONTROL_OFFHOOK:
706 case AST_CONTROL_FLASH:
707 /* Ignore going off hook and flash */
710 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
711 if (option_verbose > 2)
712 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
713 ast_indicate(in, -1);
719 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
722 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
723 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
724 if (ast_write(in, f))
725 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
726 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
727 if (ast_write(in, f))
728 ast_log(LOG_WARNING, "Unable to forward image\n");
729 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
730 if (ast_write(in, f))
731 ast_log(LOG_WARNING, "Unable to send text\n");
732 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
733 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
734 ast_log(LOG_WARNING, "Unable to send URL\n");
740 struct ast_frame *f = ast_read(in);
742 if (f && (f->frametype != AST_FRAME_VOICE))
743 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
744 else if (!f || (f->frametype != AST_FRAME_VOICE))
745 printf("Hangup received on %s\n", in->name);
747 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
750 strcpy(pa->status, "CANCEL");
756 /* now f is guaranteed non-NULL */
757 if (f->frametype == AST_FRAME_DTMF) {
758 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
759 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
760 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
761 if (option_verbose > 2)
762 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
764 *result = f->subclass;
765 strcpy(pa->status, "CANCEL");
771 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
772 (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
773 if (option_verbose > 2)
774 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
776 strcpy(pa->status, "CANCEL");
782 /* Forward HTML stuff */
783 if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
784 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
785 ast_log(LOG_WARNING, "Unable to send URL\n");
788 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
789 if (ast_write(outgoing->chan, f))
790 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
792 if (single && (f->frametype == AST_FRAME_CONTROL) &&
793 ((f->subclass == AST_CONTROL_HOLD) ||
794 (f->subclass == AST_CONTROL_UNHOLD) ||
795 (f->subclass == AST_CONTROL_VIDUPDATE))) {
796 if (option_verbose > 2)
797 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
798 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
802 if (!*to && (option_verbose > 2))
803 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
809 static void replace_macro_delimiter(char *s)
817 /* returns true if there is a valid privacy reply */
818 static int valid_priv_reply(struct ast_flags *opts, int res)
822 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
824 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
829 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
830 char *parse, unsigned int *calldurationlimit)
832 char *stringp = ast_strdupa(parse);
833 char *limit_str, *warning_str, *warnfreq_str;
835 int play_to_caller=0,play_to_callee=0;
838 limit_str = strsep(&stringp, ":");
839 warning_str = strsep(&stringp, ":");
840 warnfreq_str = strsep(&stringp, ":");
842 config->timelimit = atol(limit_str);
844 config->play_warning = atol(warning_str);
846 config->warning_freq = atol(warnfreq_str);
848 if (!config->timelimit) {
849 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
850 config->timelimit = config->play_warning = config->warning_freq = 0;
851 config->warning_sound = NULL;
852 return -1; /* error */
853 } else if ( (delta = config->play_warning - config->timelimit) > 0) {
854 int w = config->warning_freq;
856 /* If the first warning is requested _after_ the entire call would end,
857 and no warning frequency is requested, then turn off the warning. If
858 a warning frequency is requested, reduce the 'first warning' time by
859 that frequency until it falls within the call's total time limit.
861 timelim->| delta |<-playwarning
862 0__________________|_________________|
865 so the number of intervals to cut is 1+(delta-1)/w
869 config->play_warning = 0;
871 config->play_warning -= w * ( 1 + (delta-1)/w );
872 if (config->play_warning < 1)
873 config->play_warning = config->warning_freq = 0;
877 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
878 play_to_caller = var ? ast_true(var) : 1;
880 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
881 play_to_callee = var ? ast_true(var) : 0;
883 if (!play_to_caller && !play_to_callee)
886 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
887 config->warning_sound = S_OR(var, "timeleft");
889 /* The code looking at config wants a NULL, not just "", to decide
890 * that the message should not be played, so we replace "" with NULL.
891 * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
894 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
895 config->end_sound = S_OR(var, NULL);
896 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
897 config->start_sound = S_OR(var, NULL);
899 /* undo effect of S(x) in case they are both used */
900 *calldurationlimit = 0;
901 /* more efficient to do it like S(x) does since no advanced opts */
902 if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
903 *calldurationlimit = config->timelimit / 1000;
904 if (option_verbose > 2)
905 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",
907 config->timelimit = play_to_caller = play_to_callee =
908 config->play_warning = config->warning_freq = 0;
909 } else if (option_verbose > 2) {
910 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
911 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", config->timelimit);
912 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", config->play_warning);
913 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
914 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
915 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", config->warning_freq);
916 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", S_OR(config->start_sound, ""));
917 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", config->warning_sound);
918 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", S_OR(config->end_sound, ""));
921 ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
923 ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
927 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
928 struct ast_flags *opts, char **opt_args, struct privacy_args *pa)
934 /* Get the user's intro, store it in priv-callerintros/$CID,
935 unless it is already there-- this should be done before the
936 call is actually dialed */
938 /* all ring indications and moh for the caller has been halted as soon as the
939 target extension was picked up. We are going to have to kill some
940 time and make the caller believe the peer hasn't picked up yet */
942 if (ast_test_flag(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
943 char *original_moh = ast_strdupa(chan->musicclass);
944 ast_indicate(chan, -1);
945 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
946 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
947 ast_string_field_set(chan, musicclass, original_moh);
948 } else if (ast_test_flag(opts, OPT_RINGBACK)) {
949 ast_indicate(chan, AST_CONTROL_RINGING);
953 /* Start autoservice on the other chan ?? */
954 res2 = ast_autoservice_start(chan);
955 /* Now Stream the File */
956 for (loopcount = 0; loopcount < 3; loopcount++) {
957 if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
959 if (!res2) /* on timeout, play the message again */
960 res2 = ast_play_and_wait(peer,"priv-callpending");
961 if (!valid_priv_reply(opts, res2))
963 /* priv-callpending script:
964 "I have a caller waiting, who introduces themselves as:"
967 res2 = ast_play_and_wait(peer, pa->privintro);
968 if (!valid_priv_reply(opts, res2))
970 /* now get input from the called party, as to their choice */
972 /* XXX can we have both, or they are mutually exclusive ? */
973 if( ast_test_flag(opts, OPT_PRIVACY) )
974 res2 = ast_play_and_wait(peer,"priv-callee-options");
975 if( ast_test_flag(opts, OPT_SCREENING) )
976 res2 = ast_play_and_wait(peer,"screen-callee-options");
978 /*! \page DialPrivacy Dial Privacy scripts
979 \par priv-callee-options script:
980 "Dial 1 if you wish this caller to reach you directly in the future,
981 and immediately connect to their incoming call
982 Dial 2 if you wish to send this caller to voicemail now and
984 Dial 3 to send this caller to the torture menus, now and forevermore.
985 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
986 Dial 5 to allow this caller to come straight thru to you in the future,
987 but right now, just this once, send them to voicemail."
988 \par screen-callee-options script:
989 "Dial 1 if you wish to immediately connect to the incoming call
990 Dial 2 if you wish to send this caller to voicemail.
991 Dial 3 to send this caller to the torture menus.
992 Dial 4 to send this caller to a simple "go away" menu.
994 if (valid_priv_reply(opts, res2))
997 res2 = ast_play_and_wait(peer, "vm-sorry");
1000 if (ast_test_flag(opts, OPT_MUSICBACK)) {
1002 } else if (ast_test_flag(opts, OPT_RINGBACK)) {
1003 ast_indicate(chan, -1);
1006 ast_autoservice_stop(chan);
1007 if(ast_test_flag(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1008 /* map keypresses to various things, the index is res2 - '1' */
1009 static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1010 static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1012 if (option_verbose > 2)
1013 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to %s\n",
1014 opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1015 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1021 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1024 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1027 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1030 /* XXX should we set status to DENY ? */
1031 if( ast_test_flag(opts, OPT_PRIVACY) )
1033 /* if not privacy, then 5 is the same as "default" case */
1034 default: /* bad input or -1 if failure to start autoservice */
1035 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1036 /* well, there seems basically two choices. Just patch the caller thru immediately,
1037 or,... put 'em thru to voicemail. */
1038 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1039 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1040 /* XXX should we set status to DENY ? */
1041 /* XXX what about the privacy flags ? */
1045 if (res2 == '1') { /* the only case where we actually connect */
1046 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1047 just clog things up, and it's not useful information, not being tied to a CID */
1048 if( strncmp(pa->privcid,"NOCALLERID",10) == 0 || ast_test_flag(opts, OPT_SCREEN_NOINTRO) ) {
1049 ast_filedelete(pa->privintro, NULL);
1050 if( ast_fileexists(pa->privintro, NULL, NULL ) > 0 )
1051 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1052 else if (option_verbose > 2)
1053 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
1055 return 0; /* the good exit path */
1057 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1062 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1063 static int setup_privacy_args(struct privacy_args *pa,
1064 struct ast_flags *opts, char *opt_args[], struct ast_channel *chan)
1070 if (!ast_strlen_zero(chan->cid.cid_num)) {
1071 l = ast_strdupa(chan->cid.cid_num);
1072 ast_shrink_phone_number(l);
1073 if (ast_test_flag(opts, OPT_PRIVACY) ) {
1074 if (option_verbose > 2)
1075 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
1076 opt_args[OPT_ARG_PRIVACY], l);
1077 pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1079 if (option_verbose > 2)
1080 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
1081 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1086 tnam = ast_strdupa(chan->name);
1087 /* clean the channel name so slashes don't try to end up in disk file name */
1088 for (tn2 = tnam; *tn2; tn2++) {
1089 if (*tn2=='/') /* any other chars to be afraid of? */
1092 if (option_verbose > 2)
1093 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
1095 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1097 pa->privdb_val = AST_PRIVACY_UNKNOWN;
1100 ast_copy_string(pa->privcid,l,sizeof(pa->privcid));
1102 if( strncmp(pa->privcid,"NOCALLERID",10) != 0 && ast_test_flag(opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */
1103 if (option_verbose > 2)
1104 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1105 pa->privdb_val = AST_PRIVACY_ALLOW;
1106 } else if (ast_test_flag(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid,"NOCALLERID",10) == 0 ) {
1107 if (option_verbose > 2)
1108 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1111 if (pa->privdb_val == AST_PRIVACY_DENY ) {
1112 ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1113 if (option_verbose > 2)
1114 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1116 } else if (pa->privdb_val == AST_PRIVACY_KILL ) {
1117 ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1118 if (ast_opt_priority_jumping || ast_test_flag(opts, OPT_PRIORITY_JUMP)) {
1119 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
1121 return 0; /* Is this right? */
1122 } else if (pa->privdb_val == AST_PRIVACY_TORTURE ) {
1123 ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1124 if (ast_opt_priority_jumping || ast_test_flag(opts, OPT_PRIORITY_JUMP)) {
1125 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
1127 return 0; /* is this right??? */
1128 } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN ) {
1129 /* Get the user's intro, store it in priv-callerintros/$CID,
1130 unless it is already there-- this should be done before the
1131 call is actually dialed */
1133 /* make sure the priv-callerintros dir actually exists */
1134 snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1135 if (mkdir(pa->privintro, 0755) && errno != EEXIST) {
1136 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
1140 snprintf(pa->privintro,sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1141 if (ast_fileexists(pa->privintro,NULL,NULL ) > 0 && strncmp(pa->privcid,"NOCALLERID",10) != 0) {
1142 /* the DELUX version of this code would allow this caller the
1143 option to hear and retape their previously recorded intro.
1146 int duration; /* for feedback from play_and_wait */
1147 /* the file doesn't exist yet. Let the caller submit his
1148 vocal intro for posterity */
1149 /* priv-recordintro script:
1151 "At the tone, please say your name:"
1155 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 */
1156 /* don't think we'll need a lock removed, we took care of
1157 conflicts by naming the pa.privintro file */
1159 /* Delete the file regardless since they hung up during recording */
1160 ast_filedelete(pa->privintro, NULL);
1161 if (ast_fileexists(pa->privintro,NULL,NULL ) > 0 )
1162 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1163 else if (option_verbose > 2)
1164 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", pa->privintro);
1167 if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1168 ast_waitstream(chan, "");
1171 return 1; /* success */
1174 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
1176 int res = -1; /* default: error */
1177 struct ast_module_user *u;
1178 char *rest, *cur; /* scan the list of destinations */
1179 struct chanlist *outgoing = NULL; /* list of destinations */
1180 struct ast_channel *peer;
1181 int to; /* timeout */
1182 struct cause_args num = { chan, 0, 0, 0 };
1184 char numsubst[AST_MAX_EXTENSION];
1185 char cidname[AST_MAX_EXTENSION];
1187 struct ast_bridge_config config;
1188 unsigned int calldurationlimit = 0;
1189 char *dtmfcalled = NULL, *dtmfcalling = NULL;
1190 struct privacy_args pa = {
1193 .status = "INVALIDARGS",
1195 int sentringing = 0, moh = 0;
1196 const char *outbound_group = NULL;
1201 AST_DECLARE_APP_ARGS(args,
1203 AST_APP_ARG(timeout);
1204 AST_APP_ARG(options);
1207 struct ast_flags opts = { 0, };
1208 char *opt_args[OPT_ARG_ARRAY_SIZE];
1210 if (ast_strlen_zero(data)) {
1211 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1212 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1216 u = ast_module_user_add(chan); /* XXX is this the right place ? */
1218 parse = ast_strdupa(data);
1220 AST_STANDARD_APP_ARGS(args, parse);
1222 memset(&config,0,sizeof(struct ast_bridge_config));
1224 if (!ast_strlen_zero(args.options) &&
1225 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
1226 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1230 if (ast_strlen_zero(args.peers)) {
1231 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1232 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1236 if (ast_test_flag(&opts, OPT_OPERMODE)) {
1237 opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1238 if (option_verbose > 2)
1239 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
1242 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1243 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1244 if (!calldurationlimit) {
1245 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1246 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1249 if (option_verbose > 2)
1250 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
1253 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1254 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
1255 dtmfcalled = strsep(&dtmfcalling, ":");
1258 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1259 if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1263 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
1264 ast_cdr_reset(chan->cdr, NULL);
1265 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1266 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1268 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1269 res = setup_privacy_args(&pa, &opts, opt_args, chan);
1272 res = -1; /* reset default */
1278 /* If a channel group has been specified, get it for use when we create peer channels */
1279 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1281 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
1282 /* loop through the list of dial destinations */
1284 while ((cur = strsep(&rest, "&")) ) {
1285 struct chanlist *tmp;
1286 struct ast_channel *tc; /* channel for this destination */
1287 /* Get a technology/[device:]number pair */
1289 char *tech = strsep(&number, "/");
1291 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1294 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1297 ast_copy_flags(tmp, &opts,
1298 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1299 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1300 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1301 OPT_CALLEE_PARK | OPT_CALLER_PARK |
1302 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1303 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
1305 ast_copy_string(numsubst, number, sizeof(numsubst));
1306 /* Request the peer */
1307 tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
1309 /* If we can't, just go on to the next call */
1310 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1311 tech, cause, ast_cause2str(cause));
1312 handle_cause(cause, &num);
1313 if (!rest) /* we are on the last destination */
1314 chan->hangupcause = cause;
1318 pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1319 if (!ast_strlen_zero(tc->call_forward)) {
1323 ast_copy_string(tmpchan, tc->call_forward, sizeof(tmpchan));
1324 if ((stuff = strchr(tmpchan, '/'))) {
1328 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tc->call_forward, tc->context);
1333 if (tmp->forwards < AST_MAX_FORWARDS) {
1334 if (option_verbose > 2)
1335 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n",
1336 chan->name, tech, stuff, tc->name);
1338 /* If we have been told to ignore forwards, just set this channel to null
1339 * and continue processing extensions normally */
1340 if (ast_test_flag(&opts, OPT_IGNORE_FORWARDING)) {
1342 cause = AST_CAUSE_BUSY;
1343 if (option_verbose > 2)
1344 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n",
1345 chan->name, tech, stuff);
1347 tc = ast_request(tech, chan->nativeformats, stuff, &cause);
1350 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1352 ast_channel_inherit_variables(chan, tc);
1354 if (option_verbose > 2)
1355 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tc->name);
1358 cause = AST_CAUSE_CONGESTION;
1361 handle_cause(cause, &num);
1367 /* Setup outgoing SDP to match incoming one */
1368 ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
1370 /* Inherit specially named variables from parent channel */
1371 ast_channel_inherit_variables(chan, tc);
1373 tc->appl = "AppDial";
1374 tc->data = "(Outgoing Line)";
1375 tc->whentohangup = 0;
1377 S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
1378 S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
1379 S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
1380 S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
1382 /* Copy language from incoming to outgoing */
1383 ast_string_field_set(tc, language, chan->language);
1384 ast_string_field_set(tc, accountcode, chan->accountcode);
1385 tc->cdrflags = chan->cdrflags;
1386 if (ast_strlen_zero(tc->musicclass))
1387 ast_string_field_set(tc, musicclass, chan->musicclass);
1388 /* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
1389 tc->cid.cid_pres = chan->cid.cid_pres;
1390 tc->cid.cid_ton = chan->cid.cid_ton;
1391 tc->cid.cid_tns = chan->cid.cid_tns;
1392 tc->adsicpe = chan->adsicpe;
1393 tc->transfercapability = chan->transfercapability;
1395 /* If we have an outbound group, set this peer channel to it */
1397 ast_app_group_set_channel(tc, outbound_group);
1399 /* Inherit context and extension */
1400 if (!ast_strlen_zero(chan->macrocontext))
1401 ast_copy_string(tc->dialcontext, chan->macrocontext, sizeof(tc->dialcontext));
1403 ast_copy_string(tc->dialcontext, chan->context, sizeof(tc->dialcontext));
1404 if (!ast_strlen_zero(chan->macroexten))
1405 ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
1407 ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
1409 res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
1411 /* Save the info in cdr's that we called them */
1413 ast_cdr_setdestchan(chan->cdr, tc->name);
1415 /* check the results of ast_call */
1417 /* Again, keep going even if there's an error */
1419 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1420 if (option_verbose > 2)
1421 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1427 senddialevent(chan, tc);
1428 if (option_verbose > 2)
1429 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1430 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1431 ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1433 /* Put them in the list of outgoing thingies... We're ready now.
1434 XXX If we're forcibly removed, these outgoing calls won't get
1436 ast_set_flag(tmp, DIAL_STILLGOING);
1438 tmp->next = outgoing;
1440 /* If this line is up, don't try anybody else */
1441 if (outgoing->chan->_state == AST_STATE_UP)
1445 if (ast_strlen_zero(args.timeout)) {
1448 to = atoi(args.timeout);
1452 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1456 strcpy(pa.status, "CHANUNAVAIL");
1458 /* Our status will at least be NOANSWER */
1459 strcpy(pa.status, "NOANSWER");
1460 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1462 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1463 char *original_moh = ast_strdupa(chan->musicclass);
1464 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1465 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1466 ast_string_field_set(chan, musicclass, original_moh);
1468 ast_moh_start(chan, NULL, NULL);
1470 ast_indicate(chan, AST_CONTROL_PROGRESS);
1471 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1472 ast_indicate(chan, AST_CONTROL_RINGING);
1478 peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1483 } else if (to) { /* Musta gotten hung up */
1485 } else { /* Nobody answered, next please? */
1488 /* almost done, although the 'else' block is 400 lines */
1491 time_t end_time, answer_time = time(NULL);
1492 char toast[80]; /* buffer to set variables */
1494 strcpy(pa.status, "ANSWER");
1495 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1496 we will always return with -1 so that it is hung up properly after the
1498 hanguptree(outgoing, peer);
1500 /* If appropriate, log that we have a destination channel */
1502 ast_cdr_setdestchan(chan->cdr, peer->name);
1504 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1506 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1509 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1510 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1512 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1513 ast_channel_sendurl( peer, args.url );
1515 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
1516 if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
1521 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1525 /* Start autoservice on the other chan */
1526 res = ast_autoservice_start(chan);
1527 /* Now Stream the File */
1529 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1531 digit = ast_waitstream(peer, AST_DIGIT_ANY);
1533 /* Ok, done. stop autoservice */
1534 res = ast_autoservice_stop(chan);
1535 if (digit > 0 && !res)
1536 res = ast_senddigit(chan, digit);
1542 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1543 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1544 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1545 ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1547 ast_pbx_start(peer);
1548 hanguptree(outgoing, NULL);
1555 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1556 struct ast_app *theapp;
1557 const char *macro_result;
1559 res = ast_autoservice_start(chan);
1561 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1565 theapp = pbx_findapp("Macro");
1567 if (theapp && !res) { /* XXX why check res here ? */
1568 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1569 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1571 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1574 ast_log(LOG_ERROR, "Could not find application Macro\n");
1578 if (ast_autoservice_stop(chan) < 0) {
1579 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1583 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1584 char *macro_transfer_dest;
1586 if (!strcasecmp(macro_result, "BUSY")) {
1587 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1588 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1589 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1590 ast_set_flag(peerflags, OPT_GO_ON);
1593 ast_set_flag(peerflags, OPT_GO_ON);
1595 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1596 ast_copy_string(pa.status, macro_result, sizeof(pa.status));
1597 ast_set_flag(peerflags, OPT_GO_ON);
1599 } else if (!strcasecmp(macro_result, "CONTINUE")) {
1600 /* hangup peer and keep chan alive assuming the macro has changed
1601 the context / exten / priority or perhaps
1602 the next priority in the current exten is desired.
1604 ast_set_flag(peerflags, OPT_GO_ON);
1606 } else if (!strcasecmp(macro_result, "ABORT")) {
1607 /* Hangup both ends unless the caller has the g flag */
1609 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1611 /* perform a transfer to a new extension */
1612 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1613 replace_macro_delimiter(macro_transfer_dest);
1614 if (!ast_parseable_goto(chan, macro_transfer_dest))
1615 ast_set_flag(peerflags, OPT_GO_ON);
1622 if (calldurationlimit > 0) {
1623 chan->whentohangup = time(NULL) + calldurationlimit;
1625 if (!ast_strlen_zero(dtmfcalled)) {
1626 if (option_verbose > 2)
1627 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1628 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1630 if (!ast_strlen_zero(dtmfcalling)) {
1631 if (option_verbose > 2)
1632 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1633 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1637 if (res) { /* some error */
1639 end_time = time(NULL);
1641 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1642 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1643 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1644 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1645 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1646 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1647 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1648 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1649 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1650 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1651 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
1652 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1653 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
1654 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
1655 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
1656 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
1661 } else if (sentringing) {
1663 ast_indicate(chan, -1);
1665 /* Be sure no generators are left on it */
1666 ast_deactivate_generator(chan);
1667 /* Make sure channels are compatible */
1668 res = ast_channel_make_compatible(chan, peer);
1670 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1675 if (opermode && !strncmp(chan->name,"Zap",3) && !strncmp(peer->name,"Zap",3)) {
1676 /* XXX what's this special handling for Zap <-> Zap ? */
1677 struct oprmode oprmode;
1679 oprmode.peer = peer;
1680 oprmode.mode = opermode;
1682 ast_channel_setoption(chan,
1683 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
1685 res = ast_bridge_call(chan,peer,&config);
1686 end_time = time(NULL);
1687 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1688 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1691 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1692 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1694 if (res != AST_PBX_NO_HANGUP_PEER) {
1695 if (!chan->_softhangup)
1696 chan->hangupcause = peer->hangupcause;
1704 } else if (sentringing) {
1706 ast_indicate(chan, -1);
1708 ast_channel_early_bridge(chan, NULL);
1709 hanguptree(outgoing, NULL);
1710 pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1711 senddialendevent(chan, pa.status);
1713 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", pa.status);
1715 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1719 ast_module_user_remove(u); /* XXX probably not the right place for this. */
1723 static int dial_exec(struct ast_channel *chan, void *data)
1725 struct ast_flags peerflags;
1727 memset(&peerflags, 0, sizeof(peerflags));
1729 return dial_exec_full(chan, data, &peerflags, NULL);
1732 static int retrydial_exec(struct ast_channel *chan, void *data)
1734 char *announce = NULL, *dialdata = NULL;
1735 const char *context = NULL;
1736 int sleep = 0, loops = 0, res = -1;
1737 struct ast_module_user *u;
1738 struct ast_flags peerflags;
1740 if (ast_strlen_zero(data)) {
1741 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1745 u = ast_module_user_add(chan);
1747 announce = ast_strdupa(data);
1749 memset(&peerflags, 0, sizeof(peerflags));
1751 if ((dialdata = strchr(announce, '|'))) {
1753 if ((sleep = atoi(dialdata))) {
1756 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1759 if ((dialdata = strchr(dialdata, '|'))) {
1761 if (!(loops = atoi(dialdata))) {
1762 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1768 if ((dialdata = strchr(dialdata, '|'))) {
1771 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1779 loops = -1; /* run forever */
1781 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1787 chan->data = "Retrying";
1788 if (ast_test_flag(chan, AST_FLAG_MOH))
1791 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
1795 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1796 if (!(res = ast_streamfile(chan, announce, chan->language)))
1797 res = ast_waitstream(chan, AST_DIGIT_ANY);
1798 if (!res && sleep) {
1799 if (!ast_test_flag(chan, AST_FLAG_MOH))
1800 ast_moh_start(chan, NULL, NULL);
1801 res = ast_waitfordigit(chan, sleep);
1804 if (!(res = ast_streamfile(chan, announce, chan->language)))
1805 res = ast_waitstream(chan, "");
1807 if (!ast_test_flag(chan, AST_FLAG_MOH))
1808 ast_moh_start(chan, NULL, NULL);
1810 res = ast_waitfordigit(chan, sleep);
1817 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1818 if (onedigit_goto(chan, context, (char) res, 1)) {
1830 if (ast_test_flag(chan, AST_FLAG_MOH))
1833 ast_module_user_remove(u);
1837 static int unload_module(void)
1841 res = ast_unregister_application(app);
1842 res |= ast_unregister_application(rapp);
1844 ast_module_user_hangup_all();
1849 static int load_module(void)
1853 res = ast_register_application(app, dial_exec, synopsis, descrip);
1854 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1859 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");