Check result of malloc in app_dial.c
[asterisk/asterisk.git] / apps / app_dial.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Trivial application to dial a channel and send an URL on answer
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/options.h>
20 #include <asterisk/module.h>
21 #include <asterisk/translate.h>
22 #include <asterisk/say.h>
23 #include <asterisk/parking.h>
24 #include <asterisk/musiconhold.h>
25 #include <asterisk/callerid.h>
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 <pthread.h>
37
38 static char *tdesc = "Dialing Application";
39
40 static char *app = "Dial";
41
42 static char *synopsis = "Place a call and connect to the current channel";
43
44 static char *descrip =
45 "  Dial(Technology/resource[&Technology2/resource2...][|timeout][|options][|URL]):\n"
46 "Requests one or more channels and places specified outgoing calls on them.\n"
47 "As soon as a channel answers, the Dial app will answer the originating\n"
48 "channel (if it needs to be answered) and will bridge a call with the channel\n"
49 "which first answered. All other calls placed by the Dial app will be hung up\n"
50 "If a timeout is not specified, the Dial application will wait indefinitely\n"
51 "until either one of the called channels answers, the user hangs up, or all\n"
52 "channels return busy or error. In general, the dialer will return 0 if it\n"
53 "was unable to place the call, or the timeout expired. However, if all\n"
54 "channels were busy, and there exists an extension with priority n+101 (where\n"
55 "n is the priority of the dialer instance), then it will be the next\n"
56 "executed extension (this allows you to setup different behavior on busy from\n"
57 "no-answer).\n"
58 "  This application returns -1 if the originating channel hangs up, or if the\n"
59 "call is bridged and either of the parties in the bridge terminate the call.\n"
60 "The option string may contain zero or more of the following characters:\n"
61 "      't' -- allow the called user transfer the calling user\n"
62 "      'T' -- to allow the calling user to transfer the call.\n"
63 "      'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
64 "      'm' -- provide hold music to the calling party until answered.\n"
65 "      'H' -- allow caller to hang up by hitting *.\n"
66 "      'C' -- reset call detail record for this call.\n"
67 "      'P[(x)]' -- privacy mode, using 'x' as database if provided.\n"
68 "      'g' -- goes on in context if the destination channel hangs up\n"
69 "      'A(x)' -- play an announcement to the called party, using x as file\n"
70 "  In addition to transferring the call, a call may be parked and then picked\n"
71 "up by another user.\n"
72 "  The optional URL will be sent to the called party if the channel supports\n"
73 "it.\n";
74
75 /* We define a customer "local user" structure because we
76    use it not only for keeping track of what is in use but
77    also for keeping track of who we're dialing. */
78
79 struct localuser {
80         struct ast_channel *chan;
81         int stillgoing;
82         int allowredirect_in;
83         int allowredirect_out;
84         int ringbackonly;
85         int musiconhold;
86         int allowdisconnect;
87         struct localuser *next;
88 };
89
90 LOCAL_USER_DECL;
91
92 static void hanguptree(struct localuser *outgoing, struct ast_channel *exception)
93 {
94         /* Hang up a tree of stuff */
95         struct localuser *oo;
96         while(outgoing) {
97                 /* Hangup any existing lines we have open */
98                 if (outgoing->chan && (outgoing->chan != exception))
99                         ast_hangup(outgoing->chan);
100                 oo = outgoing;
101                 outgoing=outgoing->next;
102                 free(oo);
103         }
104 }
105
106 #define MAX 256
107
108 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect)
109 {
110         struct localuser *o;
111         int found;
112         int numlines;
113         int sentringing = 0;
114         int numbusies = 0;
115         int orig = *to;
116         struct ast_frame *f;
117         struct ast_channel *peer = NULL;
118         struct ast_channel *watchers[MAX];
119         int pos;
120         int single;
121         int moh=0;
122         int ringind=0;
123         struct ast_channel *winner;
124         
125         single = (outgoing && !outgoing->next && !outgoing->musiconhold && !outgoing->ringbackonly);
126         
127         if (single) {
128                 /* Turn off hold music, etc */
129                 ast_indicate(in, -1);
130                 /* If we are calling a single channel, make them compatible for in-band tone purpose */
131                 ast_channel_make_compatible(outgoing->chan, in);
132         }
133         
134         if (outgoing) {
135                 moh = outgoing->musiconhold;
136                 ringind = outgoing->ringbackonly;
137                 if (outgoing->musiconhold) {
138                         ast_moh_start(in, NULL);
139                 } else if (outgoing->ringbackonly) {
140                         ast_indicate(in, AST_CONTROL_RINGING);
141                 }
142         }
143         
144         while(*to && !peer) {
145                 o = outgoing;
146                 found = -1;
147                 pos = 1;
148                 numlines = 0;
149                 watchers[0] = in;
150                 while(o) {
151                         /* Keep track of important channels */
152                         if (o->stillgoing && o->chan) {
153                                 watchers[pos++] = o->chan;
154                                 found = 1;
155                         }
156                         o = o->next;
157                         numlines++;
158                 }
159                 if (found < 0) {
160                         if (numlines == numbusies) {
161                                 if (option_verbose > 2)
162                                         ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy at this time\n");
163                                 /* See if there is a special busy message */
164                                 if (ast_exists_extension(in, in->context, in->exten, in->priority + 101, in->callerid)) 
165                                         in->priority+=100;
166                         } else {
167                                 if (option_verbose > 2)
168                                         ast_verbose( VERBOSE_PREFIX_2 "No one is available to answer at this time\n");
169                         }
170                         *to = 0;
171                         /* if no one available we'd better stop MOH/ringing to */
172                         if (moh) {
173                                 ast_moh_stop(in);
174                         } else if (ringind) {
175                                 ast_indicate(in, -1);
176                         }
177                         return NULL;
178                 }
179                 winner = ast_waitfor_n(watchers, pos, to);
180                 o = outgoing;
181                 while(o) {
182                         if (o->stillgoing && o->chan && (o->chan->_state == AST_STATE_UP)) {
183                                 if (!peer) {
184                                         if (option_verbose > 2)
185                                                 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
186                                         peer = o->chan;
187                                         *allowredir_in = o->allowredirect_in;
188                                         *allowredir_out = o->allowredirect_out;
189                                         *allowdisconnect = o->allowdisconnect;
190                                 }
191                         } else if (o->chan && (o->chan == winner)) {
192                                 if (strlen(o->chan->call_forward)) {
193                                         char tmpchan[256];
194                                         /* Before processing channel, go ahead and check for forwarding */
195                                         if (option_verbose > 2)
196                                                 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s@%s' (thanks to %s)\n", in->name, o->chan->call_forward, o->chan->context, o->chan->name);
197                                         /* Setup parameters */
198                                         snprintf(tmpchan, sizeof(tmpchan),"%s@%s", o->chan->call_forward, o->chan->context);
199                                         ast_hangup(o->chan);
200                                         o->chan = ast_request("Local", in->nativeformats, tmpchan);
201                                         if (!o->chan) {
202                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s'\n", tmpchan);
203                                                 o->stillgoing = 0;
204                                                 numbusies++;
205                                         } else {
206                                                 if (in->callerid) {
207                                                         if (o->chan->callerid)
208                                                                 free(o->chan->callerid);
209                                                         o->chan->callerid = malloc(strlen(in->callerid) + 1);
210                                                         if (o->chan->callerid)
211                                                                 strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
212                                                         else
213                                                                 ast_log(LOG_WARNING, "Out of memory\n");
214                                                 }
215                                                 if (in->ani) {
216                                                         if (o->chan->ani)
217                                                                 free(o->chan->ani);
218                                                         o->chan->ani = malloc(strlen(in->ani) + 1);
219                                                         if (o->chan->ani)
220                                                                 strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
221                                                         else
222                                                                 ast_log(LOG_WARNING, "Out of memory\n");
223                                                 }
224                                                 if (ast_call(o->chan, tmpchan, 0)) {
225                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
226                                                         o->stillgoing = 0;
227                                                         ast_hangup(o->chan);
228                                                         o->chan = NULL;
229                                                         numbusies++;
230                                                 }
231                                         }
232                                         continue;
233                                 }
234                                 f = ast_read(winner);
235                                 if (f) {
236                                         if (f->frametype == AST_FRAME_CONTROL) {
237                                                 switch(f->subclass) {
238                                             case AST_CONTROL_ANSWER:
239                                                         /* This is our guy if someone answered. */
240                                                         if (!peer) {
241                                                                 if (option_verbose > 2)
242                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
243                                                                 peer = o->chan;
244                                                                 *allowredir_in = o->allowredirect_in;
245                                                                 *allowredir_out = o->allowredirect_out;
246                                                                 *allowdisconnect = o->allowdisconnect;
247                                                         }
248                                                         break;
249                                                 case AST_CONTROL_BUSY:
250                                                         if (option_verbose > 2)
251                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
252                                                         in->hangupcause = o->chan->hangupcause;
253                                                         ast_hangup(o->chan);
254                                                         o->chan = NULL;
255                                                         o->stillgoing = 0;
256                                                         if (in->cdr)
257                                                                 ast_cdr_busy(in->cdr);
258                                                         numbusies++;
259                                                         break;
260                                                 case AST_CONTROL_CONGESTION:
261                                                         if (option_verbose > 2)
262                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
263                                                         in->hangupcause = o->chan->hangupcause;
264                                                         ast_hangup(o->chan);
265                                                         o->chan = NULL;
266                                                         o->stillgoing = 0;
267                                                         if (in->cdr)
268                                                                 ast_cdr_busy(in->cdr);
269                                                         numbusies++;
270                                                         break;
271                                                 case AST_CONTROL_RINGING:
272                                                         if (option_verbose > 2)
273                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
274                                                         if (!sentringing && !moh) {
275                                                                 ast_indicate(in, AST_CONTROL_RINGING);
276                                                                 sentringing++;
277                                                                 ringind++;
278                                                         }
279                                                         break;
280                                                 case AST_CONTROL_PROGRESS:
281                                                         if (option_verbose > 2)
282                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
283                                                         ast_indicate(in, AST_CONTROL_PROGRESS);
284                                                         break;
285                                                 case AST_CONTROL_OFFHOOK:
286                                                         /* Ignore going off hook */
287                                                         break;
288                                                 case -1:
289                                                         if (option_verbose > 2)
290                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
291                                                         ast_indicate(in, -1);
292                                                         break;
293                                                 default:
294                                                         ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
295                                                 }
296                                         } else if (single && (f->frametype == AST_FRAME_VOICE) && 
297                                                                 !(outgoing->ringbackonly || outgoing->musiconhold)) {
298                                                 if (ast_write(in, f)) 
299                                                         ast_log(LOG_WARNING, "Unable to forward frame\n");
300                                         } else if (single && (f->frametype == AST_FRAME_IMAGE) && 
301                                                                 !(outgoing->ringbackonly || outgoing->musiconhold)) {
302                                                 if (ast_write(in, f))
303                                                         ast_log(LOG_WARNING, "Unable to forward image\n");
304                                         }
305                                         ast_frfree(f);
306                                 } else {
307                                         in->hangupcause = o->chan->hangupcause;
308                                         ast_hangup(o->chan);
309                                         o->chan = NULL;
310                                         o->stillgoing = 0;
311                                 }
312                         }
313                         o = o->next;
314                 }
315                 if (winner == in) {
316                         f = ast_read(in);
317 #if 0
318                         if (f && (f->frametype != AST_FRAME_VOICE))
319                                         printf("Frame type: %d, %d\n", f->frametype, f->subclass);
320                         else if (!f || (f->frametype != AST_FRAME_VOICE))
321                                 printf("Hangup received on %s\n", in->name);
322 #endif
323                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
324                                 /* Got hung up */
325                                 *to=-1;
326                                 return NULL;
327                         }
328                         if (f && (f->frametype == AST_FRAME_DTMF) && *allowdisconnect &&
329                                 (f->subclass == '*')) {
330                             if (option_verbose > 3)
331                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
332                                 *to=0;
333                                 return NULL;
334                         }
335                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
336                                 if (ast_write(outgoing->chan, f))
337                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
338                                 ast_frfree(f);
339                         }
340                 }
341                 if (!*to && (option_verbose > 2))
342                         ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
343         }
344         if (moh) {
345                 ast_moh_stop(in);
346         } else if (ringind) {
347                 ast_indicate(in, -1);
348         }
349
350         return peer;
351         
352 }
353
354 static int dial_exec(struct ast_channel *chan, void *data)
355 {
356         int res=-1;
357         struct localuser *u;
358         char info[256], *peers, *timeout, *tech, *number, *rest, *cur;
359         char  privdb[256] = "", *s;
360         char  announcemsg[256] = "", *ann;
361         struct localuser *outgoing=NULL, *tmp;
362         struct ast_channel *peer;
363         int to;
364         int allowredir_in=0;
365         int allowredir_out=0;
366         int allowdisconnect=0;
367         int privacy=0;
368         int announce=0;
369         int resetcdr=0;
370         char numsubst[AST_MAX_EXTENSION];
371         char restofit[AST_MAX_EXTENSION];
372         char *transfer = NULL;
373         char *newnum;
374         char callerid[256], *l, *n;
375         char *url=NULL; /* JDG */
376         struct ast_var_t *current;
377         struct varshead *headp, *newheadp;
378         struct ast_var_t *newvar;
379         int go_on=0;
380         
381         if (!data) {
382                 ast_log(LOG_WARNING, "Dial requires an argument (technology1/number1&technology2/number2...|optional timeout)\n");
383                 return -1;
384         }
385         
386         LOCAL_USER_ADD(u);
387         
388         strncpy(info, (char *)data, sizeof(info) - 1);
389         peers = info;
390         if (peers) {
391                 timeout = strchr(info, '|');
392                 if (timeout) {
393                         *timeout = '\0';
394                         timeout++;
395                         transfer = strchr(timeout, '|');
396                         if (transfer) {
397                                 *transfer = '\0';
398                                 transfer++;
399                                 /* JDG */
400                                 url = strchr(transfer, '|');
401                                 if (url) {
402                                         *url = '\0';
403                                         url++;
404                                         ast_log(LOG_DEBUG, "DIAL WITH URL=%s_\n", url);
405                                 } else 
406                                         ast_log(LOG_DEBUG, "SIMPLE DIAL (NO URL)\n");
407                                 /* /JDG */
408                         }
409                 }
410         } else
411                 timeout = NULL;
412         if (!peers || !strlen(peers)) {
413                 ast_log(LOG_WARNING, "Dial argument takes format (technology1/number1&technology2/number2...|optional timeout)\n");
414                 goto out;
415         }
416         
417
418         if (transfer) {
419                 /* XXX ANNOUNCE SUPPORT */
420                 if ((ann = strstr(transfer, "A("))) {
421                         announce = 1;
422                         strncpy(announcemsg, ann + 2, sizeof(announcemsg) - 1);
423                         /* Overwrite with X's what was the announce info */
424                         while(*ann && (*ann != ')')) 
425                                 *(ann++) = 'X';
426                         if (*ann)
427                                 *ann = 'X';
428                         /* Now find the end of the privdb */
429                         ann = strchr(announcemsg, ')');
430                         if (ann)
431                                 *ann = '\0';
432                         else {
433                                 ast_log(LOG_WARNING, "Transfer with Announce spec lacking trailing ')'\n");
434                                 announce = 0;
435                         }
436                 }
437                 /* Extract privacy info from transfer */
438                 if ((s = strstr(transfer, "P("))) {
439                         privacy = 1;
440                         strncpy(privdb, s + 2, sizeof(privdb) - 1);
441                         /* Overwrite with X's what was the privacy info */
442                         while(*s && (*s != ')')) 
443                                 *(s++) = 'X';
444                         if (*s)
445                                 *s = 'X';
446                         /* Now find the end of the privdb */
447                         s = strchr(privdb, ')');
448                         if (s)
449                                 *s = '\0';
450                         else {
451                                 ast_log(LOG_WARNING, "Transfer with privacy lacking trailing ')'\n");
452                                 privacy = 0;
453                         }
454                 } else if (strchr(transfer, 'P')) {
455                         /* No specified privdb */
456                         privacy = 1;
457                 } else if (strchr(transfer, 'C')) {
458                         resetcdr = 1;
459                 }
460         }
461         if (resetcdr && chan->cdr)
462                 ast_cdr_reset(chan->cdr, 0);
463         if (!strlen(privdb) && privacy) {
464                 /* If privdb is not specified and we are using privacy, copy from extension */
465                 strncpy(privdb, chan->exten, sizeof(privdb) - 1);
466         }
467         if (privacy) {
468                 if (chan->callerid)
469                         strncpy(callerid, chan->callerid, sizeof(callerid));
470                 else
471                         strcpy(callerid, "");
472                 ast_callerid_parse(callerid, &n, &l);
473                 if (l) {
474                         ast_shrink_phone_number(l);
475                 } else
476                         l = "";
477                 ast_log(LOG_NOTICE, "Privacy DB is '%s', privacy is %d, clid is '%s'\n", privdb, privacy, l);
478         }
479         cur = peers;
480         do {
481                 /* Remember where to start next time */
482                 rest = strchr(cur, '&');
483                 if (rest) {
484                         *rest = 0;
485                         rest++;
486                 }
487                 /* Get a technology/[device:]number pair */
488                 tech = cur;
489                 number = strchr(tech, '/');
490                 if (!number) {
491                         ast_log(LOG_WARNING, "Dial argument takes format (technology1/[device:]number1&technology2/[device:]number2...|optional timeout)\n");
492                         goto out;
493                 }
494                 *number = '\0';
495                 number++;
496                 tmp = malloc(sizeof(struct localuser));
497                 if (!tmp) {
498                         ast_log(LOG_WARNING, "Out of memory\n");
499                         goto out;
500                 }
501                 memset(tmp, 0, sizeof(struct localuser));
502                 if (transfer) {
503                         if (strchr(transfer, 't'))
504                                 tmp->allowredirect_in = 1;
505                         else    tmp->allowredirect_in = 0;
506                         if (strchr(transfer, 'T'))
507                                 tmp->allowredirect_out = 1;
508                         else    tmp->allowredirect_out = 0;
509                         if (strchr(transfer, 'r'))
510                                 tmp->ringbackonly = 1;
511                         else    tmp->ringbackonly = 0;
512                         if (strchr(transfer, 'm'))
513                                 tmp->musiconhold = 1;
514                         else    tmp->musiconhold = 0;
515                         if (strchr(transfer, 'H'))
516                                 allowdisconnect = tmp->allowdisconnect = 1;
517                         else    allowdisconnect = tmp->allowdisconnect = 0;
518                         if(strchr(transfer, 'g'))
519                                 go_on=1;
520                 }
521                 strncpy(numsubst, number, sizeof(numsubst)-1);
522                 /* If we're dialing by extension, look at the extension to know what to dial */
523                 if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
524                         strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
525                         snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
526                         if (option_debug)
527                                 ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
528                 }
529                 /* Request the peer */
530                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
531                 if (!tmp->chan) {
532                         /* If we can't, just go on to the next call */
533                         ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", tech);
534                         if (chan->cdr)
535                                 ast_cdr_busy(chan->cdr);
536                         free(tmp);
537                         cur = rest;
538                         continue;
539                 }
540                 if (strlen(tmp->chan->call_forward)) {
541                         char tmpchan[256];
542                         if (option_verbose > 2)
543                                 ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
544                         snprintf(tmpchan, sizeof(tmpchan),"%s@%s", tmp->chan->call_forward, tmp->chan->context);
545                         ast_hangup(tmp->chan);
546                         tmp->chan = ast_request("Local", chan->nativeformats, tmpchan);
547                         if (!tmp->chan) {
548                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s'\n", tmpchan);
549                                 free(tmp);
550                                 cur = rest;
551                                 continue;
552                         }
553                 }
554                 /* If creating a SIP channel, look for a variable called */
555                 /* VXML_URL in the calling channel and copy it to the    */
556                 /* new channel.                                          */
557                 if (strcasecmp(tech,"SIP")==0)
558                 {
559                         headp=&chan->varshead;
560                         AST_LIST_TRAVERSE(headp,current,entries) {
561                                 if (strcasecmp(ast_var_name(current),"VXML_URL")==0)
562                                 {
563                                         newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
564                                         newheadp=&tmp->chan->varshead;
565                                         AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
566                                         break;
567                                 }
568                         }
569                 }
570                 /* Check for ALERT_INFO in the SetVar list.  This is for   */
571                 /* SIP distinctive ring as per the RFC.  For Cisco 7960s,  */
572                 /* SetVar(ALERT_INFO=<x>) where x is an integer value 1-5. */
573                 /* However, the RFC says it should be a URL.  -km-         */
574
575                 if (strcasecmp(tech,"SIP")==0)
576                 {
577                         headp=&chan->varshead;
578                         AST_LIST_TRAVERSE(headp,current,entries) {
579                                 /* Search for ALERT_INFO */
580                                 if (strcasecmp(ast_var_name(current),"ALERT_INFO")==0)
581                                 {
582                                         newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
583                                         newheadp=&tmp->chan->varshead;
584                                         AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
585                                         break;
586                                 }
587                         }
588                 }
589                 
590                 tmp->chan->appl = "AppDial";
591                 tmp->chan->data = "(Outgoing Line)";
592                 tmp->chan->whentohangup = 0;
593                 if (tmp->chan->callerid)
594                         free(tmp->chan->callerid);
595                 if (tmp->chan->ani)
596                         free(tmp->chan->ani);
597                 if (chan->callerid)
598                         tmp->chan->callerid = strdup(chan->callerid);
599                 else
600                         tmp->chan->callerid = NULL;
601                 /* Copy language from incoming to outgoing */
602                 strcpy(tmp->chan->language, chan->language);
603                 if (!strlen(tmp->chan->musicclass))
604                         strncpy(tmp->chan->musicclass, chan->musicclass, sizeof(tmp->chan->musicclass) - 1);
605                 if (chan->ani)
606                         tmp->chan->ani = strdup(chan->ani);
607                 else
608                         tmp->chan->ani = NULL;
609                 /* Pass hidecallerid setting */
610                 tmp->chan->restrictcid = chan->restrictcid;
611                 /* Pass callingpres setting */
612                 tmp->chan->callingpres = chan->callingpres;
613                 /* Presense of ADSI CPE on outgoing channel follows ours */
614                 tmp->chan->adsicpe = chan->adsicpe;
615                 /* pass the digital flag */
616                 ast_dup_flag(tmp->chan, chan, AST_FLAG_DIGITAL);
617                 /* Place the call, but don't wait on the answer */
618                 res = ast_call(tmp->chan, numsubst, 0);
619
620                 /* Save the info in cdr's that we called them */
621                 if (chan->cdr)
622                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
623
624                 /* check the restuls of ast_call */
625                 if (res) {
626                         /* Again, keep going even if there's an error */
627                         if (option_debug)
628                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
629                         else if (option_verbose > 2)
630                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
631                         ast_hangup(tmp->chan);
632                         free(tmp);
633                         cur = rest;
634                         continue;
635                 } else
636                         if (option_verbose > 2)
637                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
638                 /* Put them in the list of outgoing thingies...  We're ready now. 
639                    XXX If we're forcibly removed, these outgoing calls won't get
640                    hung up XXX */
641                 tmp->stillgoing = -1;
642                 tmp->next = outgoing;
643                 outgoing = tmp;
644                 /* If this line is up, don't try anybody else */
645                 if (outgoing->chan->_state == AST_STATE_UP)
646                         break;
647                 cur = rest;
648         } while(cur);
649         
650         if (timeout && strlen(timeout))
651                 to = atoi(timeout) * 1000;
652         else
653                 to = -1;
654         peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect);
655         if (!peer) {
656                 if (to) 
657                         /* Musta gotten hung up */
658                         res = -1;
659                  else 
660                         /* Nobody answered, next please? */
661                         res=0;
662                 
663                 goto out;
664         }
665         if (peer) {
666                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
667                    we will always return with -1 so that it is hung up properly after the 
668                    conversation.  */
669                 hanguptree(outgoing, peer);
670                 outgoing = NULL;
671                 /* If appropriate, log that we have a destination channel */
672                 if (chan->cdr)
673                         ast_cdr_setdestchan(chan->cdr, peer->name);
674                 if (peer->name)
675                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
676                 if (numsubst)
677                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", numsubst);
678                 /* Make sure channels are compatible */
679                 res = ast_channel_make_compatible(chan, peer);
680                 if (res < 0) {
681                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
682                         ast_hangup(peer);
683                         return -1;
684                 }
685                 /* JDG: sendurl */
686                 if( url && strlen(url) && ast_channel_supports_html(peer) ) {
687                         ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
688                         ast_channel_sendurl( peer, url );
689                 } /* /JDG */
690                 if (announce && announcemsg)
691                 {
692                         int res2;
693                         // Start autoservice on the other chan
694                         res2 = ast_autoservice_start(chan);
695                         // Now Stream the File
696                         if (!res2)
697                                 res2 = ast_streamfile(peer,announcemsg,peer->language);
698                         if (!res2)
699                                 res2 = ast_waitstream(peer,"");
700                         // Ok, done. stop autoservice
701                         res2 = ast_autoservice_stop(chan);
702                 }
703                 res = ast_bridge_call(chan, peer, allowredir_in, allowredir_out, allowdisconnect);
704
705                 if (res != AST_PBX_NO_HANGUP_PEER)
706                         ast_hangup(peer);
707         }       
708 out:
709         hanguptree(outgoing, NULL);
710         LOCAL_USER_REMOVE(u);
711         
712         if((go_on>0) && (!chan->_softhangup))
713             res=0;
714             
715         return res;
716 }
717
718 int unload_module(void)
719 {
720         STANDARD_HANGUP_LOCALUSERS;
721         return ast_unregister_application(app);
722 }
723
724 int load_module(void)
725 {
726         int res;
727         res = ast_register_application(app, dial_exec, synopsis, descrip);
728         return res;
729 }
730
731 char *description(void)
732 {
733         return tdesc;
734 }
735
736 int usecount(void)
737 {
738         int res;
739         STANDARD_USECOUNT(res);
740         return res;
741 }
742
743 char *key()
744 {
745         return ASTERISK_GPL_KEY;
746 }