40b9e9145e89e833091d70f07211c1983e023e26
[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 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
702 {
703         int res = -1;
704         struct localuser *u;
705         char *rest, *cur;
706         struct dial_localuser *outgoing = NULL;
707         struct ast_channel *peer;
708         int to;
709         int numbusy = 0;
710         int numcongestion = 0;
711         int numnochan = 0;
712         int cause;
713         char numsubst[AST_MAX_EXTENSION];
714         char cidname[AST_MAX_EXTENSION];
715         int privdb_val = 0;
716         unsigned int calldurationlimit = 0;
717         long timelimit = 0;
718         long play_warning = 0;
719         long warning_freq = 0;
720         const char *warning_sound = NULL;
721         const char *end_sound = NULL;
722         const char *start_sound = NULL;
723         char *dtmfcalled = NULL, *dtmfcalling = NULL;
724         char status[256];
725         int play_to_caller = 0, play_to_callee = 0;
726         int sentringing = 0, moh = 0;
727         const char *outbound_group = NULL;
728         int result = 0;
729         time_t start_time;
730         char privintro[1024];
731         char privcid[256];
732         char *parse;
733         AST_DECLARE_APP_ARGS(args,
734                              AST_APP_ARG(peers);
735                              AST_APP_ARG(timeout);
736                              AST_APP_ARG(options);
737                              AST_APP_ARG(url);
738         );
739         struct ast_flags opts = { 0, };
740         char *opt_args[OPT_ARG_ARRAY_SIZE];
741
742         if (ast_strlen_zero(data)) {
743                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
744                 return -1;
745         }
746
747         LOCAL_USER_ADD(u);
748
749         if (!(parse = ast_strdupa(data)))
750                 goto done;
751
752         AST_STANDARD_APP_ARGS(args, parse);
753
754         if (!ast_strlen_zero(args.options) &&
755                         ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
756                 goto done;
757
758         if (ast_strlen_zero(args.peers)) {
759                 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
760                 goto done;
761         }
762
763         if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
764                 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
765                 if (!calldurationlimit) {
766                         ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
767                         goto done;
768                 }
769                 if (option_verbose > 2)
770                         ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
771         }
772
773         if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
774                 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
775                 dtmfcalled = strsep(&dtmfcalling, ":");
776         }
777
778         if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
779                 char *limit_str, *warning_str, *warnfreq_str;
780                 const char *var;
781
782                 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
783                 limit_str = strsep(&warnfreq_str, ":");
784                 warning_str = strsep(&warnfreq_str, ":");
785
786                 timelimit = atol(limit_str);
787                 if (warning_str)
788                         play_warning = atol(warning_str);
789                 if (warnfreq_str)
790                         warning_freq = atol(warnfreq_str);
791
792                 if (!timelimit) {
793                         ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
794                         goto done;
795                 } else if (play_warning > timelimit) {
796                         /* If the first warning is requested _after_ the entire call would end,
797                            and no warning frequency is requested, then turn off the warning. If
798                            a warning frequency is requested, reduce the 'first warning' time by
799                            that frequency until it falls within the call's total time limit.
800                         */
801
802                         if (!warning_freq) {
803                                 play_warning = 0;
804                         } else {
805                                 /* XXX fix this!! */
806                                 while (play_warning > timelimit)
807                                         play_warning -= warning_freq;
808                                 if (play_warning < 1)
809                                         play_warning = warning_freq = 0;
810                         }
811                 }
812
813                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
814                 play_to_caller = var ? ast_true(var) : 1;
815                 
816                 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
817                 play_to_callee = var ? ast_true(var) : 0;
818                 
819                 if (!play_to_caller && !play_to_callee)
820                         play_to_caller = 1;
821                 
822                 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
823                 warning_sound = S_OR(var, "timeleft");
824                 
825                 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
826                 end_sound = S_OR(var, NULL);    /* XXX not much of a point in doing this! */
827                 
828                 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
829                 start_sound = S_OR(var, NULL);  /* XXX not much of a point in doing this! */
830
831                 /* undo effect of S(x) in case they are both used */
832                 calldurationlimit = 0;
833                 /* more efficient to do it like S(x) does since no advanced opts */
834                 if (!play_warning && !start_sound && !end_sound && timelimit) {
835                         calldurationlimit = timelimit / 1000;
836                         if (option_verbose > 2)
837                                 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
838                         timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
839                 } else if (option_verbose > 2) {
840                         ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
841                         ast_verbose(VERBOSE_PREFIX_4 "timelimit      = %ld\n", timelimit);
842                         ast_verbose(VERBOSE_PREFIX_4 "play_warning   = %ld\n", play_warning);
843                         ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
844                         ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
845                         ast_verbose(VERBOSE_PREFIX_4 "warning_freq   = %ld\n", warning_freq);
846                         ast_verbose(VERBOSE_PREFIX_4 "start_sound    = %s\n", start_sound);
847                         ast_verbose(VERBOSE_PREFIX_4 "warning_sound  = %s\n", warning_sound);
848                         ast_verbose(VERBOSE_PREFIX_4 "end_sound      = %s\n", end_sound);
849                 }
850         }
851
852         if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
853                 ast_cdr_reset(chan->cdr, NULL);
854         if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
855                 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
856         if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
857                 char callerid[60];
858                 char *l = chan->cid.cid_num;    /* XXX watch out, we are overwriting it */
859                 if (!ast_strlen_zero(l)) {
860                         ast_shrink_phone_number(l);
861                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
862                                 if (option_verbose > 2)
863                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy DB is '%s', clid is '%s'\n",
864                                                      opt_args[OPT_ARG_PRIVACY], l);
865                                 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
866                         }
867                         else {
868                                 if (option_verbose > 2)
869                                         ast_verbose(VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
870                                 privdb_val = AST_PRIVACY_UNKNOWN;
871                         }
872                 } else {
873                         char *tnam, *tn2;
874
875                         tnam = ast_strdupa(chan->name);
876                         /* clean the channel name so slashes don't try to end up in disk file name */
877                         for(tn2 = tnam; *tn2; tn2++) {
878                                 if( *tn2=='/')
879                                         *tn2 = '=';  /* any other chars to be afraid of? */
880                         }
881                         if (option_verbose > 2)
882                                 ast_verbose(VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
883
884                         snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
885                         l = callerid;
886                         privdb_val = AST_PRIVACY_UNKNOWN;
887                 }
888                 
889                 ast_copy_string(privcid,l,sizeof(privcid));
890
891                 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 */  
892                         if (option_verbose > 2)
893                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
894                         privdb_val = AST_PRIVACY_ALLOW;
895                 }
896                 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
897                         if (option_verbose > 2)
898                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
899                 }
900                 
901                 if(privdb_val == AST_PRIVACY_DENY ) {
902                         if (option_verbose > 2)
903                                 ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
904                         res=0;
905                         goto out;
906                 }
907                 else if(privdb_val == AST_PRIVACY_KILL ) {
908                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
909                         res = 0;
910                         goto out; /* Is this right? */
911                 }
912                 else if(privdb_val == AST_PRIVACY_TORTURE ) {
913                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
914                         res = 0;
915                         goto out; /* is this right??? */
916
917                 }
918                 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
919                         /* Get the user's intro, store it in priv-callerintros/$CID, 
920                            unless it is already there-- this should be done before the 
921                            call is actually dialed  */
922
923                         /* make sure the priv-callerintros dir exists? */
924
925                         snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
926                         if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
927                                 /* the DELUX version of this code would allow this caller the
928                                    option to hear and retape their previously recorded intro.
929                                 */
930                         }
931                         else {
932                                 int duration; /* for feedback from play_and_wait */
933                                 /* the file doesn't exist yet. Let the caller submit his
934                                    vocal intro for posterity */
935                                 /* priv-recordintro script:
936
937                                    "At the tone, please say your name:"
938
939                                 */
940                                 ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
941                                                                                 /* don't think we'll need a lock removed, we took care of
942                                                                                    conflicts by naming the privintro file */
943                         }
944                 }
945         }
946
947         /* If a channel group has been specified, get it for use when we create peer channels */
948         outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
949
950         ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP);
951         /* loop through the list of dial destinations */
952         rest = args.peers;
953         while ((cur = strsep(&rest, "&")) ) {
954                 struct dial_localuser *tmp;
955                 /* Get a technology/[device:]number pair */
956                 char *number = cur;
957                 char *tech = strsep(&number, "/");
958                 if (!number) {
959                         ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
960                         goto out;
961                 }
962                 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
963                         goto out;
964                 if (opts.flags) {
965                         ast_copy_flags(tmp, &opts,
966                                        OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
967                                        OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
968                                        OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
969                                        OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
970                         ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);       
971                 }
972                 ast_copy_string(numsubst, number, sizeof(numsubst));
973                 /* Request the peer */
974                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
975                 if (!tmp->chan) {
976                         /* If we can't, just go on to the next call */
977                         ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
978                         HANDLE_CAUSE(cause, chan);
979                         if (!rest)      /* we are on the last destination */
980                                 chan->hangupcause = cause;
981                         continue;
982                 }
983                 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
984                 if (!ast_strlen_zero(tmp->chan->call_forward)) {
985                         char tmpchan[256];
986                         char *stuff;
987                         char *tech;
988                         ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
989                         if ((stuff = strchr(tmpchan, '/'))) {
990                                 *stuff++ = '\0';
991                                 tech = tmpchan;
992                         } else {
993                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
994                                 stuff = tmpchan;
995                                 tech = "Local";
996                         }
997                         tmp->forwards++;
998                         if (tmp->forwards < AST_MAX_FORWARDS) {
999                                 if (option_verbose > 2)
1000                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
1001                                 ast_hangup(tmp->chan);
1002                                 /* Setup parameters */
1003                                 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
1004                                 if (!tmp->chan)
1005                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1006                         } else {
1007                                 if (option_verbose > 2)
1008                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
1009                                 ast_hangup(tmp->chan);
1010                                 tmp->chan = NULL;
1011                                 cause = AST_CAUSE_CONGESTION;
1012                         }
1013                         if (!tmp->chan) {
1014                                 HANDLE_CAUSE(cause, chan);
1015                                 continue;
1016                         }
1017                 }
1018
1019                 /* Setup outgoing SDP to match incoming one */
1020                 ast_rtp_make_compatible(tmp->chan, chan);
1021                 
1022                 /* Inherit specially named variables from parent channel */
1023                 ast_channel_inherit_variables(chan, tmp->chan);
1024
1025                 tmp->chan->appl = "AppDial";
1026                 tmp->chan->data = "(Outgoing Line)";
1027                 tmp->chan->whentohangup = 0;
1028
1029                 if (tmp->chan->cid.cid_num)
1030                         free(tmp->chan->cid.cid_num);
1031                 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
1032
1033                 if (tmp->chan->cid.cid_name)
1034                         free(tmp->chan->cid.cid_name);
1035                 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
1036
1037                 if (tmp->chan->cid.cid_ani)
1038                         free(tmp->chan->cid.cid_ani);
1039                 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
1040                 
1041                 /* Copy language from incoming to outgoing */
1042                 ast_string_field_set(tmp->chan, language, chan->language);
1043                 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
1044                 tmp->chan->cdrflags = chan->cdrflags;
1045                 if (ast_strlen_zero(tmp->chan->musicclass))
1046                         ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
1047                 /* XXX don't we free previous values ? */
1048                 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
1049                 /* Pass callingpres setting */
1050                 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1051                 /* Pass type of number */
1052                 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1053                 /* Pass type of tns */
1054                 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1055                 /* Presense of ADSI CPE on outgoing channel follows ours */
1056                 tmp->chan->adsicpe = chan->adsicpe;
1057                 /* Pass the transfer capability */
1058                 tmp->chan->transfercapability = chan->transfercapability;
1059
1060                 /* If we have an outbound group, set this peer channel to it */
1061                 if (outbound_group)
1062                         ast_app_group_set_channel(tmp->chan, outbound_group);
1063
1064                 /* Place the call, but don't wait on the answer */
1065                 res = ast_call(tmp->chan, numsubst, 0);
1066
1067                 /* Save the info in cdr's that we called them */
1068                 if (chan->cdr)
1069                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1070
1071                 /* check the results of ast_call */
1072                 if (res) {
1073                         /* Again, keep going even if there's an error */
1074                         if (option_debug)
1075                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1076                         else if (option_verbose > 2)
1077                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1078                         ast_hangup(tmp->chan);
1079                         tmp->chan = NULL;
1080                         continue;
1081                 } else {
1082                         senddialevent(chan, tmp->chan);
1083                         if (option_verbose > 2)
1084                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1085                         if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
1086                                 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
1087                 }
1088                 /* Put them in the list of outgoing thingies...  We're ready now. 
1089                    XXX If we're forcibly removed, these outgoing calls won't get
1090                    hung up XXX */
1091                 ast_set_flag(tmp, DIAL_STILLGOING);     
1092                 tmp->next = outgoing;
1093                 outgoing = tmp;
1094                 /* If this line is up, don't try anybody else */
1095                 if (outgoing->chan->_state == AST_STATE_UP)
1096                         break;
1097         }
1098         
1099         if (ast_strlen_zero(args.timeout)) {
1100                 to = -1;
1101         } else {
1102                 to = atoi(args.timeout);
1103                 if (to > 0)
1104                         to *= 1000;
1105                 else
1106                         ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
1107         }
1108
1109         if (!outgoing) {
1110                 strcpy(status, "CHANUNAVAIL");
1111         } else {
1112                 /* Our status will at least be NOANSWER */
1113                 strcpy(status, "NOANSWER");
1114                 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
1115                         moh=1;
1116                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1117                 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
1118                         ast_indicate(chan, AST_CONTROL_RINGING);
1119                         sentringing++;
1120                 }
1121         }
1122
1123         time(&start_time);
1124         peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
1125         
1126         if (!peer) {
1127                 if (result) {
1128                         res = result;
1129                 } else if (to) { /* Musta gotten hung up */
1130                         res = -1;
1131                 } else { /* Nobody answered, next please? */
1132                         res = 0;
1133                 }
1134                 /* almost done, although the 'else' block is 400 lines */
1135         } else {
1136                 const char *number;
1137                 time_t end_time, answer_time = time(NULL);
1138
1139                 strcpy(status, "ANSWER");
1140                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
1141                    we will always return with -1 so that it is hung up properly after the 
1142                    conversation.  */
1143                 hanguptree(outgoing, peer);
1144                 outgoing = NULL;
1145                 /* If appropriate, log that we have a destination channel */
1146                 if (chan->cdr)
1147                         ast_cdr_setdestchan(chan->cdr, peer->name);
1148                 if (peer->name)
1149                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1150
1151                 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1152                 if (!number)
1153                         number = numsubst;
1154                 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1155                 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
1156                         if (option_debug)
1157                                 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
1158                         ast_channel_sendurl( peer, args.url );
1159                 }
1160                 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
1161                         int res2;
1162                         int loopcount = 0;
1163                         if( privdb_val == AST_PRIVACY_UNKNOWN ) {
1164
1165                                 /* Get the user's intro, store it in priv-callerintros/$CID, 
1166                                    unless it is already there-- this should be done before the 
1167                                    call is actually dialed  */
1168
1169                                 /* all ring indications and moh for the caller has been halted as soon as the 
1170                                    target extension was picked up. We are going to have to kill some
1171                                    time and make the caller believe the peer hasn't picked up yet */
1172
1173                                 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1174                                         ast_indicate(chan, -1);
1175                                         ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK]);
1176                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1177                                         ast_indicate(chan, AST_CONTROL_RINGING);
1178                                         sentringing++;
1179                                 }
1180
1181                                 /* Start autoservice on the other chan ?? */
1182                                 res2 = ast_autoservice_start(chan);
1183                                 /* Now Stream the File */
1184                                 if (!res2) {
1185                                         do {
1186                                                 if (!res2)
1187                                                         res2 = ast_play_and_wait(peer,"priv-callpending");
1188                                                 if( res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2>'5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1189                                                         res2 = 0;
1190                                                 
1191                                                 /* priv-callpending script: 
1192                                                    "I have a caller waiting, who introduces themselves as:"
1193                                                 */
1194                                                 if (!res2)
1195                                                         res2 = ast_play_and_wait(peer,privintro);
1196                                                 if( res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2>'5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1197                                                         res2 = 0;
1198                                                 /* now get input from the called party, as to their choice */
1199                                                 if( !res2 ) {
1200                                                         if( ast_test_flag(&opts, OPT_PRIVACY) )
1201                                                                 res2 = ast_play_and_wait(peer,"priv-callee-options");
1202                                                         if( ast_test_flag(&opts, OPT_SCREENING) )
1203                                                                 res2 = ast_play_and_wait(peer,"screen-callee-options");
1204                                                 }
1205                                                 /*! \page DialPrivacy Dial Privacy scripts
1206                                                 \par priv-callee-options script:
1207                                                         "Dial 1 if you wish this caller to reach you directly in the future,
1208                                                                 and immediately connect to their incoming call
1209                                                          Dial 2 if you wish to send this caller to voicemail now and 
1210                                                                 forevermore.
1211                                                          Dial 3 to send this callerr to the torture menus, now and forevermore.
1212                                                          Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1213                                                          Dial 5 to allow this caller to come straight thru to you in the future,
1214                                                                 but right now, just this once, send them to voicemail."
1215                                                 \par screen-callee-options script:
1216                                                         "Dial 1 if you wish to immediately connect to the incoming call
1217                                                          Dial 2 if you wish to send this caller to voicemail.
1218                                                          Dial 3 to send this callerr to the torture menus.
1219                                                          Dial 4 to send this caller to a simple "go away" menu.
1220                                                 */
1221                                                 if(!res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4') ) {
1222                                                         /* invalid option */
1223                                                         res2 = ast_play_and_wait(peer, "vm-sorry");
1224                                                 }
1225                                                 loopcount++; /* give the callee a couple chances to make a choice */
1226                                         } while( (!res2 || res2 < '1' || (ast_test_flag(&opts, OPT_PRIVACY) && res2 > '5') || (ast_test_flag(&opts, OPT_SCREENING) && res2 > '4')) && loopcount < 2 );
1227                                 }
1228
1229                                 switch(res2) {
1230                                 case '1':
1231                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1232                                                 if (option_verbose > 2)
1233                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1234                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1235                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1236                                         }
1237                                         break;
1238                                 case '2':
1239                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1240                                                 if (option_verbose > 2)
1241                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
1242                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1243                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
1244                                         }
1245                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1246                                                 ast_moh_stop(chan);
1247                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1248                                                 ast_indicate(chan, -1);
1249                                                 sentringing=0;
1250                                         }
1251                                         res2 = ast_autoservice_stop(chan);
1252                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1253                                         res=0;
1254                                         goto out;
1255                                 case '3':
1256                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1257                                                 if (option_verbose > 2)
1258                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
1259                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1260                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
1261                                         }
1262                                         ast_copy_string(status, "TORTURE", sizeof(status));
1263                                         
1264                                         res = 0;
1265                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1266                                                 ast_moh_stop(chan);
1267                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1268                                                 ast_indicate(chan, -1);
1269                                                 sentringing=0;
1270                                         }
1271                                         res2 = ast_autoservice_stop(chan);
1272                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1273                                         goto out; /* Is this right? */
1274                                 case '4':
1275                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1276                                                 if (option_verbose > 2)
1277                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
1278                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1279                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
1280                                         }
1281
1282                                         ast_copy_string(status, "DONTCALL", sizeof(status));
1283                                         res = 0;
1284                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1285                                                 ast_moh_stop(chan);
1286                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1287                                                 ast_indicate(chan, -1);
1288                                                 sentringing=0;
1289                                         }
1290                                         res2 = ast_autoservice_stop(chan);
1291                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1292                                         goto out; /* Is this right? */
1293                                 case '5':
1294                                         if( ast_test_flag(&opts, OPT_PRIVACY) ) {
1295                                                 if (option_verbose > 2)
1296                                                         ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
1297                                                                      opt_args[OPT_ARG_PRIVACY], privcid);
1298                                                 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
1299                                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1300                                                         ast_moh_stop(chan);
1301                                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1302                                                         ast_indicate(chan, -1);
1303                                                         sentringing=0;
1304                                                 }
1305                                                 res2 = ast_autoservice_stop(chan);
1306                                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1307                                                 res=0;
1308                                                 goto out;
1309                                         } /* if not privacy, then 5 is the same as "default" case */
1310                                 default:
1311                                         /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1312                                         /* well, there seems basically two choices. Just patch the caller thru immediately,
1313                                                   or,... put 'em thru to voicemail. */
1314                                         /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1315                                         ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1316                                         if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1317                                                 ast_moh_stop(chan);
1318                                         } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1319                                                 ast_indicate(chan, -1);
1320                                                 sentringing=0;
1321                                         }
1322                                         res2 = ast_autoservice_stop(chan);
1323                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1324                                         res=0;
1325                                         goto out;
1326                                 }
1327                                 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
1328                                         ast_moh_stop(chan);
1329                                 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
1330                                         ast_indicate(chan, -1);
1331                                         sentringing=0;
1332                                 }
1333                                 res2 = ast_autoservice_stop(chan);
1334                                 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
1335                                    just clog things up, and it's not useful information, not being tied to a CID */
1336                                 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
1337                                         ast_filedelete(privintro, NULL);
1338                                         if( ast_fileexists(privintro, NULL, NULL ) > 0 )
1339                                                 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
1340                                         else if (option_verbose > 2)
1341                                                 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1342                                 }
1343                         }
1344                 }
1345                 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
1346                         res = 0;
1347                 } else {
1348                         int digit = 0;
1349                         /* Start autoservice on the other chan */
1350                         res = ast_autoservice_start(chan);
1351                         /* Now Stream the File */
1352                         if (!res)
1353                                 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
1354                         if (!res) {
1355                                 digit = ast_waitstream(peer, AST_DIGIT_ANY); 
1356                         }
1357                         /* Ok, done. stop autoservice */
1358                         res = ast_autoservice_stop(chan);
1359                         if (digit > 0 && !res)
1360                                 res = ast_senddigit(chan, digit); 
1361                         else
1362                                 res = digit;
1363
1364                 }
1365
1366                 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
1367                         replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
1368                         ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
1369                         ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
1370                         peer->priority++;
1371                         ast_pbx_start(peer);
1372                         hanguptree(outgoing, NULL);
1373                         res = 0;
1374                         goto done;
1375                 }
1376
1377                 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
1378                         struct ast_app *theapp;
1379
1380                         res = ast_autoservice_start(chan);
1381                         if (res) {
1382                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1383                                 res = -1;
1384                         }
1385
1386                         theapp = pbx_findapp("Macro");
1387
1388                         if (theapp && !res) {   /* XXX why check res here ? */
1389                                 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
1390                                 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
1391                                 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1392                                 res = 0;
1393                         } else {
1394                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
1395                                 res = -1;
1396                         }
1397
1398                         if (ast_autoservice_stop(chan) < 0) {
1399                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1400                                 res = -1;
1401                         }
1402
1403                         if (!res) {
1404                                 const char *macro_result;
1405                                 if ((macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1406                                         char *macro_transfer_dest;
1407
1408                                         if (!strcasecmp(macro_result, "BUSY")) {
1409                                                 ast_copy_string(status, macro_result, sizeof(status));
1410                                                 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
1411                                                         if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1412                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1413                                                         }
1414                                                 } else
1415                                                         ast_set_flag(peerflags, OPT_GO_ON);
1416                                                 res = -1;
1417                                         }
1418                                         else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1419                                                 ast_copy_string(status, macro_result, sizeof(status));
1420                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1421                                                 res = -1;
1422                                         }
1423                                         else if (!strcasecmp(macro_result, "CONTINUE")) {
1424                                                 /* hangup peer and keep chan alive assuming the macro has changed 
1425                                                    the context / exten / priority or perhaps 
1426                                                    the next priority in the current exten is desired.
1427                                                 */
1428                                                 ast_set_flag(peerflags, OPT_GO_ON);     
1429                                                 res = -1;
1430                                         } else if (!strcasecmp(macro_result, "ABORT")) {
1431                                                 /* Hangup both ends unless the caller has the g flag */
1432                                                 res = -1;
1433                                         } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1434                                                 res = -1;
1435                                                 /* perform a transfer to a new extension */
1436                                                 if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
1437                                                         replace_macro_delimiter(macro_transfer_dest);
1438                                                         if (!ast_parseable_goto(chan, macro_transfer_dest))
1439                                                                 ast_set_flag(peerflags, OPT_GO_ON);
1440
1441                                                 }
1442                                         }
1443                                 }
1444                         }
1445                 }
1446
1447                 if (!res) {
1448                         if (calldurationlimit > 0) {
1449                                 chan->whentohangup = time(NULL) + calldurationlimit;
1450                         }
1451                         if (!ast_strlen_zero(dtmfcalled)) { 
1452                                 if (option_verbose > 2)
1453                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
1454                                 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1455                         }
1456                         if (!ast_strlen_zero(dtmfcalling)) {
1457                                 if (option_verbose > 2)
1458                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
1459                                 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1460                         }
1461                 }
1462                 
1463                 if (!res) {
1464                         struct ast_bridge_config config;
1465
1466                         memset(&config,0,sizeof(struct ast_bridge_config));
1467                         if (play_to_caller)
1468                                 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1469                         if (play_to_callee)
1470                                 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1471                         if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
1472                                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1473                         if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
1474                                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1475                         if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
1476                                 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1477                         if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
1478                                 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1479                         if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
1480                                 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1481                         if (ast_test_flag(peerflags, OPT_CALLER_MONITOR)) 
1482                                 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1483
1484                         config.timelimit = timelimit;
1485                         config.play_warning = play_warning;
1486                         config.warning_freq = warning_freq;
1487                         config.warning_sound = warning_sound;
1488                         config.end_sound = end_sound;
1489                         config.start_sound = start_sound;
1490                         if (moh) {
1491                                 moh = 0;
1492                                 ast_moh_stop(chan);
1493                         } else if (sentringing) {
1494                                 sentringing = 0;
1495                                 ast_indicate(chan, -1);
1496                         }
1497                         /* Be sure no generators are left on it */
1498                         ast_deactivate_generator(chan);
1499                         /* Make sure channels are compatible */
1500                         res = ast_channel_make_compatible(chan, peer);
1501                         if (res < 0) {
1502                                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1503                                 ast_hangup(peer);
1504                                 res = -1;
1505                                 goto done;
1506                         }
1507                         res = ast_bridge_call(chan,peer,&config);
1508                         time(&end_time);
1509                         {
1510                                 char toast[80];
1511                                 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1512                                 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1513                         }
1514                 } else {
1515                         time(&end_time);
1516                         res = -1;
1517                 }
1518                 {
1519                         char toast[80];
1520                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1521                         pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1522                 }
1523                 
1524                 if (res != AST_PBX_NO_HANGUP_PEER) {
1525                         if (!chan->_softhangup)
1526                                 chan->hangupcause = peer->hangupcause;
1527                         ast_hangup(peer);
1528                 }
1529         }       
1530 out:
1531         if (moh) {
1532                 moh = 0;
1533                 ast_moh_stop(chan);
1534         } else if (sentringing) {
1535                 sentringing = 0;
1536                 ast_indicate(chan, -1);
1537         }
1538         hanguptree(outgoing, NULL);
1539         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1540         if (option_debug)
1541                 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1542         
1543         if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1544                 res = 0;
1545
1546 done:
1547         LOCAL_USER_REMOVE(u);    
1548         return res;
1549 }
1550
1551 static int dial_exec(struct ast_channel *chan, void *data)
1552 {
1553         struct ast_flags peerflags;
1554         memset(&peerflags, 0, sizeof(peerflags));
1555         return dial_exec_full(chan, data, &peerflags);
1556 }
1557
1558 static int retrydial_exec(struct ast_channel *chan, void *data)
1559 {
1560         char *announce = NULL, *dialdata = NULL;
1561         const char *context = NULL;
1562         int sleep = 0, loops = 0, res = -1;
1563         struct localuser *u;
1564         struct ast_flags peerflags;
1565         
1566         if (ast_strlen_zero(data)) {
1567                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1568                 return -1;
1569         }       
1570
1571         LOCAL_USER_ADD(u);
1572
1573         if (!(announce = ast_strdupa(data)))
1574                 goto done;
1575
1576         memset(&peerflags, 0, sizeof(peerflags));
1577
1578         if ((dialdata = strchr(announce, '|'))) {
1579                 *dialdata++ = '\0';
1580                 if ((sleep = atoi(dialdata))) {
1581                         sleep *= 1000;
1582                 } else {
1583                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1584                         goto done;
1585                 }
1586                 if ((dialdata = strchr(dialdata, '|'))) {
1587                         *dialdata++ = '\0';
1588                         if (!(loops = atoi(dialdata))) {
1589                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1590                                 goto done;
1591                         }
1592                 }
1593         }
1594         
1595         if ((dialdata = strchr(dialdata, '|'))) {
1596                 *dialdata++ = '\0';
1597         } else {
1598                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1599                 goto done;
1600         }
1601                 
1602         if (sleep < 1000)
1603                 sleep = 10000;
1604
1605         if (!loops)
1606                 loops = -1;     /* run forever */
1607         
1608         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1609
1610         res = 0;
1611         while (loops) {
1612                 chan->data = "Retrying";
1613                 if (ast_test_flag(chan, AST_FLAG_MOH))
1614                         ast_moh_stop(chan);
1615
1616                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1617                         if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
1618                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1619                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1620                                 if (!res && sleep) {
1621                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1622                                                 ast_moh_start(chan, NULL);
1623                                         res = ast_waitfordigit(chan, sleep);
1624                                 }
1625                         } else {
1626                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1627                                         res = ast_waitstream(chan, "");
1628                                 if (sleep) {
1629                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1630                                                 ast_moh_start(chan, NULL);
1631                                         if (!res) 
1632                                                 res = ast_waitfordigit(chan, sleep);
1633                                 }
1634                         }
1635                 }
1636
1637                 if (res < 0)
1638                         break;
1639                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1640                         if (onedigit_goto(chan, context, (char) res, 1)) {
1641                                 res = 0;
1642                                 break;
1643                         }
1644                 }
1645                 loops--;
1646         }
1647         if (loops == 0)
1648                 res = 0;
1649         
1650         if (ast_test_flag(chan, AST_FLAG_MOH))
1651                 ast_moh_stop(chan);
1652 done:
1653         LOCAL_USER_REMOVE(u);
1654         return res;
1655 }
1656
1657 static int unload_module(void *mod)
1658 {
1659         int res;
1660
1661         res = ast_unregister_application(app);
1662         res |= ast_unregister_application(rapp);
1663
1664         STANDARD_HANGUP_LOCALUSERS;
1665         
1666         return res;
1667 }
1668
1669 static int load_module(void *mod)
1670 {
1671         int res;
1672
1673         res = ast_register_application(app, dial_exec, synopsis, descrip);
1674         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1675         
1676         return res;
1677 }
1678
1679 static const char *description(void)
1680 {
1681         return "Dialing Application";
1682 }
1683
1684 static const char *key(void)
1685 {
1686         return ASTERISK_GPL_KEY;
1687 }
1688
1689 STD_MOD(MOD_1, NULL, NULL, NULL);