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