fix up help text (issue #5479)
[asterisk/asterisk.git] / apps / app_dial.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*
20  *
21  * Trivial application to dial a channel and send an URL on answer
22  * 
23  */
24
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <sys/time.h>
32 #include <sys/signal.h>
33 #include <netinet/in.h>
34
35 #include "asterisk.h"
36
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38
39 #include "asterisk/lock.h"
40 #include "asterisk/file.h"
41 #include "asterisk/logger.h"
42 #include "asterisk/channel.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/options.h"
45 #include "asterisk/module.h"
46 #include "asterisk/translate.h"
47 #include "asterisk/say.h"
48 #include "asterisk/config.h"
49 #include "asterisk/features.h"
50 #include "asterisk/musiconhold.h"
51 #include "asterisk/callerid.h"
52 #include "asterisk/utils.h"
53 #include "asterisk/app.h"
54 #include "asterisk/causes.h"
55 #include "asterisk/manager.h"
56 #include "asterisk/privacy.h"
57
58 static char *tdesc = "Dialing Application";
59
60 static char *app = "Dial";
61
62 static char *synopsis = "Place a call and connect to the current channel";
63
64 static char *descrip =
65 "  Dial(Technology/resource[&Technology2/resource2...][|timeout][|options][|URL]):\n"
66 "Requests one or more channels and places specified outgoing calls on them.\n"
67 "As soon as a channel answers, the Dial app will answer the originating\n"
68 "channel (if it needs to be answered) and will bridge a call with the channel\n"
69 "which first answered. All other calls placed by the Dial app will be hung up.\n"
70 "If a timeout is not specified, the Dial application will wait indefinitely\n"
71 "until either one of the called channels answers, the user hangs up, or all\n"
72 "channels return busy or error. In general, the dialer will return 0 if it\n"
73 "was unable to place the call, or the timeout expired. However, if all\n"
74 "channels were busy, and there exists an extension with priority n+101 (where\n"
75 "n is the priority of the dialer instance), then it will be the next\n"
76 "executed extension (this allows you to setup different behavior on busy from\n"
77 "no-answer).\n"
78 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to DONTCALL, \n"
79 "if the called party chooses to send the calling party to the 'Go Away' script, and \n"
80 "the DIALSTATUS variable will be set to TORTURE, if the called party wants to send the caller to \n"
81 "the TORTURE scripts\n"
82 "  This application returns -1 if the originating channel hangs up, or if the\n"
83 "call is bridged and either of the parties in the bridge terminate the call.\n"
84 "The option string may contain zero or more of the following characters:\n"
85 "       '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 (strlen(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 (!data || 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 (!peers || 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 (l && !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 (timeout && !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                 /* JDG: sendurl */
1298                 if ( url && !ast_strlen_zero(url) && ast_channel_supports_html(peer) ) {
1299                         ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
1300                         ast_channel_sendurl( peer, url );
1301                 } /* /JDG */
1302                 if( privacy || screen ) {
1303                         int res2;
1304                         int loopcount = 0;
1305                         if( privdb_val == AST_PRIVACY_UNKNOWN ) {
1306
1307                                 /* Get the user's intro, store it in priv-callerintros/$CID, 
1308                                    unless it is already there-- this should be done before the 
1309                                    call is actually dialed  */
1310
1311                                 /* all ring indications and moh for the caller has been halted as soon as the 
1312                                    target extension was picked up. We are going to have to kill some
1313                                    time and make the caller believe the peer hasn't picked up yet */
1314
1315                                 if ( strchr(transfer, 'm') ) {
1316                                         ast_indicate(chan, -1);
1317                                         ast_moh_start(chan, mohclass);
1318                                 } else if ( strchr(transfer, 'r') ) {
1319                                         ast_indicate(chan, AST_CONTROL_RINGING);
1320                                         sentringing++;
1321                                 }
1322
1323                                 /* Start autoservice on the other chan ?? */
1324                                 res2 = ast_autoservice_start(chan);
1325                                 /* Now Stream the File */
1326                                 if (!res2) {
1327                                         do {
1328                                                 if (!res2)
1329                                                         res2 = ast_play_and_wait(peer,"priv-callpending");
1330                                                 if( res2 < '1' || (privacy && res2>'5') || (screen && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1331                                                         res2 = 0;
1332                                                 
1333                                                 /* priv-callpending script: 
1334                                                    "I have a caller waiting, who introduces themselves as:"
1335                                                 */
1336                                                 if (!res2)
1337                                                         res2 = ast_play_and_wait(peer,privintro);
1338                                                 if( res2 < '1' || (privacy && res2>'5') || (screen && res2 > '4') ) /* uh, interrupting with a bad answer is ... ignorable! */
1339                                                         res2 = 0;
1340                                                 /* now get input from the called party, as to their choice */
1341                                                 if( !res2 ) {
1342                                                         if( privacy )
1343                                                                 res2 = ast_play_and_wait(peer,"priv-callee-options");
1344                                                         if( screen )
1345                                                                 res2 = ast_play_and_wait(peer,"screen-callee-options");
1346                                                 }
1347                                                 /* priv-callee-options script:
1348                                                         "Dial 1 if you wish this caller to reach you directly in the future,
1349                                                                 and immediately connect to their incoming call
1350                                                          Dial 2 if you wish to send this caller to voicemail now and 
1351                                                                 forevermore.
1352                                                          Dial 3 to send this callerr to the torture menus, now and forevermore.
1353                                                          Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1354                                                          Dial 5 to allow this caller to come straight thru to you in the future,
1355                                                 but right now, just this once, send them to voicemail."
1356                                                 */
1357                                 
1358                                                 /* screen-callee-options script:
1359                                                         "Dial 1 if you wish to immediately connect to the incoming call
1360                                                          Dial 2 if you wish to send this caller to voicemail.
1361                                                          Dial 3 to send this callerr to the torture menus.
1362                                                          Dial 4 to send this caller to a simple "go away" menu.
1363                                                 */
1364                                                 if( !res2 || res2 < '1' || (privacy && res2 > '5') || (screen && res2 > '4') ) {
1365                                                         /* invalid option */
1366                                                         res2 = ast_play_and_wait(peer,"vm-sorry");
1367                                                 }
1368                                                 loopcount++; /* give the callee a couple chances to make a choice */
1369                                         } while( (!res2 || res2 < '1' || (privacy && res2 > '5') || (screen && res2 > '4')) && loopcount < 2 );
1370                                 }
1371
1372                                 switch(res2) {
1373                                 case '1':
1374                                         if( privacy ) {
1375                                                 if (option_verbose > 2)
1376                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n", privdb, privcid);
1377                                                 ast_privacy_set(privdb,privcid,AST_PRIVACY_ALLOW);
1378                                         }
1379                                         break;
1380                                 case '2':
1381                                         if( privacy ) {
1382                                                 if (option_verbose > 2)
1383                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n", privdb, privcid);
1384                                                 ast_privacy_set(privdb,privcid,AST_PRIVACY_DENY);
1385                                         }
1386                                         if ( strchr(transfer, 'm') ) {
1387                                                 ast_moh_stop(chan);
1388                                         } else if ( strchr(transfer, 'r') ) {
1389                                                 ast_indicate(chan, -1);
1390                                                 sentringing=0;
1391                                         }
1392                                         res2 = ast_autoservice_stop(chan);
1393                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1394                                         res=0;
1395                                         goto out;
1396                                         break;
1397                                 case '3':
1398                                         if( privacy ) {
1399                                                 ast_privacy_set(privdb,privcid,AST_PRIVACY_TORTURE);
1400                                                 if (option_verbose > 2)
1401                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n", privdb, privcid);
1402                                         }
1403                                         ast_copy_string(status, "TORTURE", sizeof(status));
1404                                         
1405                                         res = 0;
1406                                         if ( strchr(transfer, 'm') ) {
1407                                                 ast_moh_stop(chan);
1408                                         } else if ( strchr(transfer, 'r') ) {
1409                                                 ast_indicate(chan, -1);
1410                                                 sentringing=0;
1411                                         }
1412                                         res2 = ast_autoservice_stop(chan);
1413                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1414                                         goto out; /* Is this right? */
1415                                         break;
1416                                 case '4':
1417                                         if( privacy ) {
1418                                                 if (option_verbose > 2)
1419                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n", privdb, privcid);
1420                                                 ast_privacy_set(privdb,privcid,AST_PRIVACY_KILL);
1421                                         }
1422
1423                                         ast_copy_string(status, "DONTCALL", sizeof(status));
1424                                         res = 0;
1425                                         if ( strchr(transfer, 'm') ) {
1426                                                 ast_moh_stop(chan);
1427                                         } else if ( strchr(transfer, 'r') ) {
1428                                                 ast_indicate(chan, -1);
1429                                                 sentringing=0;
1430                                         }
1431                                         res2 = ast_autoservice_stop(chan);
1432                                         ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1433                                         goto out; /* Is this right? */
1434                                         break;
1435                                 case '5':
1436                                         if( privacy ) {
1437                                                 if (option_verbose > 2)
1438                                                         ast_verbose( VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n", privdb, privcid);
1439                                                 ast_privacy_set(privdb,privcid,AST_PRIVACY_ALLOW);
1440                                         
1441                                                 if ( strchr(transfer, 'm') ) {
1442                                                         ast_moh_stop(chan);
1443                                                 } else if ( strchr(transfer, 'r') ) {
1444                                                         ast_indicate(chan, -1);
1445                                                         sentringing=0;
1446                                                 }
1447                                                 res2 = ast_autoservice_stop(chan);
1448                                                 ast_hangup(peer); /* hang up on the caller -- he didn't want to talk anyway! */
1449                                                 res=0;
1450                                                 goto out;
1451                                                 break;
1452                                         } /* if not privacy, then 5 is the same as "default" case */
1453                                 default:
1454                                         /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1455                                         /* well, there seems basically two choices. Just patch the caller thru immediately,
1456                                                   or,... put 'em thru to voicemail. */
1457                                         /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1458                                         if (option_verbose > 2)
1459                                                 ast_log(LOG_NOTICE,"privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1460                                         if ( strchr(transfer, 'm') ) {
1461                                                 ast_moh_stop(chan);
1462                                         } else if ( strchr(transfer, 'r') ) {
1463                                                 ast_indicate(chan, -1);
1464                                                 sentringing=0;
1465                                         }
1466                                         res2 = ast_autoservice_stop(chan);
1467                                         ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1468                                         res=0;
1469                                         goto out;
1470                                         break;
1471                                 }
1472                                 if ( strchr(transfer, 'm') ) {
1473                                         ast_moh_stop(chan);
1474                                 } else if ( strchr(transfer, 'r') ) {
1475                                         ast_indicate(chan, -1);
1476                                         sentringing=0;
1477                                 }
1478                                 res2 = ast_autoservice_stop(chan);
1479                                 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll 
1480                                    just clog things up, and it's not useful information, not being tied to a CID */
1481                                 if( strncmp(privcid,"NOCALLERID",10) == 0 || no_save_intros ) {
1482                                         ast_filedelete(privintro, NULL);
1483                                         if( ast_fileexists(privintro,NULL,NULL ) > 0 )
1484                                                 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
1485                                         else if (option_verbose > 2)
1486                                                 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
1487                                 }
1488                         }
1489                 }
1490                 if (announce && announcemsg) {
1491                         /* Start autoservice on the other chan */
1492                         res = ast_autoservice_start(chan);
1493                         /* Now Stream the File */
1494                         if (!res)
1495                                 res = ast_streamfile(peer, announcemsg, peer->language);
1496                         if (!res) {
1497                                 digit = ast_waitstream(peer, AST_DIGIT_ANY); 
1498                         }
1499                         /* Ok, done. stop autoservice */
1500                         res = ast_autoservice_stop(chan);
1501                         if (digit > 0 && !res)
1502                                 res = ast_senddigit(chan, digit); 
1503                         else
1504                                 res = digit;
1505
1506                 } else
1507                         res = 0;
1508
1509                 if (chan && peer && dblgoto) {
1510                         for (mac = dblgoto; *mac; mac++) {
1511                                 if(*mac == '^') {
1512                                         *mac = '|';
1513                                 }
1514                         }
1515                         ast_parseable_goto(chan, dblgoto);
1516                         ast_parseable_goto(peer, dblgoto);
1517                         peer->priority++;
1518                         ast_pbx_start(peer);
1519                         hanguptree(outgoing, NULL);
1520                         LOCAL_USER_REMOVE(u);
1521                         return 0;
1522                 }
1523
1524                 if (hasmacro && macroname) {
1525                         res = ast_autoservice_start(chan);
1526                         if (res) {
1527                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
1528                                 res = -1;
1529                         }
1530
1531                         app = pbx_findapp("Macro");
1532
1533                         if (app && !res) {
1534                                 for (res = 0; res<strlen(macroname); res++)
1535                                         if (macroname[res] == '^')
1536                                                 macroname[res] = '|';
1537                                 res = pbx_exec(peer, app, macroname, 1);
1538                                 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
1539                                 res = 0;
1540                         } else {
1541                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
1542                                 res = -1;
1543                         }
1544
1545                         if (ast_autoservice_stop(chan) < 0) {
1546                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
1547                                 res = -1;
1548                         }
1549
1550                         if (!res) {
1551                                 if ((macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
1552                                         if (!strcasecmp(macro_result, "BUSY")) {
1553                                                 ast_copy_string(status, macro_result, sizeof(status));
1554                                                 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
1555                                                         ast_set_flag(peerflags, DIAL_GO_ON);
1556                                                 }
1557                                                 res = -1;
1558                                         }
1559                                         else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
1560                                                 ast_copy_string(status, macro_result, sizeof(status));
1561                                                 ast_set_flag(peerflags, DIAL_GO_ON);    
1562                                                 res = -1;
1563                                         }
1564                                         else if (!strcasecmp(macro_result, "CONTINUE")) {
1565                                                 /* hangup peer and keep chan alive assuming the macro has changed 
1566                                                    the context / exten / priority or perhaps 
1567                                                    the next priority in the current exten is desired.
1568                                                 */
1569                                                 ast_set_flag(peerflags, DIAL_GO_ON);    
1570                                                 res = -1;
1571                                         } else if (!strcasecmp(macro_result, "ABORT")) {
1572                                                 /* Hangup both ends unless the caller has the g flag */
1573                                                 res = -1;
1574                                         } else if (!strncasecmp(macro_result, "GOTO:",5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
1575                                                 res = -1;
1576                                                 /* perform a transfer to a new extension */
1577                                                 if (strchr(macro_transfer_dest,'^')) { /* context^exten^priority*/
1578                                                         /* no brainer mode... substitute ^ with | and feed it to builtin goto */
1579                                                         for (res=0;res<strlen(macro_transfer_dest);res++)
1580                                                                 if (macro_transfer_dest[res] == '^')
1581                                                                         macro_transfer_dest[res] = '|';
1582
1583                                                         if (!ast_parseable_goto(chan, macro_transfer_dest))
1584                                                                 ast_set_flag(peerflags, DIAL_GO_ON);
1585
1586                                                 }
1587                                         }
1588                                 }
1589                         }
1590                 }
1591
1592                 if (!res) {
1593                         if (calldurationlimit > 0) {
1594                                 time(&now);
1595                                 chan->whentohangup = now + calldurationlimit;
1596                         }
1597                         if (dtmfcalled && !ast_strlen_zero(dtmfcalled)) { 
1598                                 if (option_verbose > 2)
1599                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n",dtmfcalled);
1600                                 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
1601                         }
1602                         if (dtmfcalling && !ast_strlen_zero(dtmfcalling)) {
1603                                 if (option_verbose > 2)
1604                                         ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n",dtmfcalling);
1605                                 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
1606                         }
1607                 }
1608                 
1609                 if (!res) {
1610                         memset(&config,0,sizeof(struct ast_bridge_config));
1611                         if (play_to_caller)
1612                                 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
1613                         if (play_to_callee)
1614                                 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
1615                         if (ast_test_flag(peerflags, DIAL_ALLOWREDIRECT_IN))
1616                                 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
1617                         if (ast_test_flag(peerflags, DIAL_ALLOWREDIRECT_OUT))
1618                                 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
1619                         if (ast_test_flag(peerflags, DIAL_ALLOWDISCONNECT_IN))
1620                                 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
1621                         if (ast_test_flag(peerflags, DIAL_ALLOWDISCONNECT_OUT))
1622                                 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
1623                         if (ast_test_flag(peerflags, DIAL_MONITOR_IN))
1624                                 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
1625                         if (ast_test_flag(peerflags, DIAL_MONITOR_OUT)) 
1626                                 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
1627
1628                         config.timelimit = timelimit;
1629                         config.play_warning = play_warning;
1630                         config.warning_freq = warning_freq;
1631                         config.warning_sound = warning_sound;
1632                         config.end_sound = end_sound;
1633                         config.start_sound = start_sound;
1634                         if (moh) {
1635                                 moh = 0;
1636                                 ast_moh_stop(chan);
1637                         } else if (sentringing) {
1638                                 sentringing = 0;
1639                                 ast_indicate(chan, -1);
1640                         }
1641                         /* Be sure no generators are left on it */
1642                         ast_deactivate_generator(chan);
1643                         /* Make sure channels are compatible */
1644                         res = ast_channel_make_compatible(chan, peer);
1645                         if (res < 0) {
1646                                 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
1647                                 ast_hangup(peer);
1648                                 LOCAL_USER_REMOVE(u);
1649                                 return -1;
1650                         }
1651                         res = ast_bridge_call(chan,peer,&config);
1652                         time(&end_time);
1653                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
1654                         pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
1655                         snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
1656                         pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
1657                         
1658                 } else 
1659                         res = -1;
1660                 
1661                 if (res != AST_PBX_NO_HANGUP_PEER) {
1662                         if (!chan->_softhangup)
1663                                 chan->hangupcause = peer->hangupcause;
1664                         ast_hangup(peer);
1665                 }
1666         }       
1667 out:
1668         if (moh) {
1669                 moh = 0;
1670                 ast_moh_stop(chan);
1671         } else if (sentringing) {
1672                 sentringing = 0;
1673                 ast_indicate(chan, -1);
1674         }
1675         hanguptree(outgoing, NULL);
1676         pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
1677         ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
1678         
1679         if ((ast_test_flag(peerflags, DIAL_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
1680                 res=0;
1681         
1682         LOCAL_USER_REMOVE(u);    
1683         
1684         return res;
1685 }
1686
1687 static int dial_exec(struct ast_channel *chan, void *data)
1688 {
1689         struct ast_flags peerflags;
1690         memset(&peerflags, 0, sizeof(peerflags));
1691         return dial_exec_full(chan, data, &peerflags);
1692 }
1693
1694 static int retrydial_exec(struct ast_channel *chan, void *data)
1695 {
1696         char *announce = NULL, *context = NULL, *dialdata = NULL;
1697         int sleep = 0, loops = 0, res = 0;
1698         struct localuser *u;
1699         struct ast_flags peerflags;
1700         
1701         if (!data || ast_strlen_zero(data)) {
1702                 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
1703                 return -1;
1704         }       
1705
1706         LOCAL_USER_ADD(u);
1707
1708         announce = ast_strdupa(data);   
1709         if (!announce) {        
1710                 ast_log(LOG_ERROR, "Out of memory!\n");
1711                 LOCAL_USER_REMOVE(u);
1712                 return -1;
1713         }
1714         
1715         memset(&peerflags, 0, sizeof(peerflags));
1716
1717         if ((dialdata = strchr(announce, '|'))) {
1718                 *dialdata = '\0';
1719                 dialdata++;
1720                 if ((sleep = atoi(dialdata))) {
1721                         sleep *= 1000;
1722                 } else {
1723                         ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
1724                         LOCAL_USER_REMOVE(u);
1725                         return -1;
1726                 }
1727                 if ((dialdata = strchr(dialdata, '|'))) {
1728                         *dialdata = '\0';
1729                         dialdata++;
1730                         if (!(loops = atoi(dialdata))) {
1731                                 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
1732                                 LOCAL_USER_REMOVE(u);
1733                                 return -1;
1734                         }
1735                 }
1736         }
1737         
1738         if ((dialdata = strchr(dialdata, '|'))) {
1739                 *dialdata = '\0';
1740                 dialdata++;
1741         } else {
1742                 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
1743                 LOCAL_USER_REMOVE(u);
1744                 return -1;
1745         }
1746                 
1747         if (sleep < 1000)
1748                 sleep = 10000;
1749         
1750         if (!loops)
1751                 loops = -1;
1752         
1753         context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
1754         
1755         while (loops) {
1756                 chan->data = "Retrying";
1757                 if (ast_test_flag(chan, AST_FLAG_MOH))
1758                         ast_moh_stop(chan);
1759
1760                 if ((res = dial_exec_full(chan, dialdata, &peerflags)) == 0) {
1761                         if (ast_test_flag(&peerflags, DIAL_HALT_ON_DTMF)) {
1762                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1763                                         res = ast_waitstream(chan, AST_DIGIT_ANY);
1764                                 if (!res && sleep) {
1765                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1766                                                 ast_moh_start(chan, NULL);
1767                                         res = ast_waitfordigit(chan, sleep);
1768                                 }
1769                         } else {
1770                                 if (!(res = ast_streamfile(chan, announce, chan->language)))
1771                                         res = ast_waitstream(chan, "");
1772                                 if (sleep) {
1773                                         if (!ast_test_flag(chan, AST_FLAG_MOH))
1774                                                 ast_moh_start(chan, NULL);
1775                                         if (!res) 
1776                                                 res = ast_waitfordigit(chan, sleep);
1777                                 }
1778                         }
1779                 }
1780
1781                 if (res < 0)
1782                         break;
1783                 else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
1784                         if (onedigit_goto(chan, context, (char) res, 1)) {
1785                                 res = 0;
1786                                 break;
1787                         }
1788                 }
1789                 loops--;
1790         }
1791         
1792         if (ast_test_flag(chan, AST_FLAG_MOH))
1793                 ast_moh_stop(chan);
1794
1795         LOCAL_USER_REMOVE(u);
1796         return loops ? res : 0;
1797
1798 }
1799
1800 int unload_module(void)
1801 {
1802         int res;
1803
1804         res = ast_unregister_application(app);
1805         res |= ast_unregister_application(rapp);
1806
1807         STANDARD_HANGUP_LOCALUSERS;
1808         
1809         return res;
1810 }
1811
1812 int load_module(void)
1813 {
1814         int res;
1815
1816         res = ast_register_application(app, dial_exec, synopsis, descrip);
1817         res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
1818         
1819         return res;
1820 }
1821
1822 char *description(void)
1823 {
1824         return tdesc;
1825 }
1826
1827 int usecount(void)
1828 {
1829         int res;
1830         STANDARD_USECOUNT(res);
1831         return res;
1832 }
1833
1834 char *key()
1835 {
1836         return ASTERISK_GPL_KEY;
1837 }