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