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