merge two nested 'if' which are really a single block.
[asterisk/asterisk.git] / apps / app_dial.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
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.
13  *
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.
17  */
18
19 /*! \file
20  *
21  * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
22  *
23  * \author Mark Spencer <markster@digium.com>
24  * 
25  * \ingroup applications
26  */
27
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <sys/time.h>
35 #include <sys/signal.h>
36 #include <netinet/in.h>
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41
42 #include "asterisk/lock.h"
43 #include "asterisk/file.h"
44 #include "asterisk/logger.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/options.h"
48 #include "asterisk/module.h"
49 #include "asterisk/translate.h"
50 #include "asterisk/say.h"
51 #include "asterisk/config.h"
52 #include "asterisk/features.h"
53 #include "asterisk/musiconhold.h"
54 #include "asterisk/callerid.h"
55 #include "asterisk/utils.h"
56 #include "asterisk/app.h"
57 #include "asterisk/causes.h"
58 #include "asterisk/rtp.h"
59 #include "asterisk/manager.h"
60 #include "asterisk/privacy.h"
61 #include "asterisk/stringfields.h"
62
63 static char *app = "Dial";
64
65 static char *synopsis = "Place a call and connect to the current channel";
66
67 static char *descrip =
68 "  Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
69 "This applicaiton will place calls to one or more specified channels. As soon\n"
70 "as one of the requested channels answers, the originating channel will be\n"
71 "answered, if it has not already been answered. These two channels will then\n"
72 "be active in a bridged call. All other channels that were requested will then\n"
73 "be hung up.\n"
74 "  Unless there is a timeout specified, the Dial application will wait\n"
75 "indefinitely until one of the called channels answers, the user hangs up, or\n"
76 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
77 "continue if no requested channels can be called, or if the timeout expires.\n\n"
78 "  This application sets the following channel variables upon completion:\n"
79 "    DIALEDTIME   - This is the time from dialing a channel until when it\n"
80 "                   is disconnected.\n" 
81 "    ANSWEREDTIME - This is the amount of time for actual call.\n"
82 "    DIALSTATUS   - This is the status of the call:\n"
83 "                   CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n" 
84 "                   DONTCALL | TORTURE\n"
85 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
86 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
87 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
88 "wants to send the caller to the 'torture' script.\n"
89 "  This application will report normal termination if the originating channel\n"
90 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
91 "ends the call.\n"
92 "  The optional URL will be sent to the called party if the channel supports it.\n"
93 "  If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
94 "application will be put into that group (as in Set(GROUP()=...).\n\n"
95 "  Options:\n"
96 "    A(x) - Play an announcement to the called party, using 'x' as the file.\n"
97 "    C    - Reset the CDR for this call.\n"
98 "    d    - Allow the calling user to dial a 1 digit extension while waiting for\n"
99 "           a call to be answered. Exit to that extension if it exists in the\n"
100 "           current context, or the context defined in the EXITCONTEXT variable,\n"
101 "           if it exists.\n"
102 "    D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
103 "           party has answered, but before the call gets bridged. The 'called'\n"
104 "           DTMF string is sent to the called party, and the 'calling' DTMF\n"
105 "           string is sent to the calling party. Both parameters can be used\n"
106 "           alone.\n"   
107 "    f    - Force the callerid of the *calling* channel to be set as the\n"
108 "           extension associated with the channel using a dialplan 'hint'.\n"
109 "           For example, some PSTNs do not allow CallerID to be set to anything\n"
110 "           other than the number assigned to the caller.\n"
111 "    g    - Proceed with dialplan execution at the current extension if the\n"
112 "           destination channel hangs up.\n"
113 "    G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
114 "           the specified priority and the called party to the specified priority+1.\n"
115 "           Optionally, an extension, or extension and context may be specified. \n"
116 "           Otherwise, the current extension is used.\n"
117 "    h    - Allow the called party to hang up by sending the '*' DTMF digit.\n"
118 "    H    - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
119 "    j    - Jump to priority n+101 if all of the requested channels were busy.\n"
120 "    L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
121 "           left. Repeat the warning every 'z' ms. The following special\n"
122 "           variables can be used with this option:\n"
123 "           * LIMIT_PLAYAUDIO_CALLER   yes|no (default yes)\n"
124 "                                      Play sounds to the caller.\n"
125 "           * LIMIT_PLAYAUDIO_CALLEE   yes|no\n"
126 "                                      Play sounds to the callee.\n"
127 "           * LIMIT_TIMEOUT_FILE       File to play when time is up.\n"
128 "           * LIMIT_CONNECT_FILE       File to play when call begins.\n"
129 "           * LIMIT_WARNING_FILE       File to play as warning if 'y' is defined.\n"
130 "                                      The default is to say the time remaining.\n"
131 "    m([class]) - Provide hold music to the calling party until a requested\n"
132 "           channel answers. A specific MusicOnHold class can be\n"
133 "           specified.\n"
134 "    M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
135 "           to the calling channel. Arguments can be specified to the Macro\n"
136 "           using '^' as a delimeter. The Macro can set the variable\n"
137 "           MACRO_RESULT to specify the following actions after the Macro is\n" 
138 "           finished executing.\n"
139 "           * ABORT        Hangup both legs of the call.\n"
140 "           * CONGESTION   Behave as if line congestion was encountered.\n"
141 "           * BUSY         Behave as if a busy signal was encountered. This will also\n"
142 "                          have the application jump to priority n+101 if the\n"
143 "                          'j' option is set.\n"
144 "           * CONTINUE     Hangup the called party and allow the calling party\n"
145 "                          to continue dialplan execution at the next priority.\n"
146 "           * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
147 "                          specified priority. Optionally, an extension, or\n"
148 "                          extension and priority can be specified.\n"
149 "    n    - This option is a modifier for the screen/privacy mode. It specifies\n"
150 "           that no introductions are to be saved in the priv-callerintros\n"
151 "           directory.\n"
152 "    N    - This option is a modifier for the screen/privacy mode. It specifies\n"
153 "           that if callerID is present, do not screen the call.\n"
154 "    o    - Specify that the CallerID that was present on the *calling* channel\n"
155 "           be set as the CallerID on the *called* channel. This was the\n"
156 "           behavior of Asterisk 1.0 and earlier.\n"
157 "    p    - This option enables screening mode. This is basically Privacy mode\n"
158 "           without memory.\n"
159 "    P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
160 "           it is provided. The current extension is used if a database\n"
161 "           family/key is not specified.\n"
162 "    r    - Indicate ringing to the calling party. Pass no audio to the calling\n"
163 "           party until the called channel has answered.\n"
164 "    S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
165 "           answered the call.\n"       
166 "    t    - Allow the called party to transfer the calling party by sending the\n"
167 "           DTMF sequence defined in features.conf.\n"
168 "    T    - Allow the calling party to transfer the called party by sending the\n"
169 "           DTMF sequence defined in features.conf.\n"
170 "    w    - Allow the called party to enable recording of the call by sending\n"
171 "           the DTMF sequence defined for one-touch recording in features.conf.\n"
172 "    W    - Allow the calling party to enable recording of the call by sending\n"
173 "           the DTMF sequence defined for one-touch recording in features.conf.\n";
174
175 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
176 static char *rapp = "RetryDial";
177 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
178 static char *rdescrip =
179 "  RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
180 "place a call using the normal Dial application. If no channel can be reached,\n"
181 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
182 "seconds before retying the call. After 'retires' number of attempts, the\n"
183 "calling channel will continue at the next priority in the dialplan. If the\n"
184 "'retries' setting is set to 0, this application will retry endlessly.\n"
185 "  While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
186 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
187 "one, The call will jump to that extension immediately.\n"
188 "  The 'dialargs' are specified in the same format that arguments are provided\n"
189 "to the Dial application.\n";
190
191 enum {
192         OPT_ANNOUNCE =          (1 << 0),
193         OPT_RESETCDR =          (1 << 1),
194         OPT_DTMF_EXIT =         (1 << 2),
195         OPT_SENDDTMF =          (1 << 3),
196         OPT_FORCECLID =         (1 << 4),
197         OPT_GO_ON =             (1 << 5),
198         OPT_CALLEE_HANGUP =     (1 << 6),
199         OPT_CALLER_HANGUP =     (1 << 7),
200         OPT_PRIORITY_JUMP =     (1 << 8),
201         OPT_DURATION_LIMIT =    (1 << 9),
202         OPT_MUSICBACK =         (1 << 10),
203         OPT_CALLEE_MACRO =      (1 << 11),
204         OPT_SCREEN_NOINTRO =    (1 << 12),
205         OPT_SCREEN_NOCLID =     (1 << 13),
206         OPT_ORIGINAL_CLID =     (1 << 14),
207         OPT_SCREENING =         (1 << 15),
208         OPT_PRIVACY =           (1 << 16),
209         OPT_RINGBACK =          (1 << 17),
210         OPT_DURATION_STOP =     (1 << 18),
211         OPT_CALLEE_TRANSFER =   (1 << 19),
212         OPT_CALLER_TRANSFER =   (1 << 20),
213         OPT_CALLEE_MONITOR =    (1 << 21),
214         OPT_CALLER_MONITOR =    (1 << 22),
215         OPT_GOTO =              (1 << 23),
216 } dial_exec_option_flags;
217
218 #define DIAL_STILLGOING                 (1 << 30)
219 #define DIAL_NOFORWARDHTML              (1 << 31)
220
221 enum {
222         OPT_ARG_ANNOUNCE = 0,
223         OPT_ARG_SENDDTMF,
224         OPT_ARG_GOTO,
225         OPT_ARG_DURATION_LIMIT,
226         OPT_ARG_MUSICBACK,
227         OPT_ARG_CALLEE_MACRO,
228         OPT_ARG_PRIVACY,
229         OPT_ARG_DURATION_STOP,
230         /* note: this entry _MUST_ be the last one in the enum */
231         OPT_ARG_ARRAY_SIZE,
232 } dial_exec_option_args;
233
234 AST_APP_OPTIONS(dial_exec_options, {
235         AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
236         AST_APP_OPTION('C', OPT_RESETCDR),
237         AST_APP_OPTION('d', OPT_DTMF_EXIT),
238         AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
239         AST_APP_OPTION('f', OPT_FORCECLID),
240         AST_APP_OPTION('g', OPT_GO_ON),
241         AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
242         AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
243         AST_APP_OPTION('H', OPT_CALLER_HANGUP),
244         AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
245         AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
246         AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
247         AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
248         AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
249         AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
250         AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
251         AST_APP_OPTION('p', OPT_SCREENING),
252         AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
253         AST_APP_OPTION('r', OPT_RINGBACK),
254         AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
255         AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
256         AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
257         AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
258         AST_APP_OPTION('W', OPT_CALLER_MONITOR),
259 });
260
261 /* We define a custom "local user" structure because we
262    use it not only for keeping track of what is in use but
263    also for keeping track of who we're dialing. */
264
265 struct dial_localuser {
266         struct ast_channel *chan;
267         unsigned int flags;
268         int forwards;
269         struct dial_localuser *next;
270 };
271
272 LOCAL_USER_DECL;
273
274 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
275 {
276         /* Hang up a tree of stuff */
277         struct dial_localuser *oo;
278         while (outgoing) {
279                 /* Hangup any existing lines we have open */
280                 if (outgoing->chan && (outgoing->chan != exception))
281                         ast_hangup(outgoing->chan);
282                 oo = outgoing;
283                 outgoing=outgoing->next;
284                 free(oo);
285         }
286 }
287
288 #define AST_MAX_FORWARDS   8
289
290 #define AST_MAX_WATCHERS 256
291
292 #define HANDLE_CAUSE(cause, chan) do { \
293         switch(cause) { \
294         case AST_CAUSE_BUSY: \
295                 if (chan->cdr) \
296                         ast_cdr_busy(chan->cdr); \
297                 numbusy++; \
298                 break; \
299         case AST_CAUSE_CONGESTION: \
300                 if (chan->cdr) \
301                         ast_cdr_failed(chan->cdr); \
302                 numcongestion++; \
303                 break; \
304         case AST_CAUSE_UNREGISTERED: \
305                 if (chan->cdr) \
306                         ast_cdr_failed(chan->cdr); \
307                 numnochan++; \
308                 break; \
309         case AST_CAUSE_NORMAL_CLEARING: \
310                 break; \
311         default: \
312                 numnochan++; \
313                 break; \
314         } \
315 } while (0)
316
317
318 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri) 
319 {
320         char rexten[2] = { exten, '\0' };
321
322         if (context) {
323                 if (!ast_goto_if_exists(chan, context, rexten, pri))
324                         return 1;
325         } else {
326                 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
327                         return 1;
328                 else if (!ast_strlen_zero(chan->macrocontext)) {
329                         if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
330                                 return 1;
331                 }
332         }
333         return 0;
334 }
335
336
337 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
338 {
339         const char *context = S_OR(chan->macrocontext, chan->context);
340         const char *exten = S_OR(chan->macroexten, chan->exten);
341
342         return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
343 }
344
345 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
346 {
347         manager_event(EVENT_FLAG_CALL, "Dial", 
348                            "Source: %s\r\n"
349                            "Destination: %s\r\n"
350                            "CallerID: %s\r\n"
351                            "CallerIDName: %s\r\n"
352                            "SrcUniqueID: %s\r\n"
353                            "DestUniqueID: %s\r\n",
354                            src->name, dst->name, src->cid.cid_num ? src->cid.cid_num : "<unknown>",
355                            src->cid.cid_name ? src->cid.cid_name : "<unknown>", src->uniqueid,
356                            dst->uniqueid);
357 }
358
359 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
360 {
361         int numbusy = busystart;
362         int numcongestion = congestionstart;
363         int numnochan = nochanstart;
364         int prestart = busystart + congestionstart + nochanstart;
365         int orig = *to;
366         struct ast_channel *peer = NULL;
367         /* single is set if only one destination is enabled */
368         int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
369         
370         if (single) {
371                 /* Turn off hold music, etc */
372                 ast_deactivate_generator(in);
373                 /* If we are calling a single channel, make them compatible for in-band tone purpose */
374                 ast_channel_make_compatible(outgoing->chan, in);
375         }
376         
377         
378         while (*to && !peer) {
379                 struct dial_localuser *o;
380                 int pos = 0;    /* how many channels do we handle */
381                 int numlines = prestart;
382                 struct ast_channel *winner;
383                 struct ast_channel *watchers[AST_MAX_WATCHERS];
384
385                 watchers[pos++] = in;
386                 for (o = outgoing; o; o = o->next) {
387                         /* Keep track of important channels */
388                         if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
389                                 watchers[pos++] = o->chan;
390                         numlines++;
391                 }
392                 if (pos == 1) { /* only the input channel is available */
393                         if (numlines == (numbusy + numcongestion + numnochan)) {
394                                 if (option_verbose > 2)
395                                         ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
396                                 if (numbusy)
397                                         strcpy(status, "BUSY"); 
398                                 else if (numcongestion)
399                                         strcpy(status, "CONGESTION");
400                                 else if (numnochan)
401                                         strcpy(status, "CHANUNAVAIL");
402                                 if (ast_opt_priority_jumping || priority_jump)
403                                         ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
404                         } else {
405                                 if (option_verbose > 2)
406                                         ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
407                         }
408                         *to = 0;
409                         return NULL;
410                 }
411                 winner = ast_waitfor_n(watchers, pos, to);
412                 for (o = outgoing; o; o = o->next) {
413                         struct ast_frame *f;
414                         struct ast_channel *c = o->chan;
415
416                         if (c == NULL)
417                                 continue;
418                         if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
419                                 if (!peer) {
420                                         if (option_verbose > 2)
421                                                 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
422                                         peer = c;
423                                         ast_copy_flags(peerflags, o,
424                                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
425                                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
426                                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
427                                                        DIAL_NOFORWARDHTML);
428                                 }
429                                 continue;
430                         }
431                         if (c != winner)
432                                 continue;
433                         if (!ast_strlen_zero(c->call_forward)) {
434                                 char tmpchan[256];
435                                 char *stuff;
436                                 char *tech;
437                                 int cause;
438
439                                 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
440                                 if ((stuff = strchr(tmpchan, '/'))) {
441                                         *stuff++ = '\0';
442                                         tech = tmpchan;
443                                 } else {
444                                         const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
445                                         snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
446                                         stuff = tmpchan;
447                                         tech = "Local";
448                                 }
449                                 /* Before processing channel, go ahead and check for forwarding */
450                                 o->forwards++;
451                                 if (o->forwards < AST_MAX_FORWARDS) {
452                                         if (option_verbose > 2)
453                                                 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
454                                         /* Setup parameters */
455                                         c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
456                                         if (!c)
457                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
458                                 } else {
459                                         if (option_verbose > 2)
460                                                 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
461                                         cause = AST_CAUSE_CONGESTION;
462                                         c = o->chan = NULL;
463                                 }
464                                 if (!c) {
465                                         ast_clear_flag(o, DIAL_STILLGOING);     
466                                         HANDLE_CAUSE(cause, in);
467                                 } else {
468                                         ast_rtp_make_compatible(c, in);
469                                         if (c->cid.cid_num)
470                                                 free(c->cid.cid_num);
471                                         c->cid.cid_num = NULL;
472                                         if (c->cid.cid_name)
473                                                 free(c->cid.cid_name);
474                                         c->cid.cid_name = NULL;
475
476                                         if (ast_test_flag(o, OPT_FORCECLID)) {
477                                                 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
478                                                 ast_string_field_set(c, accountcode, winner->accountcode);
479                                                 c->cdrflags = winner->cdrflags;
480                                         } else {
481                                                 c->cid.cid_num = ast_strdup(in->cid.cid_num);
482                                                 c->cid.cid_name = ast_strdup(in->cid.cid_name);
483                                                 ast_string_field_set(c, accountcode, in->accountcode);
484                                                 c->cdrflags = in->cdrflags;
485                                         }
486
487                                         if (in->cid.cid_ani) {
488                                                 if (c->cid.cid_ani)
489                                                         free(c->cid.cid_ani);
490                                                 c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
491                                         }
492                                         if (c->cid.cid_rdnis) 
493                                                 free(c->cid.cid_rdnis);
494                                         c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
495                                         if (ast_call(c, tmpchan, 0)) {
496                                                 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
497                                                 ast_clear_flag(o, DIAL_STILLGOING);     
498                                                 ast_hangup(c);
499                                                 c = o->chan = NULL;
500                                                 numnochan++;
501                                         } else {
502                                                 senddialevent(in, c);
503                                                 /* After calling, set callerid to extension */
504                                                 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
505                                                         char cidname[AST_MAX_EXTENSION];
506                                                         ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
507                                                 }
508                                         }
509                                 }
510                                 /* Hangup the original channel now, in case we needed it */
511                                 ast_hangup(winner);
512                                 continue;
513                         }
514                         f = ast_read(winner);
515                         if (!f) {
516                                 in->hangupcause = c->hangupcause;
517                                 ast_hangup(c);
518                                 c = o->chan = NULL;
519                                 ast_clear_flag(o, DIAL_STILLGOING);
520                                 HANDLE_CAUSE(in->hangupcause, in);
521                                 continue;
522                         }
523                         if (f->frametype == AST_FRAME_CONTROL) {
524                                 switch(f->subclass) {
525                                 case AST_CONTROL_ANSWER:
526                                         /* This is our guy if someone answered. */
527                                         if (!peer) {
528                                                 if (option_verbose > 2)
529                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
530                                                 peer = c;
531                                                 ast_copy_flags(peerflags, o,
532                                                                OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
533                                                                OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
534                                                                OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
535                                                                DIAL_NOFORWARDHTML);
536                                         }
537                                         /* If call has been answered, then the eventual hangup is likely to be normal hangup */
538                                         in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
539                                         c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
540                                         break;
541                                 case AST_CONTROL_BUSY:
542                                         if (option_verbose > 2)
543                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
544                                         in->hangupcause = c->hangupcause;
545                                         ast_hangup(c);
546                                         c = o->chan = NULL;
547                                         ast_clear_flag(o, DIAL_STILLGOING);     
548                                         HANDLE_CAUSE(AST_CAUSE_BUSY, in);
549                                         break;
550                                 case AST_CONTROL_CONGESTION:
551                                         if (option_verbose > 2)
552                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
553                                         in->hangupcause = c->hangupcause;
554                                         ast_hangup(c);
555                                         c = o->chan = NULL;
556                                         ast_clear_flag(o, DIAL_STILLGOING);
557                                         HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
558                                         break;
559                                 case AST_CONTROL_RINGING:
560                                         if (option_verbose > 2)
561                                                 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
562                                         if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
563                                                 ast_indicate(in, AST_CONTROL_RINGING);
564                                                 (*sentringing)++;
565                                         }
566                                         break;
567                                 case AST_CONTROL_PROGRESS:
568                                         if (option_verbose > 2)
569                                                 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
570                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
571                                                 ast_indicate(in, AST_CONTROL_PROGRESS);
572                                         break;
573                                 case AST_CONTROL_VIDUPDATE:
574                                         if (option_verbose > 2)
575                                                 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
576                                         ast_indicate(in, AST_CONTROL_VIDUPDATE);
577                                         break;
578                                 case AST_CONTROL_PROCEEDING:
579                                         if (option_verbose > 2)
580                                                 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
581                                         if (!ast_test_flag(outgoing, OPT_RINGBACK))
582                                                 ast_indicate(in, AST_CONTROL_PROCEEDING);
583                                         break;
584                                 case AST_CONTROL_HOLD:
585                                         if (option_verbose > 2)
586                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
587                                         ast_indicate(in, AST_CONTROL_HOLD);
588                                         break;
589                                 case AST_CONTROL_UNHOLD:
590                                         if (option_verbose > 2)
591                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
592                                         ast_indicate(in, AST_CONTROL_UNHOLD);
593                                         break;
594                                 case AST_CONTROL_OFFHOOK:
595                                 case AST_CONTROL_FLASH:
596                                         /* Ignore going off hook and flash */
597                                         break;
598                                 case -1:
599                                         if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
600                                                 if (option_verbose > 2)
601                                                         ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
602                                                 ast_indicate(in, -1);
603                                                 (*sentringing) = 0;
604                                         }
605                                         break;
606                                 default:
607                                         if (option_debug)
608                                                 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
609                                 }
610                         } else if (single) {
611                                 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
612                                 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
613                                         if (ast_write(in, f)) 
614                                                 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
615                                 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
616                                         if (ast_write(in, f))
617                                                 ast_log(LOG_WARNING, "Unable to forward image\n");
618                                 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
619                                         if (ast_write(in, f))
620                                                 ast_log(LOG_WARNING, "Unable to send text\n");
621                                 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
622                                         if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
623                                                 ast_log(LOG_WARNING, "Unable to send URL\n");
624                                 }
625                         }
626                         ast_frfree(f);
627                 } /* end for */
628                 if (winner == in) {
629                         struct ast_frame *f = ast_read(in);
630 #if 0
631                         if (f && (f->frametype != AST_FRAME_VOICE))
632                                 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
633                         else if (!f || (f->frametype != AST_FRAME_VOICE))
634                                 printf("Hangup received on %s\n", in->name);
635 #endif
636                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
637                                 /* Got hung up */
638                                 *to = -1;
639                                 strcpy(status, "CANCEL");
640                                 if (f)
641                                         ast_frfree(f);
642                                 return NULL;
643                         }
644
645                         if (f && (f->frametype == AST_FRAME_DTMF)) {
646                                 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
647                                         const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
648                                         if (onedigit_goto(in, context, (char) f->subclass, 1)) {
649                                                 if (option_verbose > 2)
650                                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
651                                                 *to=0;
652                                                 *result = f->subclass;
653                                                 strcpy(status, "CANCEL");
654                                                 ast_frfree(f);
655                                                 return NULL;
656                                         }
657                                 }
658
659                                 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
660                                                   (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
661                                         if (option_verbose > 2)
662                                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
663                                         *to=0;
664                                         strcpy(status, "CANCEL");
665                                         ast_frfree(f);
666                                         return NULL;
667                                 }
668                         }
669
670                         /* Forward HTML stuff */
671                         if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
672                                 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
673                                         ast_log(LOG_WARNING, "Unable to send URL\n");
674                         
675
676                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
677                                 if (ast_write(outgoing->chan, f))
678                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
679                         }
680                         if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
681                                 if (option_verbose > 2)
682                                         ast_verbose(VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
683                                 ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
684                         }
685                         ast_frfree(f);
686                 }
687                 if (!*to && (option_verbose > 2))
688                         ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
689         }
690
691         return peer;
692 }
693
694 static void replace_macro_delimiter(char *s)
695 {
696         for (; *s; s++)
697                 if (*s == '^')
698                         *s = '|';
699 }
700
701
702 /* returns true if there is a valid privacy reply */
703 static int valid_priv_reply(struct ast_flags *opts, int res)
704 {
705         if (res < '1')
706                 return 0;
707         if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
708                 return 1;
709         if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
710                 return 1;
711         return 0;
712 }
713
714 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
715 {
716         int res = -1;
717         struct localuser *u;
718         char *rest, *cur;
719         struct dial_localuser *outgoing = NULL;
720         struct ast_channel *peer;
721         int to;
722         int numbusy = 0;
723         int numcongestion = 0;
724         int numnochan = 0;
725         int cause;
726         char numsubst[AST_MAX_EXTENSION];
727         char cidname[AST_MAX_EXTENSION];
728         int privdb_val = 0;
729         unsigned int calldurationlimit = 0;
730         long timelimit = 0;
731         long play_warning = 0;
732         long warning_freq = 0;
733         const char *warning_sound = NULL;
734         const char *end_sound = NULL;
735         const char *start_sound = NULL;
736         char *dtmfcalled = NULL, *dtmfcalling = NULL;
737         char status[256];
738         int play_to_caller = 0, play_to_callee = 0;
739         int sentringing = 0, moh = 0;
740         const char *outbound_group = NULL;
741         int result = 0;
742         time_t start_time;
743         char privintro[1024];
744         char privcid[256];
745         char *parse;
746         AST_DECLARE_APP_ARGS(args,
747                              AST_APP_ARG(peers);
748                              AST_APP_ARG(timeout);
749                              AST_APP_ARG(options);
750                              AST_APP_ARG(url);
751         );
752         struct ast_flags opts = { 0, };
753         char *opt_args[OPT_ARG_ARRAY_SIZE];
754
755         if (ast_strlen_zero(data)) {
756                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
757                 return -1;
758         }
759
760         LOCAL_USER_ADD(u);
761
762         if (!(parse = ast_strdupa(data)))
763                 goto done;
764
765         AST_STANDARD_APP_ARGS(args, parse);
766
767         if (!ast_strlen_zero(args.options) &&
768                         ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
769                 goto done;
770
771         if (ast_strlen_zero(args.peers)) {
772                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
773                 goto done;
774         }
775
776         if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
777                 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
778                 if (!calldurationlimit) {
779                         ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
780                         goto done;
781                 }
782                 if (option_verbose > 2)
783                         ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
784         }
785
786         if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
787                 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
788                 dtmfcalled = strsep(&dtmfcalling, ":");
789         }
790
791         if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
792                 char *limit_str, *warning_str, *warnfreq_str;
793                 const char *var;
794
795                 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
796                 limit_str = strsep(&warnfreq_str, ":");
797                 warning_str = strsep(&warnfreq_str, ":");
798
799                 timelimit = atol(limit_str);
800                 if (warning_str)
801                         play_warning = atol(warning_str);
802                 if (warnfreq_str)
803                         warning_freq = atol(warnfreq_str);
804
805                 if (!timelimit) {
806                         ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
807                         goto done;
808                 } else if (play_warning > timelimit) {
809                         /* If the first warning is requested _after_ the entire call would end,
810                            and no warning frequency is requested, then turn off the warning. If
811                            a warning frequency is requested, reduce the 'first warning' time by
812                            that frequency until it falls within the call's total time limit.
813                         */
814
815                         if (!warning_freq) {
816                                 play_warning = 0;
817                         } else {
818                                 /* XXX fix this!! */
819                                 while (play_warning > timelimit)
820                                         play_warning -= warning_freq;
821                                 if (play_warning < 1)
822                                         play_warning = warning_freq = 0;
823                         }
824                 }
825
826                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
827                 play_to_caller = var ? ast_true(var) : 1;
828                 
829                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
830                 play_to_callee = var ? ast_true(var) : 0;
831                 
832                 if (!play_to_caller && !play_to_callee)
833                         play_to_caller = 1;
834                 
835                 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
836                 warning_sound = S_OR(var, "timeleft");
837                 
838                 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
839                 end_sound = S_OR(var, NULL);    /* XXX not much of a point in doing this! */
840                 
841                 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
842                 start_sound = S_OR(var, NULL);  /* XXX not much of a point in doing this! */
843
844                 /* undo effect of S(x) in case they are both used */
845                 calldurationlimit = 0;
846                 /* more efficient to do it like S(x) does since no advanced opts */
847                 if (!play_warning && !start_sound && !end_sound && timelimit) {
848                         calldurationlimit = timelimit / 1000;
849                         if (option_verbose > 2)
850                                 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
851                         timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
852                 } else if (option_verbose > 2) {
853                         ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
854                         ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", timelimit);
855                         ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", play_warning);
856                         ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
857                         ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
858                         ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", warning_freq);
859                         ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
860                         ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
861                         ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
862                 }
863         }
864
865         if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
866                 ast_cdr_reset(chan->cdr, NULL);
867         if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
868                 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
869         if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
870                 char callerid[60];
871                 char *l = chan->cid.cid_num;    /* XXX watch out, we are overwriting it */
872                 if (!ast_strlen_zero(l)) {
873                         ast_shrink_phone_number(l);
874                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
875                                 if (option_verbose > 2)
876                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
877                                                      opt_args[OPT_ARG_PRIVACY], l);
878                                 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
879                         }
880                         else {
881                                 if (option_verbose > 2)
882                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
883                                 privdb_val = AST_PRIVACY_UNKNOWN;
884                         }
885                 } else {
886                         char *tnam, *tn2;
887
888                         tnam = ast_strdupa(chan->name);
889                         /* clean the channel name so slashes don't try to end up in disk file name */
890                         for(tn2 = tnam; *tn2; tn2++) {
891                                 if( *tn2=='/')
892                                         *tn2 = '=';  /* any other chars to be afraid of? */
893                         }
894                         if (option_verbose > 2)
895                                 ast_verbose(VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
896
897                         snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
898                         l = callerid;
899                         privdb_val = AST_PRIVACY_UNKNOWN;
900                 }
901                 
902                 ast_copy_string(privcid,l,sizeof(privcid));
903
904                 if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */  
905                         if (option_verbose > 2)
906                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
907                         privdb_val = AST_PRIVACY_ALLOW;
908                 }
909                 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
910                         if (option_verbose > 2)
911                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
912                 }
913                 
914                 if(privdb_val == AST_PRIVACY_DENY ) {
915                         if (option_verbose > 2)
916                                 ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
917                         res=0;
918                         goto out;
919                 }
920                 else if(privdb_val == AST_PRIVACY_KILL ) {
921                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
922                         res = 0;
923                         goto out; /* Is this right? */
924                 }
925                 else if(privdb_val == AST_PRIVACY_TORTURE ) {
926                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
927                         res = 0;
928                         goto out; /* is this right??? */
929
930                 }
931                 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
932                         /* Get the user's intro, store it in priv-callerintros/$CID, 
933                            unless it is already there-- this should be done before the 
934                            call is actually dialed  */
935
936                         /* make sure the priv-callerintros dir exists? */
937
938                         snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
939                         if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
940                                 /* the DELUX version of this code would allow this caller the
941                                    option to hear and retape their previously recorded intro.
942                                 */
943                         }
944                         else {
945                                 int duration; /* for feedback from play_and_wait */
946                                 /* the file doesn't exist yet. Let the caller submit his
947                                    vocal intro for posterity */
948                                 /* priv-recordintro script:
949
950                                    "At the tone, please say your name:"
951
952                                 */
953                                 ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
954                                                                                 /* don't think we'll need a lock removed, we took care of
955                                                                                    conflicts by naming the privintro file */
956                         }
957                 }
958         }
959
960         /* If a channel group has been specified, get it for use when we create peer channels */
961         outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
962
963         ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP);
964         /* loop through the list of dial destinations */
965         rest = args.peers;
966         while ((cur = strsep(&rest, "&")) ) {
967                 struct dial_localuser *tmp;
968                 /* Get a technology/[device:]number pair */
969                 char *number = cur;
970                 char *tech = strsep(&number, "/");
971                 if (!number) {
972                         ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
973                         goto out;
974                 }
975                 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
976                         goto out;
977                 if (opts.flags) {
978                         ast_copy_flags(tmp, &opts,
979                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
980                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
981                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
982                                        OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
983                         ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);       
984                 }
985                 ast_copy_string(numsubst, number, sizeof(numsubst));
986                 /* Request the peer */
987                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
988                 if (!tmp->chan) {
989                         /* If we can't, just go on to the next call */
990                         ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
991                         HANDLE_CAUSE(cause, chan);
992                         if (!rest)      /* we are on the last destination */
993                                 chan->hangupcause = cause;
994                         continue;
995                 }
996                 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
997                 if (!ast_strlen_zero(tmp->chan->call_forward)) {
998                         char tmpchan[256];
999                         char *stuff;
1000                         char *tech;
1001                         ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
1002                         if ((stuff = strchr(tmpchan, '/'))) {
1003                                 *stuff++ = '\0';
1004                                 tech = tmpchan;
1005                         } else {
1006                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
1007                                 stuff = tmpchan;
1008                                 tech = "Local";
1009                         }
1010                         tmp->forwards++;
1011                         if (tmp->forwards < AST_MAX_FORWARDS) {
1012                                 if (option_verbose > 2)
1013                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
1014                                 ast_hangup(tmp->chan);
1015                                 /* Setup parameters */
1016                                 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
1017                                 if (!tmp->chan)
1018                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1019                         } else {
1020                                 if (option_verbose > 2)
1021                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
1022                                 ast_hangup(tmp->chan);
1023                                 tmp->chan = NULL;
1024                                 cause = AST_CAUSE_CONGESTION;
1025                         }
1026                         if (!tmp->chan) {
1027                                 HANDLE_CAUSE(cause, chan);
1028                                 continue;
1029                         }
1030                 }
1031
1032                 /* Setup outgoing SDP to match incoming one */
1033                 ast_rtp_make_compatible(tmp->chan, chan);
1034                 
1035                 /* Inherit specially named variables from parent channel */
1036                 ast_channel_inherit_variables(chan, tmp->chan);
1037
1038                 tmp->chan->appl = "AppDial";
1039                 tmp->chan->data = "(Outgoing Line)";
1040                 tmp->chan->whentohangup = 0;
1041
1042                 if (tmp->chan->cid.cid_num)
1043                         free(tmp->chan->cid.cid_num);
1044                 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
1045
1046                 if (tmp->chan->cid.cid_name)
1047                         free(tmp->chan->cid.cid_name);
1048                 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
1049
1050                 if (tmp->chan->cid.cid_ani)
1051                         free(tmp->chan->cid.cid_ani);
1052                 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
1053                 
1054                 /* Copy language from incoming to outgoing */
1055                 ast_string_field_set(tmp->chan, language, chan->language);
1056                 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1057                 tmp->chan->cdrflags = chan->cdrflags;
1058                 if (ast_strlen_zero(tmp->chan->musicclass))
1059                         ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1060                 /* XXX don't we free previous values ? */
1061                 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
1062                 /* Pass callingpres setting */
1063                 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1064                 /* Pass type of number */
1065                 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1066                 /* Pass type of tns */
1067                 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1068                 /* Presense of ADSI CPE on outgoing channel follows ours */
1069                 tmp->chan->adsicpe = chan->adsicpe;
1070                 /* Pass the transfer capability */
1071                 tmp->chan->transfercapability = chan->transfercapability;
1072
1073                 /* If we have an outbound group, set this peer channel to it */
1074                 if (outbound_group)
1075                         ast_app_group_set_channel(tmp->chan, outbound_group);
1076
1077                 /* Place the call, but don't wait on the answer */
1078                 res = ast_call(tmp->chan, numsubst, 0);
1079
1080                 /* Save the info in cdr's that we called them */
1081                 if (chan->cdr)
1082                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1083
1084                 /* check the results of ast_call */
1085                 if (res) {
1086                         /* Again, keep going even if there's an error */
1087                         if (option_debug)
1088                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1089                         else if (option_verbose > 2)
1090                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1091                         ast_hangup(tmp->chan);
1092                         tmp->chan = NULL;
1093                         continue;
1094                 } else {
1095                         senddialevent(chan, tmp->chan);
1096                         if (option_verbose > 2)
1097                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1098                         if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1099                                 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1100                 }
1101                 /* Put them in the list of outgoing thingies...  We're ready now. 
1102                    XXX If we're forcibly removed, these outgoing calls won't get
1103                    hung up XXX */
1104                 ast_set_flag(tmp, DIAL_STILLGOING);     
1105                 tmp->next = outgoing;
1106                 outgoing = tmp;
1107                 /* If this line is up, don't try anybody else */
1108                 if (outgoing->chan->_state == AST_STATE_UP)
1109                         break;
1110         }
1111         
1112         if (ast_strlen_zero(args.timeout)) {
1113                 to = -1;
1114         } else {
1115                 to = atoi(args.timeout);
1116                 if (to > 0)
1117                         to *= 1000;
1118                 else
1119                         ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1120         }
1121
1122         if (!outgoing) {
1123                 strcpy(status, "CHANUNAVAIL");
1124         } else {
1125                 /* Our status will at least be NOANSWER */
1126                 strcpy(status, "NOANSWER");
1127                 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1128                         moh=1;
1129                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1130                 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1131                         ast_indicate(chan, AST_CONTROL_RINGING);
1132                         sentringing++;
1133                 }
1134         }
1135
1136         time(&start_time);
1137         peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1138         
1139         if (!peer) {
1140                 if (result) {
1141                         res = result;
1142                 } else if (to) { /* Musta gotten hung up */
1143                         res = -1;
1144                 } else { /* Nobody answered, next please? */
1145                         res = 0;
1146                 }
1147                 /* almost done, although the 'else' block is 400 lines */
1148         } else {
1149                 const char *number;
1150                 time_t end_time, answer_time = time(NULL);
1151
1152                 strcpy(status, "ANSWER");
1153                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
1154                    we will always return with -1 so that it is hung up properly after the 
1155                    conversation.  */
1156                 hanguptree(outgoing, peer);
1157                 outgoing = NULL;
1158                 /* If appropriate, log that we have a destination channel */
1159                 if (chan->cdr)
1160                         ast_cdr_setdestchan(chan->cdr, peer->name);
1161                 if (peer->name)
1162                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1163
1164                 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1165                 if (!number)
1166                         number = numsubst;
1167                 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1168                 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1169                         if (option_debug)
1170                                 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1171                         ast_channel_sendurl( peer, args.url );
1172                 }
1173                 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
1174                         int res2;
1175                         int loopcount = 0;
1176
1177                         /* Get the user's intro, store it in priv-callerintros/$CID, 
1178                            unless it is already there-- this should be done before the 
1179                            call is actually dialed  */
1180
1181                         /* all ring indications and moh for the caller has been halted as soon as the 
1182                            target extension was picked up. We are going to have to kill some
1183                            time and make the caller believe the peer hasn't picked up yet */
1184
1185                         if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1186                                 ast_indicate(chan, -1);
1187                                 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1188                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1189                                 ast_indicate(chan, AST_CONTROL_RINGING);
1190                                 sentringing++;
1191                         }
1192
1193                         /* Start autoservice on the other chan ?? */
1194                         res2 = ast_autoservice_start(chan);
1195                         /* Now Stream the File */
1196                         for (loopcount = 0; loopcount < 3; loopcount++) {
1197                                 if (res2 && loopcount == 0)     /* error in ast_autoservice_start() */
1198                                         break;
1199                                 if (!res2)      /* on timeout, play the message again */
1200                                         res2 = ast_play_and_wait(peer,"priv-callpending");
1201                                 if (!valid_priv_reply(&opts, res2))
1202                                         res2 = 0;
1203                                 
1204                                 /* priv-callpending script: 
1205                                    "I have a caller waiting, who introduces themselves as:"
1206                                 */
1207                                 if (!res2)
1208                                         res2 = ast_play_and_wait(peer,privintro);
1209                                 if (!valid_priv_reply(&opts, res2))
1210                                         res2 = 0;
1211                                 /* now get input from the called party, as to their choice */
1212                                 if( !res2 ) {
1213                                         /* XXX can we have both, or they are mutually exclusive ? */
1214                                         if( ast_test_flag(&opts, OPT_PRIVACY) )
1215                                                 res2 = ast_play_and_wait(peer,"priv-callee-options");
1216                                         if( ast_test_flag(&opts, OPT_SCREENING) )
1217                                                 res2 = ast_play_and_wait(peer,"screen-callee-options");
1218                                 }
1219                                 /*! \page DialPrivacy Dial Privacy scripts
1220                                 \par priv-callee-options script:
1221                                         "Dial 1 if you wish this caller to reach you directly in the future,
1222                                                 and immediately connect to their incoming call
1223                                          Dial 2 if you wish to send this caller to voicemail now and 
1224                                                 forevermore.
1225                                          Dial 3 to send this caller to the torture menus, now and forevermore.
1226                                          Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1227                                          Dial 5 to allow this caller to come straight thru to you in the future,
1228                                                 but right now, just this once, send them to voicemail."
1229                                 \par screen-callee-options script:
1230                                         "Dial 1 if you wish to immediately connect to the incoming call
1231                                          Dial 2 if you wish to send this caller to voicemail.
1232                                          Dial 3 to send this caller to the torture menus.
1233                                          Dial 4 to send this caller to a simple "go away" menu.
1234                                 */
1235                                 if (valid_priv_reply(&opts, res2))
1236                                         break;
1237                                 /* invalid option */
1238                                 res2 = ast_play_and_wait(peer, "vm-sorry");
1239                         }
1240
1241                         switch(res2) {
1242                         case '1':
1243                                 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1244                                         if (option_verbose > 2)
1245                                                 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1246                                                              opt_args[OPT_ARG_PRIVACY], privcid);
1247                                         ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1248                                 }
1249                                 break;
1250                         case '2':
1251                                 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1252                                         if (option_verbose > 2)
1253                                                 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1254                                                              opt_args[OPT_ARG_PRIVACY], privcid);
1255                                         ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1256                                 }
1257                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1258                                         ast_moh_stop(chan);
1259                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1260                                         ast_indicate(chan, -1);
1261                                         sentringing=0;
1262                                 }
1263                                 res2 = ast_autoservice_stop(chan);
1264                                 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1265                                 res=0;
1266                                 goto out;
1267                         case '3':
1268                                 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1269                                         if (option_verbose > 2)
1270                                                 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1271                                                              opt_args[OPT_ARG_PRIVACY], privcid);
1272                                         ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1273                                 }
1274                                 ast_copy_string(status, "TORTURE", sizeof(status));
1275                                 
1276                                 res = 0;
1277                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1278                                         ast_moh_stop(chan);
1279                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1280                                         ast_indicate(chan, -1);
1281                                         sentringing=0;
1282                                 }
1283                                 res2 = ast_autoservice_stop(chan);
1284                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1285                                 goto out; /* Is this right? */
1286                         case '4':
1287                                 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1288                                         if (option_verbose > 2)
1289                                                 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1290                                                              opt_args[OPT_ARG_PRIVACY], privcid);
1291                                         ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1292                                 }
1293
1294                                 ast_copy_string(status, "DONTCALL", sizeof(status));
1295                                 res = 0;
1296                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1297                                         ast_moh_stop(chan);
1298                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1299                                         ast_indicate(chan, -1);
1300                                         sentringing=0;
1301                                 }
1302                                 res2 = ast_autoservice_stop(chan);
1303                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1304                                 goto out; /* Is this right? */
1305                         case '5':
1306                                 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1307                                         if (option_verbose > 2)
1308                                                 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1309                                                              opt_args[OPT_ARG_PRIVACY], privcid);
1310                                         ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1311                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1312                                                 ast_moh_stop(chan);
1313                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1314                                                 ast_indicate(chan, -1);
1315                                                 sentringing=0;
1316                                         }
1317                                         res2 = ast_autoservice_stop(chan);
1318                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1319                                         res=0;
1320                                         goto out;
1321                                 } /* if not privacy, then 5 is the same as "default" case */
1322                         default:        /* bad input or -1 if failure to start autoservice */
1323                                 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1324                                 /* well, there seems basically two choices. Just patch the caller thru immediately,
1325                                           or,... put 'em thru to voicemail. */
1326                                 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1327                                 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1328                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1329                                         ast_moh_stop(chan);
1330                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1331                                         ast_indicate(chan, -1);
1332                                         sentringing=0;
1333                                 }
1334                                 res2 = ast_autoservice_stop(chan);
1335                                 ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1336                                 res=0;
1337                                 goto out;
1338                         }
1339                         /* XXX we only reach this point in case '1', but all other cases are
1340                          * also doing the same thing inline, so probably this code should
1341                          * be done once before the switch() above.
1342                          */
1343                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1344                                 ast_moh_stop(chan);
1345                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1346                                 ast_indicate(chan, -1);
1347                                 sentringing=0;
1348                         }
1349                         res2 = ast_autoservice_stop(chan);
1350                         /* ---- */
1351
1352                         /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
1353                            just clog things up, and it's not useful information, not being tied to a CID */
1354                         if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1355                                 ast_filedelete(privintro, NULL);
1356                                 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1357                                         ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1358                                 else if (option_verbose > 2)
1359                                         ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1360                         }
1361                 }
1362                 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1363                         res = 0;
1364                 } else {
1365                         int digit = 0;
1366                         /* Start autoservice on the other chan */
1367                         res = ast_autoservice_start(chan);
1368                         /* Now Stream the File */
1369                         if (!res)
1370                                 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1371                         if (!res) {
1372                                 digit = ast_waitstream(peer, AST_DIGIT_ANY); 
1373                         }
1374                         /* Ok, done. stop autoservice */
1375                         res = ast_autoservice_stop(chan);
1376                         if (digit > 0 && !res)
1377                                 res = ast_senddigit(chan, digit); 
1378                         else
1379                                 res = digit;
1380
1381                 }
1382
1383                 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1384                         replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1385                         ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1386                         ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1387                         peer->priority++;
1388                         ast_pbx_start(peer);
1389                         hanguptree(outgoing, NULL);
1390                         res = 0;
1391                         goto done;
1392                 }
1393
1394                 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1395                         struct ast_app *theapp;
1396                         const char *macro_result;
1397
1398                         res = ast_autoservice_start(chan);
1399                         if (res) {
1400                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1401                                 res = -1;
1402                         }
1403
1404                         theapp = pbx_findapp("Macro");
1405
1406                         if (theapp && !res) {   /* XXX why check res here ? */
1407                                 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1408                                 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1409                                 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1410                                 res = 0;
1411                         } else {
1412                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
1413                                 res = -1;
1414                         }
1415
1416                         if (ast_autoservice_stop(chan) < 0) {
1417                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1418                                 res = -1;
1419                         }
1420
1421                         if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1422                                         char *macro_transfer_dest;
1423
1424                                         if (!strcasecmp(macro_result, "BUSY")) {
1425                                                 ast_copy_string(status, macro_result, sizeof(status));
1426                                                 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1427                                                         if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1428                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1429                                                         }
1430                                                 } else
1431                                                         ast_set_flag(peerflags, OPT_GO_ON);
1432                                                 res = -1;
1433                                         } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1434                                                 ast_copy_string(status, macro_result, sizeof(status));
1435                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1436                                                 res = -1;
1437                                         } else if (!strcasecmp(macro_result, "CONTINUE")) {
1438                                                 /* hangup peer and keep chan alive assuming the macro has changed 
1439                                                    the context / exten / priority or perhaps 
1440                                                    the next priority in the current exten is desired.
1441                                                 */
1442                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1443                                                 res = -1;
1444                                         } else if (!strcasecmp(macro_result, "ABORT")) {
1445                                                 /* Hangup both ends unless the caller has the g flag */
1446                                                 res = -1;
1447                                         } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1448                                                 res = -1;
1449                                                 /* perform a transfer to a new extension */
1450                                                 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1451                                                         replace_macro_delimiter(macro_transfer_dest);
1452                                                         if (!ast_parseable_goto(chan, macro_transfer_dest))
1453                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1454
1455                                                 }
1456                                         }
1457                         }
1458                 }
1459
1460                 if (!res) {
1461                         if (calldurationlimit > 0) {
1462                                 chan->whentohangup = time(NULL) + calldurationlimit;
1463                         }
1464                         if (!ast_strlen_zero(dtmfcalled)) { 
1465                                 if (option_verbose > 2)
1466                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1467                                 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1468                         }
1469                         if (!ast_strlen_zero(dtmfcalling)) {
1470                                 if (option_verbose > 2)
1471                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1472                                 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1473                         }
1474                 }
1475                 
1476                 if (!res) {
1477                         struct ast_bridge_config config;
1478
1479                         memset(&config,0,sizeof(struct ast_bridge_config));
1480                         if (play_to_caller)
1481                                 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1482                         if (play_to_callee)
1483                                 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1484                         if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1485                                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1486                         if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1487                                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1488                         if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1489                                 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1490                         if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1491                                 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1492                         if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1493                                 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1494                         if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) 
1495                                 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1496
1497                         config.timelimit = timelimit;
1498                         config.play_warning = play_warning;
1499                         config.warning_freq = warning_freq;
1500                         config.warning_sound = warning_sound;
1501                         config.end_sound = end_sound;
1502                         config.start_sound = start_sound;
1503                         if (moh) {
1504                                 moh = 0;
1505                                 ast_moh_stop(chan);
1506                         } else if (sentringing) {
1507                                 sentringing = 0;
1508                                 ast_indicate(chan, -1);
1509                         }
1510                         /* Be sure no generators are left on it */
1511                         ast_deactivate_generator(chan);
1512                         /* Make sure channels are compatible */
1513                         res = ast_channel_make_compatible(chan, peer);
1514                         if (res < 0) {
1515                                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1516                                 ast_hangup(peer);
1517                                 res = -1;
1518                                 goto done;
1519                         }
1520                         res = ast_bridge_call(chan,peer,&config);
1521                         time(&end_time);
1522                         {
1523                                 char toast[80];
1524                                 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1525                                 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1526                         }
1527                 } else {
1528                         time(&end_time);
1529                         res = -1;
1530                 }
1531                 {
1532                         char toast[80];
1533                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1534                         pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1535                 }
1536                 
1537                 if (res != AST_PBX_NO_HANGUP_PEER) {
1538                         if (!chan->_softhangup)
1539                                 chan->hangupcause = peer->hangupcause;
1540                         ast_hangup(peer);
1541                 }
1542         }       
1543 out:
1544         if (moh) {
1545                 moh = 0;
1546                 ast_moh_stop(chan);
1547         } else if (sentringing) {
1548                 sentringing = 0;
1549                 ast_indicate(chan, -1);
1550         }
1551         hanguptree(outgoing, NULL);
1552         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1553         if (option_debug)
1554                 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1555         
1556         if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1557                 res = 0;
1558
1559 done:
1560         LOCAL_USER_REMOVE(u);    
1561         return res;
1562 }
1563
1564 static int dial_exec(struct ast_channel *chan, void *data)
1565 {
1566         struct ast_flags peerflags;
1567         memset(&peerflags, 0, sizeof(peerflags));
1568         return dial_exec_full(chan, data, &peerflags);
1569 }
1570
1571 static int retrydial_exec(struct ast_channel *chan, void *data)
1572 {
1573         char *announce = NULL, *dialdata = NULL;
1574         const char *context = NULL;
1575         int sleep = 0, loops = 0, res = -1;
1576         struct localuser *u;
1577         struct ast_flags peerflags;
1578         
1579         if (ast_strlen_zero(data)) {
1580                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1581                 return -1;
1582         }       
1583
1584         LOCAL_USER_ADD(u);
1585
1586         if (!(announce = ast_strdupa(data)))
1587                 goto done;
1588
1589         memset(&peerflags, 0, sizeof(peerflags));
1590
1591         if ((dialdata = strchr(announce, '|'))) {
1592                 *dialdata++ = '\0';
1593                 if ((sleep = atoi(dialdata))) {
1594                         sleep *= 1000;
1595                 } else {
1596                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1597                         goto done;
1598                 }
1599                 if ((dialdata = strchr(dialdata, '|'))) {
1600                         *dialdata++ = '\0';
1601                         if (!(loops = atoi(dialdata))) {
1602                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1603                                 goto done;
1604                         }
1605                 }
1606         }
1607         
1608         if ((dialdata = strchr(dialdata, '|'))) {
1609                 *dialdata++ = '\0';
1610         } else {
1611                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1612                 goto done;
1613         }
1614                 
1615         if (sleep < 1000)
1616                 sleep = 10000;
1617
1618         if (!loops)
1619                 loops = -1;     /* run forever */
1620         
1621         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1622
1623         res = 0;
1624         while (loops) {
1625                 chan->data = "Retrying";
1626                 if (ast_test_flag(chan, AST_FLAG_MOH))
1627                         ast_moh_stop(chan);
1628
1629                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1630                         if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1631                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1632                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1633                                 if (!res && sleep) {
1634                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1635                                                 ast_moh_start(chan, NULL);
1636                                         res = ast_waitfordigit(chan, sleep);
1637                                 }
1638                         } else {
1639                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1640                                         res = ast_waitstream(chan, "");
1641                                 if (sleep) {
1642                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1643                                                 ast_moh_start(chan, NULL);
1644                                         if (!res) 
1645                                                 res = ast_waitfordigit(chan, sleep);
1646                                 }
1647                         }
1648                 }
1649
1650                 if (res < 0)
1651                         break;
1652                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1653                         if (onedigit_goto(chan, context, (char) res, 1)) {
1654                                 res = 0;
1655                                 break;
1656                         }
1657                 }
1658                 loops--;
1659         }
1660         if (loops == 0)
1661                 res = 0;
1662         
1663         if (ast_test_flag(chan, AST_FLAG_MOH))
1664                 ast_moh_stop(chan);
1665 done:
1666         LOCAL_USER_REMOVE(u);
1667         return res;
1668 }
1669
1670 static int unload_module(void *mod)
1671 {
1672         int res;
1673
1674         res = ast_unregister_application(app);
1675         res |= ast_unregister_application(rapp);
1676
1677         STANDARD_HANGUP_LOCALUSERS;
1678         
1679         return res;
1680 }
1681
1682 static int load_module(void *mod)
1683 {
1684         int res;
1685
1686         res = ast_register_application(app, dial_exec, synopsis, descrip);
1687         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1688         
1689         return res;
1690 }
1691
1692 static const char *description(void)
1693 {
1694         return "Dialing Application";
1695 }
1696
1697 static const char *key(void)
1698 {
1699         return ASTERISK_GPL_KEY;
1700 }
1701
1702 STD_MOD(MOD_1, NULL, NULL, NULL);