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