36e5030d03acabad5d7df59604f33a824a4ea311
[asterisk/asterisk.git] / apps / app_dial.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
22  * 
23  */
24
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <sys/time.h>
32 #include <sys/signal.h>
33 #include <netinet/in.h>
34
35 #include "asterisk.h"
36
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38
39 #include "asterisk/lock.h"
40 #include "asterisk/file.h"
41 #include "asterisk/logger.h"
42 #include "asterisk/channel.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/options.h"
45 #include "asterisk/module.h"
46 #include "asterisk/translate.h"
47 #include "asterisk/say.h"
48 #include "asterisk/config.h"
49 #include "asterisk/features.h"
50 #include "asterisk/musiconhold.h"
51 #include "asterisk/callerid.h"
52 #include "asterisk/utils.h"
53 #include "asterisk/app.h"
54 #include "asterisk/causes.h"
55 #include "asterisk/manager.h"
56 #include "asterisk/privacy.h"
57
58 static char *tdesc = "Dialing Application";
59
60 static char *app = "Dial";
61
62 static char *synopsis = "Place a call and connect to the current channel";
63
64 static char *descrip =
65 "  Dial(Technology/resource[&Technology2/resource2...][|timeout][|options][|URL]):\n"
66 "Requests one or more channels and places specified outgoing calls on them.\n"
67 "As soon as a channel answers, the Dial app will answer the originating\n"
68 "channel (if it needs to be answered) and will bridge a call with the channel\n"
69 "which first answered. All other calls placed by the Dial app will be hung up.\n"
70 "If a timeout is not specified, the Dial application will wait indefinitely\n"
71 "until either one of the called channels answers, the user hangs up, or all\n"
72 "channels return busy or error. In general, the dialer will return 0 if it\n"
73 "was unable to place the call, or the timeout expired. However, if all\n"
74 "channels were busy, and there exists an extension with priority n+101 (where\n"
75 "n is the priority of the dialer instance), then it will be the next\n"
76 "executed extension (this allows you to setup different behavior on busy from\n"
77 "no-answer).\n"
78 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to DONTCALL, \n"
79 "if the called party chooses to send the calling party to the 'Go Away' script, and \n"
80 "the DIALSTATUS variable will be set to TORTURE, if the called party wants to send the caller to \n"
81 "the TORTURE scripts\n"
82 "  This application returns -1 if the originating channel hangs up, or if the\n"
83 "call is bridged and either of the parties in the bridge terminate the call.\n"
84 "The option string may contain zero or more of the following characters:\n"
85 "       'A(x)' -- play an announcement to the called party, using x as file\n"
86 "       'C' -- reset call detail record for this call.\n"
87 "       'd' -- allow the calling user to dial a 1 digit extension while waiting for a call to\n"
88 "               be answered exiting to that extension if it exists in the context defined by\n"
89 "               ${EXITCONTEXT} or the current context.\n"
90 "       'D([called][:calling])'  -- Send DTMF strings *after* called party has answered, but before the\n"
91 "               call gets bridged. The 'called' DTMF string is sent to the called party, and the\n"
92 "               'calling' DTMF string is sent to the calling party. Both parameters can be used alone.\n"       
93 "       'f' -- Forces callerid to be set as the extension of the line \n"
94 "             making/redirecting the outgoing call. For example, some PSTNs\n"
95 "             don't allow callerid set to numbers that are not assigned to you.\n"
96 "       'g' -- goes on in context if the destination channel hangs up\n"
97 "       'G(context^exten^pri)' -- If the call is answered transfer both parties to the specified exten.\n"
98 "       'h' -- allow callee to hang up by hitting *.\n"
99 "       'H' -- allow caller to hang up by hitting *.\n"
100 "       'j' -- Jump to n+101 if all of the channels were busy.\n"
101 "       'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left\n"
102 "               repeated every 'z' ms) Only 'x' is required, 'y' and 'z' are optional.\n"
103 "             The following special variables are optional:\n"
104 "             * LIMIT_PLAYAUDIO_CALLER    yes|no (default yes)\n"
105 "                                         Play sounds to the caller.\n"
106 "             * LIMIT_PLAYAUDIO_CALLEE    yes|no\n"
107 "                                         Play sounds to the callee.\n"
108 "             * LIMIT_TIMEOUT_FILE        File to play when time is up.\n"
109 "             * LIMIT_CONNECT_FILE        File to play when call begins.\n"
110 "             * LIMIT_WARNING_FILE        File to play as warning if 'y' is defined.\n"
111 "                        'timeleft' is a special sound macro to auto-say the time \n"
112 "                        left and is the default.\n"
113 "       'm[(class)]' -- provide hold music to the calling party until answered (optionally\n"
114 "                      with the specified class.\n"
115 "       'M(x[^arg])' -- Executes the macro (x with ^ delim arg list) upon connect of the call.\n"
116 "                      Also, the macro can set the MACRO_RESULT variable to do the following:\n"
117 "                     -- ABORT - Hangup both legs of the call.\n"
118 "                     -- CONGESTION - Behave as if line congestion was encountered.\n"
119 "                     -- BUSY - Behave as if a busy signal was encountered. (n+101)\n"
120 "                     -- CONTINUE - Hangup the called party and continue on in the dialplan.\n"
121 "                     -- GOTO:<context>^<exten>^<priority> - Transfer the call.\n"
122 "       'n' -- modifier for screen/privacy mode. No intros are to be saved in the priv-callerintros dir.\n"
123 "       'N' -- modifier for screen/privacy mode. if callerID is present, do not screen the call.\n"
124 "       'o' -- Original (inbound) Caller*ID should be placed on the outbound leg of the call\n" 
125 "             instead of using the destination extension (old style asterisk behavior)\n"
126 "       'p' -- screening mode.  Basically Privacy mode without memory.\n"
127 "       'P[(x)]' -- privacy mode, using 'x' as database if provided, or the extension is used if not provided.\n"
128 "       'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
129 "       'S(x)' -- hangup the call after x seconds AFTER called party picked up\n"       
130 "       't' -- allow the called user to transfer the calling user by hitting the key sequence defiend in features.conf.\n"
131 "       'T' -- allow the calling user to transfer the call by hitting the key sequence defined in features.conf.\n"
132 "       'w' -- allow the called user to write the conversation to disk via Monitor\n"
133 "       'W' -- allow the calling user to write the conversation to disk via Monitor\n\n"
134 "  In addition to transferring the call, a call may be parked and then picked\n"
135 "up by another user.\n"
136 "  The optional URL will be sent to the called party if the channel supports it.\n"
137 "  If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
138 "  application will be put into that group (as in SetGroup).\n"
139 "  This application sets the following channel variables upon completion:\n"
140 "      DIALEDTIME    Time from dial to answer\n" 
141 "      ANSWEREDTIME  Time for actual call\n"
142 "      DIALSTATUS    The status of the call as a text string, one of\n"
143 "             CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL | DONTCALL | TORTURE\n"
144 "";
145
146 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
147 static char *rapp = "RetryDial";
148 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
149 static char *rdescrip =
150 "  RetryDial(announce|sleep|loops|Technology/resource[&Technology2/resource2...][|timeout][|options][|URL]):\n"
151 "Attempt to place a call.  If no channel can be reached, play the file defined by 'announce'\n"
152 "waiting 'sleep' seconds to retry the call.  If the specified number of attempts matches \n"
153 "'loops' the call will continue in the dialplan.  If 'loops' is set to 0, the call will retry endlessly.\n\n"
154 "While waiting, a 1 digit extension may be dialed.  If that extension exists in either\n"
155 "the context defined in ${EXITCONTEXT} or the current one, The call will transfer\n"
156 "to that extension immmediately.\n\n"
157 "All arguments after 'loops' are passed directly to the Dial() application.\n"
158 "";
159
160
161 /* We define a customer "local user" structure because we
162    use it not only for keeping track of what is in use but
163    also for keeping track of who we're dialing. */
164
165 #define DIAL_STILLGOING                 (1 << 0)
166 #define DIAL_ALLOWREDIRECT_IN           (1 << 1)
167 #define DIAL_ALLOWREDIRECT_OUT          (1 << 2)
168 #define DIAL_ALLOWDISCONNECT_IN         (1 << 3)
169 #define DIAL_ALLOWDISCONNECT_OUT        (1 << 4)
170 #define DIAL_RINGBACKONLY               (1 << 5)
171 #define DIAL_MUSICONHOLD                (1 << 6)
172 #define DIAL_FORCECALLERID              (1 << 7)
173 #define DIAL_MONITOR_IN                 (1 << 8)
174 #define DIAL_MONITOR_OUT                (1 << 9)
175 #define DIAL_GO_ON                      (1 << 10)
176 #define DIAL_HALT_ON_DTMF               (1 << 11)
177 #define DIAL_PRESERVE_CALLERID          (1 << 12)
178 #define DIAL_NOFORWARDHTML              (1 << 13)
179
180 struct localuser {
181         struct ast_channel *chan;
182         unsigned int flags;
183         int forwards;
184         struct localuser *next;
185 };
186
187 LOCAL_USER_DECL;
188
189 static void hanguptree(struct localuser *outgoing, struct ast_channel *exception)
190 {
191         /* Hang up a tree of stuff */
192         struct localuser *oo;
193         while (outgoing) {
194                 /* Hangup any existing lines we have open */
195                 if (outgoing->chan && (outgoing->chan != exception))
196                         ast_hangup(outgoing->chan);
197                 oo = outgoing;
198                 outgoing=outgoing->next;
199                 free(oo);
200         }
201 }
202
203 #define AST_MAX_FORWARDS   8
204
205 #define AST_MAX_WATCHERS 256
206
207 #define HANDLE_CAUSE(cause, chan) do { \
208         switch(cause) { \
209         case AST_CAUSE_BUSY: \
210                 if (chan->cdr) \
211                         ast_cdr_busy(chan->cdr); \
212                 numbusy++; \
213                 break; \
214         case AST_CAUSE_CONGESTION: \
215                 if (chan->cdr) \
216                         ast_cdr_busy(chan->cdr); \
217                 numcongestion++; \
218                 break; \
219         case AST_CAUSE_UNREGISTERED: \
220                 if (chan->cdr) \
221                         ast_cdr_busy(chan->cdr); \
222                 numnochan++; \
223                 break; \
224         default: \
225                 numnochan++; \
226                 break; \
227         } \
228 } while (0)
229
230
231 static int onedigit_goto(struct ast_channel *chan, char *context, char exten, int pri) 
232 {
233         char rexten[2] = { exten, '\0' };
234
235         if (context) {
236                 if (!ast_goto_if_exists(chan, context, rexten, pri))
237                         return 1;
238         } else {
239                 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
240                         return 1;
241                 else if (!ast_strlen_zero(chan->macrocontext)) {
242                         if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
243                                 return 1;
244                 }
245         }
246         return 0;
247 }
248
249
250 static char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
251 {
252         char *context;
253         char *exten;
254         if (!ast_strlen_zero(chan->macrocontext))
255                 context = chan->macrocontext;
256         else
257                 context = chan->context;
258
259         if (!ast_strlen_zero(chan->macroexten))
260                 exten = chan->macroexten;
261         else
262                 exten = chan->exten;
263
264         if (ast_get_hint(NULL, 0, name, namelen, chan, context, exten))
265                 return name;
266         else
267                 return "";
268 }
269
270 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
271 {
272         manager_event(EVENT_FLAG_CALL, "Dial", 
273                            "Source: %s\r\n"
274                            "Destination: %s\r\n"
275                            "CallerID: %s\r\n"
276                            "CallerIDName: %s\r\n"
277                            "SrcUniqueID: %s\r\n"
278                            "DestUniqueID: %s\r\n",
279                            src->name, dst->name, src->cid.cid_num ? src->cid.cid_num : "<unknown>",
280                            src->cid.cid_name ? src->cid.cid_name : "<unknown>", src->uniqueid,
281                            dst->uniqueid);
282 }
283
284 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
285 {
286         struct localuser *o;
287         int found;
288         int numlines;
289         int numbusy = busystart;
290         int numcongestion = congestionstart;
291         int numnochan = nochanstart;
292         int prestart = busystart + congestionstart + nochanstart;
293         int cause;
294         int orig = *to;
295         struct ast_frame *f;
296         struct ast_channel *peer = NULL;
297         struct ast_channel *watchers[AST_MAX_WATCHERS];
298         int pos;
299         int single;
300         struct ast_channel *winner;
301         char *context = NULL;
302         char cidname[AST_MAX_EXTENSION];
303
304         single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, DIAL_MUSICONHOLD | DIAL_RINGBACKONLY));
305         
306         if (single) {
307                 /* Turn off hold music, etc */
308                 ast_deactivate_generator(in);
309                 /* If we are calling a single channel, make them compatible for in-band tone purpose */
310                 ast_channel_make_compatible(outgoing->chan, in);
311         }
312         
313         
314         while (*to && !peer) {
315                 o = outgoing;
316                 found = -1;
317                 pos = 1;
318                 numlines = prestart;
319                 watchers[0] = in;
320                 while (o) {
321                         /* Keep track of important channels */
322                         if (ast_test_flag(o, DIAL_STILLGOING) && o->chan) {
323                                 watchers[pos++] = o->chan;
324                                 found = 1;
325                         }
326                         o = o->next;
327                         numlines++;
328                 }
329                 if (found < 0) {
330                         if (numlines == (numbusy + numcongestion + numnochan)) {
331                                 if (option_verbose > 2)
332                                         ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
333                                 if (numbusy)
334                                         strcpy(status, "BUSY"); 
335                                 else if (numcongestion)
336                                         strcpy(status, "CONGESTION");
337                                 else if (numnochan)
338                                         strcpy(status, "CHANUNAVAIL");
339                                 if (option_priority_jumping || priority_jump)
340                                         ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
341                         } else {
342                                 if (option_verbose > 2)
343                                         ast_verbose( VERBOSE_PREFIX_2 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
344                         }
345                         *to = 0;
346                         return NULL;
347                 }
348                 winner = ast_waitfor_n(watchers, pos, to);
349                 o = outgoing;
350                 while (o) {
351                         if (ast_test_flag(o, DIAL_STILLGOING) && o->chan && (o->chan->_state == AST_STATE_UP)) {
352                                 if (!peer) {
353                                         if (option_verbose > 2)
354                                                 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
355                                         peer = o->chan;
356                                         ast_copy_flags(peerflags, o, DIAL_ALLOWREDIRECT_IN|DIAL_ALLOWREDIRECT_OUT|DIAL_ALLOWDISCONNECT_IN|DIAL_ALLOWDISCONNECT_OUT|DIAL_NOFORWARDHTML);
357                                 }
358                         } else if (o->chan && (o->chan == winner)) {
359                                 if (!ast_strlen_zero(o->chan->call_forward)) {
360                                         char tmpchan[256];
361                                         char *stuff;
362                                         char *tech;
363                                         ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
364                                         if ((stuff = strchr(tmpchan, '/'))) {
365                                                 *stuff = '\0';
366                                                 stuff++;
367                                                 tech = tmpchan;
368                                         } else {
369                                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
370                                                 stuff = tmpchan;
371                                                 tech = "Local";
372                                         }
373                                         /* Before processing channel, go ahead and check for forwarding */
374                                         o->forwards++;
375                                         if (o->forwards < AST_MAX_FORWARDS) {
376                                                 if (option_verbose > 2)
377                                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
378                                                 /* Setup parameters */
379                                                 o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
380                                                 if (!o->chan)
381                                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
382                                         } else {
383                                                 if (option_verbose > 2)
384                                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", o->chan->name);
385                                                 cause = AST_CAUSE_CONGESTION;
386                                                 o->chan = NULL;
387                                         }
388                                         if (!o->chan) {
389                                                 ast_clear_flag(o, DIAL_STILLGOING);     
390                                                 HANDLE_CAUSE(cause, in);
391                                         } else {
392                                                 if (o->chan->cid.cid_num)
393                                                         free(o->chan->cid.cid_num);
394                                                 o->chan->cid.cid_num = NULL;
395                                                 if (o->chan->cid.cid_name)
396                                                         free(o->chan->cid.cid_name);
397                                                 o->chan->cid.cid_name = NULL;
398
399                                                 if (ast_test_flag(o, DIAL_FORCECALLERID)) {
400                                                         char *newcid = NULL;
401
402                                                         if (!ast_strlen_zero(in->macroexten))
403                                                                 newcid = in->macroexten;
404                                                         else
405                                                                 newcid = in->exten;
406                                                         o->chan->cid.cid_num = strdup(newcid);
407                                                         ast_copy_string(o->chan->accountcode, winner->accountcode, sizeof(o->chan->accountcode));
408                                                         o->chan->cdrflags = winner->cdrflags;
409                                                         if (!o->chan->cid.cid_num)
410                                                                 ast_log(LOG_WARNING, "Out of memory\n");
411                                                 } else {
412                                                         if (in->cid.cid_num) {
413                                                                 o->chan->cid.cid_num = strdup(in->cid.cid_num);
414                                                                 if (!o->chan->cid.cid_num)
415                                                                         ast_log(LOG_WARNING, "Out of memory\n");        
416                                                         }
417                                                         if (in->cid.cid_name) {
418                                                                 o->chan->cid.cid_name = strdup(in->cid.cid_name);
419                                                                 if (!o->chan->cid.cid_name)
420                                                                         ast_log(LOG_WARNING, "Out of memory\n");        
421                                                         }
422                                                         ast_copy_string(o->chan->accountcode, in->accountcode, sizeof(o->chan->accountcode));
423                                                         o->chan->cdrflags = in->cdrflags;
424                                                 }
425
426                                                 if (in->cid.cid_ani) {
427                                                         if (o->chan->cid.cid_ani)
428                                                                 free(o->chan->cid.cid_ani);
429                                                         o->chan->cid.cid_ani = malloc(strlen(in->cid.cid_ani) + 1);
430                                                         if (o->chan->cid.cid_ani)
431                                                                 ast_copy_string(o->chan->cid.cid_ani, in->cid.cid_ani, sizeof(o->chan->cid.cid_ani));
432                                                         else
433                                                                 ast_log(LOG_WARNING, "Out of memory\n");
434                                                 }
435                                                 if (o->chan->cid.cid_rdnis) 
436                                                         free(o->chan->cid.cid_rdnis);
437                                                 if (!ast_strlen_zero(in->macroexten))
438                                                         o->chan->cid.cid_rdnis = strdup(in->macroexten);
439                                                 else
440                                                         o->chan->cid.cid_rdnis = strdup(in->exten);
441                                                 if (ast_call(o->chan, tmpchan, 0)) {
442                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
443                                                         ast_clear_flag(o, DIAL_STILLGOING);     
444                                                         ast_hangup(o->chan);
445                                                         o->chan = NULL;
446                                                         numnochan++;
447                                                 } else {
448                                                         senddialevent(in, o->chan);
449                                                         /* After calling, set callerid to extension */
450                                                         if (!ast_test_flag(peerflags, DIAL_PRESERVE_CALLERID))
451                                                                 ast_set_callerid(o->chan, ast_strlen_zero(in->macroexten) ? in->exten : in->macroexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
452                                                 }
453                                         }
454                                         /* Hangup the original channel now, in case we needed it */
455                                         ast_hangup(winner);
456                                         continue;
457                                 }
458                                 f = ast_read(winner);
459                                 if (f) {
460                                         if (f->frametype == AST_FRAME_CONTROL) {
461                                                 switch(f->subclass) {
462                                                 case AST_CONTROL_ANSWER:
463                                                         /* This is our guy if someone answered. */
464                                                         if (!peer) {
465                                                                 if (option_verbose > 2)
466                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
467                                                                 peer = o->chan;
468                                                                 ast_copy_flags(peerflags, o, DIAL_ALLOWREDIRECT_IN|DIAL_ALLOWREDIRECT_OUT|DIAL_ALLOWDISCONNECT_IN|DIAL_ALLOWDISCONNECT_OUT|DIAL_NOFORWARDHTML);
469                                                         }
470                                                         /* If call has been answered, then the eventual hangup is likely to be normal hangup */
471                                                         in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
472                                                         o->chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
473                                                         break;
474                                                 case AST_CONTROL_BUSY:
475                                                         if (option_verbose > 2)
476                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
477                                                         in->hangupcause = o->chan->hangupcause;
478                                                         ast_hangup(o->chan);
479                                                         o->chan = NULL;
480                                                         ast_clear_flag(o, DIAL_STILLGOING);     
481                                                         HANDLE_CAUSE(AST_CAUSE_BUSY, in);
482                                                         break;
483                                                 case AST_CONTROL_CONGESTION:
484                                                         if (option_verbose > 2)
485                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
486                                                         in->hangupcause = o->chan->hangupcause;
487                                                         ast_hangup(o->chan);
488                                                         o->chan = NULL;
489                                                         ast_clear_flag(o, DIAL_STILLGOING);
490                                                         HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
491                                                         break;
492                                                 case AST_CONTROL_RINGING:
493                                                         if (option_verbose > 2)
494                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
495                                                         if (!(*sentringing) && !ast_test_flag(outgoing, DIAL_MUSICONHOLD)) {
496                                                                 ast_indicate(in, AST_CONTROL_RINGING);
497                                                                 (*sentringing)++;
498                                                         }
499                                                         break;
500                                                 case AST_CONTROL_PROGRESS:
501                                                         if (option_verbose > 2)
502                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
503                                                         if (!ast_test_flag(outgoing, DIAL_RINGBACKONLY))
504                                                                 ast_indicate(in, AST_CONTROL_PROGRESS);
505                                                         break;
506                                                 case AST_CONTROL_VIDUPDATE:
507                                                         if (option_verbose > 2)
508                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", o->chan->name,in->name);
509                                                         ast_indicate(in, AST_CONTROL_VIDUPDATE);
510                                                         break;
511                                                 case AST_CONTROL_PROCEEDING:
512                                                         if (option_verbose > 2)
513                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", o->chan->name,in->name);
514                                                         if (!ast_test_flag(outgoing, DIAL_RINGBACKONLY))
515                                                                 ast_indicate(in, AST_CONTROL_PROCEEDING);
516                                                         break;
517                                                 case AST_CONTROL_HOLD:
518                                                         if (option_verbose > 2)
519                                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", o->chan->name);
520                                                         ast_indicate(in, AST_CONTROL_HOLD);
521                                                         break;
522                                                 case AST_CONTROL_UNHOLD:
523                                                         if (option_verbose > 2)
524                                                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", o->chan->name);
525                                                         ast_indicate(in, AST_CONTROL_UNHOLD);
526                                                         break;
527                                                 case AST_CONTROL_OFFHOOK:
528                                                 case AST_CONTROL_FLASH:
529                                                         /* Ignore going off hook and flash */
530                                                         break;
531                                                 case -1:
532                                                         if (!ast_test_flag(outgoing, DIAL_RINGBACKONLY | DIAL_MUSICONHOLD)) {
533                                                                 if (option_verbose > 2)
534                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
535                                                                 ast_indicate(in, -1);
536                                                                 (*sentringing) = 0;
537                                                         }
538                                                         break;
539                                                 default:
540                                                         ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
541                                                 }
542                                         } else if (single && (f->frametype == AST_FRAME_VOICE) && 
543                                                                 !(ast_test_flag(outgoing, DIAL_RINGBACKONLY|DIAL_MUSICONHOLD))) {
544                                                 if (ast_write(in, f)) 
545                                                         ast_log(LOG_DEBUG, "Unable to forward frame\n");
546                                         } else if (single && (f->frametype == AST_FRAME_IMAGE) && 
547                                                                 !(ast_test_flag(outgoing, DIAL_RINGBACKONLY|DIAL_MUSICONHOLD))) {
548                                                 if (ast_write(in, f))
549                                                         ast_log(LOG_DEBUG, "Unable to forward image\n");
550                                         } else if (single && (f->frametype == AST_FRAME_TEXT) && 
551                                                                 !(ast_test_flag(outgoing, DIAL_RINGBACKONLY|DIAL_MUSICONHOLD))) {
552                                                 if (ast_write(in, f))
553                                                         ast_log(LOG_DEBUG, "Unable to text\n");
554                                         } else if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
555                                                 ast_channel_sendhtml(in, f->subclass, f->data, f->datalen);
556
557                                         ast_frfree(f);
558                                 } else {
559                                         in->hangupcause = o->chan->hangupcause;
560                                         ast_hangup(o->chan);
561                                         o->chan = NULL;
562                                         ast_clear_flag(o, DIAL_STILLGOING);
563                                 }
564                         }
565                         o = o->next;
566                 }
567                 if (winner == in) {
568                         f = ast_read(in);
569 #if 0
570                         if (f && (f->frametype != AST_FRAME_VOICE))
571                                 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
572                         else if (!f || (f->frametype != AST_FRAME_VOICE))
573                                 printf("Hangup received on %s\n", in->name);
574 #endif
575                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
576                                 /* Got hung up */
577                                 *to=-1;
578                                 strcpy(status, "CANCEL");
579                                 if (f)
580                                         ast_frfree(f);
581                                 return NULL;
582                         }
583
584                         if (f && (f->frametype == AST_FRAME_DTMF)) {
585                                 if (ast_test_flag(peerflags, DIAL_HALT_ON_DTMF)) {
586                                         context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
587                                         if (onedigit_goto(in, context, (char) f->subclass, 1)) {
588                                                 if (option_verbose > 3)
589                                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
590                                                 *to=0;
591                                                 *result = f->subclass;
592                                                 strcpy(status, "CANCEL");
593                                                 ast_frfree(f);
594                                                 return NULL;
595                                         }
596                                 }
597
598                                 if (ast_test_flag(peerflags, DIAL_ALLOWDISCONNECT_OUT) && 
599                                                   (f->subclass == '*')) { /* hmm it it not guarenteed to be '*' anymore. */
600                                         if (option_verbose > 3)
601                                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
602                                         *to=0;
603                                         strcpy(status, "CANCEL");
604                                         ast_frfree(f);
605                                         return NULL;
606                                 }
607                         }
608
609                         /* Forward HTML stuff */
610                         if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
611                                 ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen);
612                         
613
614                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
615                                 if (ast_write(outgoing->chan, f))
616                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
617                         }
618                         if (single && (f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_VIDUPDATE)) {
619                                 if (option_verbose > 2)
620                                         ast_verbose ( VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", in->name,outgoing->chan->name);
621                                 ast_indicate(outgoing->chan, AST_CONTROL_VIDUPDATE);
622                         }
623                         ast_frfree(f);
624                 }
625                 if (!*to && (option_verbose > 2))
626                         ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
627         }
628
629         return peer;
630         
631 }
632
633
634 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
635 {
636         int res=-1;
637         struct localuser *u;
638         char *info, *peers, *timeout, *tech, *number, *rest, *cur;
639         char privdb[256], *s;
640         char privcid[256];
641         char privintro[1024];
642         char  announcemsg[256] = "", *ann;
643         struct localuser *outgoing=NULL, *tmp;
644         struct ast_channel *peer;
645         int to;
646         int hasmacro = 0;
647         int privacy=0;
648         int screen=0;
649         int no_save_intros = 0;
650         int no_screen_callerid = 0;
651         int announce=0;
652         int resetcdr=0;
653         int numbusy = 0;
654         int numcongestion = 0;
655         int numnochan = 0;
656         int cause;
657         char numsubst[AST_MAX_EXTENSION];
658         char restofit[AST_MAX_EXTENSION];
659         char cidname[AST_MAX_EXTENSION];
660         char *transfer = NULL;
661         char *newnum;
662         char *l;
663         char *url=NULL; /* JDG */
664         int privdb_val=0;
665         unsigned int calldurationlimit=0;
666         char *cdl;
667         time_t now;
668         struct ast_bridge_config config;
669         long timelimit = 0;
670         long play_warning = 0;
671         long warning_freq=0;
672         char *warning_sound=NULL;
673         char *end_sound=NULL;
674         char *start_sound=NULL;
675         char *limitptr;
676         char limitdata[256];
677         char *sdtmfptr;
678         char *dtmfcalled=NULL, *dtmfcalling=NULL;
679         char *stack,*var;
680         char *mac = NULL, *macroname = NULL;
681         char status[256];
682         char toast[80];
683         int play_to_caller=0,play_to_callee=0;
684         int playargs=0, sentringing=0, moh=0;
685         char *mohclass = NULL;
686         char *outbound_group = NULL;
687         char *macro_result = NULL, *macro_transfer_dest = NULL;
688         int digit = 0, result = 0;
689         time_t start_time, answer_time, end_time;
690         struct ast_app *app = NULL;
691         char *dblgoto = NULL;
692         int priority_jump = 0;
693
694         if (ast_strlen_zero(data)) {
695                 ast_log(LOG_WARNING, "Dial requires an argument (technology1/number1&technology2/number2...|optional timeout|options)\n");
696                 return -1;
697         }
698
699         LOCAL_USER_ADD(u);
700
701         info = ast_strdupa(data);       
702         if (!info) {
703                 ast_log(LOG_WARNING, "Unable to dupe data :(\n");
704                 LOCAL_USER_REMOVE(u);
705                 return -1;
706         }
707         
708         peers = info;
709         if (peers) {
710                 timeout = strchr(info, '|');
711                 if (timeout) {
712                         *timeout = '\0';
713                         timeout++;
714                         transfer = strchr(timeout, '|');
715                         if (transfer) {
716                                 *transfer = '\0';
717                                 transfer++;
718                                 /* JDG */
719                                 url = strchr(transfer, '|');
720                                 if (url) {
721                                         *url = '\0';
722                                         url++;
723                                         if (option_debug)
724                                                 ast_log(LOG_DEBUG, "DIAL WITH URL=%s_\n", url);
725                                 } else 
726                                         if (option_debug) {
727                                                 ast_log(LOG_DEBUG, "SIMPLE DIAL (NO URL)\n");
728                                         }
729                                 /* /JDG */
730                         }
731                 }
732         } else
733                 timeout = NULL;
734         if (ast_strlen_zero(peers)) {
735                 ast_log(LOG_WARNING, "Dial argument takes format (technology1/number1&technology2/number2...|optional timeout)\n");
736                 goto out;
737         }
738         
739
740         if (transfer) {
741
742                 /* Extract call duration limit */
743                 if ((cdl = strstr(transfer, "S("))) {
744                         calldurationlimit=atoi(cdl+2);
745                         if (option_verbose > 2)
746                                 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n",calldurationlimit);                 
747                 } 
748
749                 /* Extract DTMF strings to send upon successfull connect */
750                 if ((sdtmfptr = strstr(transfer, "D("))) {
751                         dtmfcalled = ast_strdupa(sdtmfptr + 2);
752                         dtmfcalling = strchr(dtmfcalled, ')');
753                         if (dtmfcalling)
754                                 *dtmfcalling = '\0';
755                         dtmfcalling = strchr(dtmfcalled, ':');
756                         if (dtmfcalling) {
757                                 *dtmfcalling = '\0';
758                                 dtmfcalling++;
759                         }                               
760                         /* Overwrite with X's what was the sdtmf info */
761                         while (*sdtmfptr && (*sdtmfptr != ')')) 
762                                 *(sdtmfptr++) = 'X';
763                         if (*sdtmfptr)
764                                 *sdtmfptr = 'X';
765                         else 
766                                 ast_log(LOG_WARNING, "D( Data lacking trailing ')'\n");
767                 }
768   
769                 /* XXX LIMIT SUPPORT */
770                 if ((limitptr = strstr(transfer, "L("))) {
771                         ast_copy_string(limitdata, limitptr + 2, sizeof(limitdata));
772                         /* Overwrite with X's what was the limit info */
773                         while (*limitptr && (*limitptr != ')')) 
774                                 *(limitptr++) = 'X';
775                         if (*limitptr)
776                                 *limitptr = 'X';
777                         /* Now find the end */
778                         limitptr = strchr(limitdata, ')');
779                         if (limitptr)
780                                 *limitptr = '\0';
781                         else
782                                 ast_log(LOG_WARNING, "Limit Data lacking trailing ')'\n");
783
784                         var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
785                         play_to_caller = var ? ast_true(var) : 1;
786                   
787                         var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
788                         play_to_callee = var ? ast_true(var) : 0;
789                   
790                         if (!play_to_caller && !play_to_callee)
791                                 play_to_caller=1;
792                   
793                         var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
794                         warning_sound = var ? var : "timeleft";
795
796                         var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
797                         end_sound = var ? var : NULL;
798
799                         var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
800                         start_sound = var ? var : NULL;
801
802                         var=stack=limitdata;
803
804                         var = strsep(&stack, ":");
805                         if (var) {
806                                 timelimit = atol(var);
807                                 playargs++;
808                                 var = strsep(&stack, ":");
809                                 if (var) {
810                                         play_warning = atol(var);
811                                         playargs++;
812                                         var = strsep(&stack, ":");
813                                         if (var) {
814                                                 warning_freq = atol(var);
815                                                 playargs++;
816                                         }
817                                 }
818                         }
819                   
820                         if (!timelimit) {
821                                 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
822                                 warning_sound = NULL;
823                         }
824                         /* undo effect of S(x) in case they are both used */
825                         calldurationlimit = 0; 
826                         /* more efficient do it like S(x) does since no advanced opts*/
827                         if (!play_warning && !start_sound && !end_sound && timelimit) { 
828                                 calldurationlimit = timelimit/1000;
829                                 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
830                         } else if (option_verbose > 2) {
831                                 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
832                                 ast_verbose(VERBOSE_PREFIX_3 "- timelimit     = %ld\n", timelimit);
833                                 ast_verbose(VERBOSE_PREFIX_3 "- play_warning  = %ld\n", play_warning);
834                                 ast_verbose(VERBOSE_PREFIX_3 "- play_to_caller= %s\n", play_to_caller ? "yes" : "no");
835                                 ast_verbose(VERBOSE_PREFIX_3 "- play_to_callee= %s\n", play_to_callee ? "yes" : "no");
836                                 ast_verbose(VERBOSE_PREFIX_3 "- warning_freq  = %ld\n", warning_freq);
837                                 ast_verbose(VERBOSE_PREFIX_3 "- start_sound   = %s\n", start_sound ? start_sound : "UNDEF");
838                                 ast_verbose(VERBOSE_PREFIX_3 "- warning_sound = %s\n", warning_sound ? warning_sound : "UNDEF");
839                                 ast_verbose(VERBOSE_PREFIX_3 "- end_sound     = %s\n", end_sound ? end_sound : "UNDEF");
840                         }
841                 }
842                 
843                 /* XXX ANNOUNCE SUPPORT */
844                 if ((ann = strstr(transfer, "A("))) {
845                         announce = 1;
846                         ast_copy_string(announcemsg, ann + 2, sizeof(announcemsg));
847                         /* Overwrite with X's what was the announce info */
848                         while (*ann && (*ann != ')')) 
849                                 *(ann++) = 'X';
850                         if (*ann)
851                                 *ann = 'X';
852                         /* Now find the end of the announce */
853                         ann = strchr(announcemsg, ')');
854                         if (ann)
855                                 *ann = '\0';
856                         else {
857                                 ast_log(LOG_WARNING, "Transfer with Announce spec lacking trailing ')'\n");
858                                 announce = 0;
859                         }
860                 }
861
862                 /* Get the goto from the dial option string */
863                 if ((mac = strstr(transfer, "G("))) {
864
865
866                         dblgoto = ast_strdupa(mac + 2);
867                         while (*mac && (*mac != ')'))
868                                 *(mac++) = 'X';
869                         if (*mac) {
870                                 *mac = 'X';
871                                 mac = strchr(dblgoto, ')');
872                                 if (mac)
873                                         *mac = '\0';
874                                 else {
875                                         ast_log(LOG_WARNING, "Goto flag set without trailing ')'\n");
876                                         dblgoto = NULL;
877                                 }
878                         } else {
879                                 ast_log(LOG_WARNING, "Could not find exten to which we should jump.\n");
880                                 dblgoto = NULL;
881                         }
882                 }
883
884                 /* Get the macroname from the dial option string */
885                 if ((mac = strstr(transfer, "M("))) {
886                         hasmacro = 1;
887                         macroname = ast_strdupa(mac + 2);
888                         while (*mac && (*mac != ')'))
889                                 *(mac++) = 'X';
890                         if (*mac) {
891                                 *mac = 'X';
892                                 mac = strchr(macroname, ')');
893                                 if (mac)
894                                         *mac = '\0';
895                                 else {
896                                         ast_log(LOG_WARNING, "Macro flag set without trailing ')'\n");
897                                         hasmacro = 0;
898                                 }
899                         } else {
900                                 ast_log(LOG_WARNING, "Could not find macro to which we should jump.\n");
901                                 hasmacro = 0;
902                         }
903                 }
904                 /* Get music on hold class */
905                 if ((mac = strstr(transfer, "m("))) {
906                         mohclass = ast_strdupa(mac + 2);
907                         mac++; /* Leave the "m" in the string */
908                         while (*mac && (*mac != ')'))
909                                 *(mac++) = 'X';
910                         if (*mac) {
911                                 *mac = 'X';
912                                 mac = strchr(mohclass, ')');
913                                 if (mac)
914                                         *mac = '\0';
915                                 else {
916                                         ast_log(LOG_WARNING, "Music on hold class specified without trailing ')'\n");
917                                         mohclass = NULL;
918                                 }
919                         } else {
920                                 ast_log(LOG_WARNING, "Could not find music on hold class to use, assuming default.\n");
921                                 mohclass=NULL;
922                         }
923                 }
924                 /* Extract privacy info from transfer */
925                 if ((s = strstr(transfer, "P("))) {
926                         privacy = 1;
927                         ast_copy_string(privdb, s + 2, sizeof(privdb));
928                         /* Overwrite with X's what was the privacy info */
929                         while (*s && (*s != ')')) 
930                                 *(s++) = 'X';
931                         if (*s)
932                                 *s = 'X';
933                         /* Now find the end of the privdb */
934                         s = strchr(privdb, ')');
935                         if (s)
936                                 *s = '\0';
937                         else {
938                                 ast_log(LOG_WARNING, "Transfer with privacy lacking trailing ')'\n");
939                                 privacy = 0;
940                         }
941                 } else if (strchr(transfer, 'P')) {
942                         /* No specified privdb */
943                         privacy = 1;
944                 } else if (strchr(transfer, 'p')) {
945                         screen = 1;
946                 } else if (strchr(transfer, 'C')) {
947                         resetcdr = 1;
948                 } else if (strchr(transfer, 'j')) {
949                         priority_jump = 1;
950                 }
951                 if (strchr(transfer, 'n')) {
952                         no_save_intros = 1;
953                 } 
954                 if (strchr(transfer, 'N')) {
955                         no_screen_callerid = 1;
956                 }
957         }
958         if (resetcdr && chan->cdr)
959                 ast_cdr_reset(chan->cdr, 0);
960         if (ast_strlen_zero(privdb) && privacy) {
961                 /* If privdb is not specified and we are using privacy, copy from extension */
962                 ast_copy_string(privdb, chan->exten, sizeof(privdb));
963         }
964         if (privacy || screen) {
965                 char callerid[60];
966
967                 l = chan->cid.cid_num;
968                 if (!ast_strlen_zero(l)) {
969                         ast_shrink_phone_number(l);
970                         if( privacy ) {
971                                 if (option_verbose > 2)
972                                         ast_verbose( VERBOSE_PREFIX_3  "Privacy DB is '%s', privacy is %d, clid is '%s'\n", privdb, privacy, l);
973                                 privdb_val = ast_privacy_check(privdb, l);
974                         }
975                         else {
976                                 if (option_verbose > 2)
977                                         ast_verbose( VERBOSE_PREFIX_3  "Privacy Screening, clid is '%s'\n", l);
978                                 privdb_val = AST_PRIVACY_UNKNOWN;
979                         }
980                 } else {
981                         char *tnam, *tn2;
982
983                         tnam = ast_strdupa(chan->name);
984                         /* clean the channel name so slashes don't try to end up in disk file name */
985                         for(tn2 = tnam; *tn2; tn2++) {
986                                 if( *tn2=='/')
987                                         *tn2 = '=';  /* any other chars to be afraid of? */
988                         }
989                         if (option_verbose > 2)
990                                 ast_verbose( VERBOSE_PREFIX_3  "Privacy-- callerid is empty\n");
991
992                         snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
993                         l = callerid;
994                         privdb_val = AST_PRIVACY_UNKNOWN;
995                 }
996                 
997                 ast_copy_string(privcid,l,sizeof(privcid));
998
999                 if( strncmp(privcid,"NOCALLERID",10) != 0 && no_screen_callerid ) { /* if callerid is set, and no_screen_callerid is set also */  
1000                         if (option_verbose > 2)
1001                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID set (%s); N option set; Screening should be off\n", privcid);
1002                         privdb_val = AST_PRIVACY_ALLOW;
1003                 }
1004                 else if( no_screen_callerid && strncmp(privcid,"NOCALLERID",10) == 0 ) {
1005                         if (option_verbose > 2)
1006                                 ast_verbose( VERBOSE_PREFIX_3  "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
1007                 }
1008                 
1009                 if( privdb_val == AST_PRIVACY_DENY ) {
1010                         ast_verbose( VERBOSE_PREFIX_3  "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1011                         res=0;
1012                         goto out;
1013                 }
1014                 else if( privdb_val == AST_PRIVACY_KILL ) {
1015                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
1016                         res = 0;
1017                         goto out; /* Is this right? */
1018                 }
1019                 else if( privdb_val == AST_PRIVACY_TORTURE ) {
1020                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
1021                         res = 0;
1022                         goto out; /* is this right??? */
1023
1024                 }
1025                 else if( privdb_val == AST_PRIVACY_UNKNOWN ) {
1026                         /* Get the user's intro, store it in priv-callerintros/$CID, 
1027                            unless it is already there-- this should be done before the 
1028                            call is actually dialed  */
1029
1030                         /* make sure the priv-callerintros dir exists? */
1031
1032                         snprintf(privintro,sizeof(privintro),"priv-callerintros/%s", privcid);
1033                         if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
1034                                 /* the DELUX version of this code would allow this caller the
1035                                    option to hear and retape their previously recorded intro.
1036                                 */
1037                         }
1038                         else {
1039                                 int duration; /* for feedback from play_and_wait */
1040                                 /* the file doesn't exist yet. Let the caller submit his
1041                                    vocal intro for posterity */
1042                                 /* priv-recordintro script:
1043
1044                                    "At the tone, please say your name:"
1045
1046                                 */
1047                                 ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
1048                                                                                                                         /* don't think we'll need a lock removed, we took care of
1049                                                                                                                            conflicts by naming the privintro file */
1050                         }
1051                 }
1052         }
1053
1054         /* If a channel group has been specified, get it for use when we create peer channels */
1055         outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
1056
1057         cur = peers;
1058         do {
1059                 /* Remember where to start next time */
1060                 rest = strchr(cur, '&');
1061                 if (rest) {
1062                         *rest = 0;
1063                         rest++;
1064                 }
1065                 /* Get a technology/[device:]number pair */
1066                 tech = cur;
1067                 number = strchr(tech, '/');
1068                 if (!number) {
1069                         ast_log(LOG_WARNING, "Dial argument takes format (technology1/[device:]number1&technology2/[device:]number2...|optional timeout)\n");
1070                         goto out;
1071                 }
1072                 *number = '\0';
1073                 number++;
1074                 tmp = malloc(sizeof(struct localuser));
1075                 if (!tmp) {
1076                         ast_log(LOG_WARNING, "Out of memory\n");
1077                         goto out;
1078                 }
1079                 memset(tmp, 0, sizeof(struct localuser));
1080                 if (transfer) {
1081                         ast_set2_flag(tmp, strchr(transfer, 't'), DIAL_ALLOWREDIRECT_IN);
1082                         ast_set2_flag(tmp, strchr(transfer, 'T'), DIAL_ALLOWREDIRECT_OUT);
1083                         ast_set2_flag(tmp, strchr(transfer, 'r'), DIAL_RINGBACKONLY);   
1084                         ast_set2_flag(tmp, strchr(transfer, 'm'), DIAL_MUSICONHOLD);    
1085                         ast_set2_flag(tmp, strchr(transfer, 'H'), DIAL_ALLOWDISCONNECT_OUT);    
1086                         ast_set2_flag(peerflags, strchr(transfer, 'H'), DIAL_ALLOWDISCONNECT_OUT);      
1087                         ast_set2_flag(tmp, strchr(transfer, 'h'), DIAL_ALLOWDISCONNECT_IN);
1088                         ast_set2_flag(peerflags, strchr(transfer, 'h'), DIAL_ALLOWDISCONNECT_IN);
1089                         ast_set2_flag(tmp, strchr(transfer, 'f'), DIAL_FORCECALLERID);  
1090                         ast_set2_flag(tmp, url, DIAL_NOFORWARDHTML);    
1091                         ast_set2_flag(peerflags, strchr(transfer, 'w'), DIAL_MONITOR_IN);       
1092                         ast_set2_flag(peerflags, strchr(transfer, 'W'), DIAL_MONITOR_OUT);      
1093                         ast_set2_flag(peerflags, strchr(transfer, 'd'), DIAL_HALT_ON_DTMF);     
1094                         ast_set2_flag(peerflags, strchr(transfer, 'g'), DIAL_GO_ON);    
1095                         ast_set2_flag(peerflags, strchr(transfer, 'o'), DIAL_PRESERVE_CALLERID);        
1096                 }
1097                 ast_copy_string(numsubst, number, sizeof(numsubst));
1098                 /* If we're dialing by extension, look at the extension to know what to dial */
1099                 if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
1100                         /* strlen("BYEXTENSION") == 11 */
1101                         ast_copy_string(restofit, newnum + 11, sizeof(restofit));
1102                         snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
1103                         if (option_debug)
1104                                 ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
1105                 }
1106                 /* Request the peer */
1107                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
1108                 if (!tmp->chan) {
1109                         /* If we can't, just go on to the next call */
1110                         ast_log(LOG_NOTICE, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
1111                         HANDLE_CAUSE(cause, chan);
1112                         cur = rest;
1113                         if (!cur)
1114                                 chan->hangupcause = cause;
1115                         continue;
1116                 }
1117                 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
1118                 if (!ast_strlen_zero(tmp->chan->call_forward)) {
1119                         char tmpchan[256];
1120                         char *stuff;
1121                         char *tech;
1122                         ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
1123                         if ((stuff = strchr(tmpchan, '/'))) {
1124                                 *stuff = '\0';
1125                                 stuff++;
1126                                 tech = tmpchan;
1127                         } else {
1128                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
1129                                 stuff = tmpchan;
1130                                 tech = "Local";
1131                         }
1132                         tmp->forwards++;
1133                         if (tmp->forwards < AST_MAX_FORWARDS) {
1134                                 if (option_verbose > 2)
1135                                         ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
1136                                 ast_hangup(tmp->chan);
1137                                 /* Setup parameters */
1138                                 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
1139                                 if (!tmp->chan)
1140                                         ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
1141                         } else {
1142                                 if (option_verbose > 2)
1143                                         ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
1144                                 ast_hangup(tmp->chan);
1145                                 tmp->chan = NULL;
1146                                 cause = AST_CAUSE_CONGESTION;
1147                         }
1148                         if (!tmp->chan) {
1149                                 HANDLE_CAUSE(cause, chan);
1150                                 cur = rest;
1151                                 continue;
1152                         }
1153                 }
1154
1155                 /* Inherit specially named variables from parent channel */
1156                 ast_channel_inherit_variables(chan, tmp->chan);
1157
1158                 tmp->chan->appl = "AppDial";
1159                 tmp->chan->data = "(Outgoing Line)";
1160                 tmp->chan->whentohangup = 0;
1161                 if (tmp->chan->cid.cid_num)
1162                         free(tmp->chan->cid.cid_num);
1163                 tmp->chan->cid.cid_num = NULL;
1164                 if (tmp->chan->cid.cid_name)
1165                         free(tmp->chan->cid.cid_name);
1166                 tmp->chan->cid.cid_name = NULL;
1167                 if (tmp->chan->cid.cid_ani)
1168                         free(tmp->chan->cid.cid_ani);
1169                 tmp->chan->cid.cid_ani = NULL;
1170
1171                 if (chan->cid.cid_num) 
1172                         tmp->chan->cid.cid_num = strdup(chan->cid.cid_num);
1173                 if (chan->cid.cid_name) 
1174                         tmp->chan->cid.cid_name = strdup(chan->cid.cid_name);
1175                 if (chan->cid.cid_ani) 
1176                         tmp->chan->cid.cid_ani = strdup(chan->cid.cid_ani);
1177                 
1178                 /* Copy language from incoming to outgoing */
1179                 ast_copy_string(tmp->chan->language, chan->language, sizeof(tmp->chan->language));
1180                 ast_copy_string(tmp->chan->accountcode, chan->accountcode, sizeof(tmp->chan->accountcode));
1181                 tmp->chan->cdrflags = chan->cdrflags;
1182                 if (ast_strlen_zero(tmp->chan->musicclass))
1183                         ast_copy_string(tmp->chan->musicclass, chan->musicclass, sizeof(tmp->chan->musicclass));
1184                 if (chan->cid.cid_rdnis)
1185                         tmp->chan->cid.cid_rdnis = strdup(chan->cid.cid_rdnis);
1186                 /* Pass callingpres setting */
1187                 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
1188                 /* Pass type of number */
1189                 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
1190                 /* Pass type of tns */
1191                 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
1192                 /* Presense of ADSI CPE on outgoing channel follows ours */
1193                 tmp->chan->adsicpe = chan->adsicpe;
1194                 /* Pass the transfer capability */
1195                 tmp->chan->transfercapability = chan->transfercapability;
1196
1197                 /* If we have an outbound group, set this peer channel to it */
1198                 if (outbound_group)
1199                         ast_app_group_set_channel(tmp->chan, outbound_group);
1200
1201                 /* Place the call, but don't wait on the answer */
1202                 res = ast_call(tmp->chan, numsubst, 0);
1203
1204                 /* Save the info in cdr's that we called them */
1205                 if (chan->cdr)
1206                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
1207
1208                 /* check the results of ast_call */
1209                 if (res) {
1210                         /* Again, keep going even if there's an error */
1211                         if (option_debug)
1212                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
1213                         else if (option_verbose > 2)
1214                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
1215                         ast_hangup(tmp->chan);
1216                         tmp->chan = NULL;
1217                         cur = rest;
1218                         continue;
1219                 } else {
1220                         senddialevent(chan, tmp->chan);
1221                         if (option_verbose > 2)
1222                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
1223                         if (!ast_test_flag(peerflags, DIAL_PRESERVE_CALLERID))
1224                                 ast_set_callerid(tmp->chan, ast_strlen_zero(chan->macroexten) ? chan->exten : chan->macroexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
1225                 }
1226                 /* Put them in the list of outgoing thingies...  We're ready now. 
1227                    XXX If we're forcibly removed, these outgoing calls won't get
1228                    hung up XXX */
1229                 ast_set_flag(tmp, DIAL_STILLGOING);     
1230                 tmp->next = outgoing;
1231                 outgoing = tmp;
1232                 /* If this line is up, don't try anybody else */
1233                 if (outgoing->chan->_state == AST_STATE_UP)
1234                         break;
1235                 cur = rest;
1236         } while (cur);
1237         
1238         if (!ast_strlen_zero(timeout)) {
1239                 to = atoi(timeout);
1240                 if (to > 0)
1241                         to *= 1000;
1242                 else
1243                         ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", timeout);
1244         } else
1245                 to = -1;
1246
1247         if (outgoing) {
1248                 /* Our status will at least be NOANSWER */
1249                 strcpy(status, "NOANSWER");
1250                 if (ast_test_flag(outgoing, DIAL_MUSICONHOLD)) {
1251                         moh=1;
1252                         ast_moh_start(chan, mohclass);
1253                 } else if (ast_test_flag(outgoing, DIAL_RINGBACKONLY)) {
1254                         ast_indicate(chan, AST_CONTROL_RINGING);
1255                         sentringing++;
1256                 }
1257         } else
1258                 strcpy(status, "CHANUNAVAIL");
1259
1260         time(&start_time);
1261         peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, priority_jump, &result);
1262         
1263         if (!peer) {
1264                 if (result) {
1265                         res = result;
1266                 } else if (to) 
1267                         /* Musta gotten hung up */
1268                         res = -1;
1269                 else 
1270                         /* Nobody answered, next please? */
1271                         res = 0;
1272                 
1273                 goto out;
1274         }
1275         if (peer) {
1276                 time(&answer_time);
1277 #ifdef OSP_SUPPORT
1278                 /* Once call is answered, ditch the OSP Handle */
1279                 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", "");
1280 #endif
1281                 strcpy(status, "ANSWER");
1282                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
1283                    we will always return with -1 so that it is hung up properly after the 
1284                    conversation.  */
1285                 hanguptree(outgoing, peer);
1286                 outgoing = NULL;
1287                 /* If appropriate, log that we have a destination channel */
1288                 if (chan->cdr)
1289                         ast_cdr_setdestchan(chan->cdr, peer->name);
1290                 if (peer->name)
1291                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
1292
1293                 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
1294                 if (!number)
1295                         number = numsubst;
1296                 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
1297                 if (!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                 }
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 (!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 (!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                                 LOCAL_USER_REMOVE(u);
1648                                 return -1;
1649                         }
1650                         res = ast_bridge_call(chan,peer,&config);
1651                         time(&end_time);
1652                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1653                         pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1654                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1655                         pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1656                         
1657                 } else 
1658                         res = -1;
1659                 
1660                 if (res != AST_PBX_NO_HANGUP_PEER) {
1661                         if (!chan->_softhangup)
1662                                 chan->hangupcause = peer->hangupcause;
1663                         ast_hangup(peer);
1664                 }
1665         }       
1666 out:
1667         if (moh) {
1668                 moh = 0;
1669                 ast_moh_stop(chan);
1670         } else if (sentringing) {
1671                 sentringing = 0;
1672                 ast_indicate(chan, -1);
1673         }
1674         hanguptree(outgoing, NULL);
1675         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1676         ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1677         
1678         if ((ast_test_flag(peerflags, DIAL_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1679                 res=0;
1680         
1681         LOCAL_USER_REMOVE(u);    
1682         
1683         return res;
1684 }
1685
1686 static int dial_exec(struct ast_channel *chan, void *data)
1687 {
1688         struct ast_flags peerflags;
1689         memset(&peerflags, 0, sizeof(peerflags));
1690         return dial_exec_full(chan, data, &peerflags);
1691 }
1692
1693 static int retrydial_exec(struct ast_channel *chan, void *data)
1694 {
1695         char *announce = NULL, *context = NULL, *dialdata = NULL;
1696         int sleep = 0, loops = 0, res = 0;
1697         struct localuser *u;
1698         struct ast_flags peerflags;
1699         
1700         if (ast_strlen_zero(data)) {
1701                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1702                 return -1;
1703         }       
1704
1705         LOCAL_USER_ADD(u);
1706
1707         announce = ast_strdupa(data);   
1708         if (!announce) {        
1709                 ast_log(LOG_ERROR, "Out of memory!\n");
1710                 LOCAL_USER_REMOVE(u);
1711                 return -1;
1712         }
1713         
1714         memset(&peerflags, 0, sizeof(peerflags));
1715
1716         if ((dialdata = strchr(announce, '|'))) {
1717                 *dialdata = '\0';
1718                 dialdata++;
1719                 if ((sleep = atoi(dialdata))) {
1720                         sleep *= 1000;
1721                 } else {
1722                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1723                         LOCAL_USER_REMOVE(u);
1724                         return -1;
1725                 }
1726                 if ((dialdata = strchr(dialdata, '|'))) {
1727                         *dialdata = '\0';
1728                         dialdata++;
1729                         if (!(loops = atoi(dialdata))) {
1730                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1731                                 LOCAL_USER_REMOVE(u);
1732                                 return -1;
1733                         }
1734                 }
1735         }
1736         
1737         if ((dialdata = strchr(dialdata, '|'))) {
1738                 *dialdata = '\0';
1739                 dialdata++;
1740         } else {
1741                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1742                 LOCAL_USER_REMOVE(u);
1743                 return -1;
1744         }
1745                 
1746         if (sleep < 1000)
1747                 sleep = 10000;
1748         
1749         if (!loops)
1750                 loops = -1;
1751         
1752         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1753         
1754         while (loops) {
1755                 chan->data = "Retrying";
1756                 if (ast_test_flag(chan, AST_FLAG_MOH))
1757                         ast_moh_stop(chan);
1758
1759                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1760                         if (ast_test_flag(&peerflags, DIAL_HALT_ON_DTMF)) {
1761                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1762                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1763                                 if (!res && sleep) {
1764                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1765                                                 ast_moh_start(chan, NULL);
1766                                         res = ast_waitfordigit(chan, sleep);
1767                                 }
1768                         } else {
1769                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1770                                         res = ast_waitstream(chan, "");
1771                                 if (sleep) {
1772                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1773                                                 ast_moh_start(chan, NULL);
1774                                         if (!res) 
1775                                                 res = ast_waitfordigit(chan, sleep);
1776                                 }
1777                         }
1778                 }
1779
1780                 if (res < 0)
1781                         break;
1782                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1783                         if (onedigit_goto(chan, context, (char) res, 1)) {
1784                                 res = 0;
1785                                 break;
1786                         }
1787                 }
1788                 loops--;
1789         }
1790         
1791         if (ast_test_flag(chan, AST_FLAG_MOH))
1792                 ast_moh_stop(chan);
1793
1794         LOCAL_USER_REMOVE(u);
1795         return loops ? res : 0;
1796
1797 }
1798
1799 int unload_module(void)
1800 {
1801         int res;
1802
1803         res = ast_unregister_application(app);
1804         res |= ast_unregister_application(rapp);
1805
1806         STANDARD_HANGUP_LOCALUSERS;
1807         
1808         return res;
1809 }
1810
1811 int load_module(void)
1812 {
1813         int res;
1814
1815         res = ast_register_application(app, dial_exec, synopsis, descrip);
1816         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1817         
1818         return res;
1819 }
1820
1821 char *description(void)
1822 {
1823         return tdesc;
1824 }
1825
1826 int usecount(void)
1827 {
1828         int res;
1829         STANDARD_USECOUNT(res);
1830         return res;
1831 }
1832
1833 char *key()
1834 {
1835         return ASTERISK_GPL_KEY;
1836 }