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