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