Spelling error 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 dialler 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 dialler 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                                                         strncpy(o->chan->callerid, in->callerid, strlen(in->callerid) + 1);
211                                                 }
212                                                 if (in->ani) {
213                                                         if (o->chan->ani)
214                                                                 free(o->chan->ani);
215                                                         o->chan->ani = malloc(strlen(in->ani) + 1);
216                                                         strncpy(o->chan->ani, in->ani, strlen(in->ani) + 1);
217                                                 }
218                                                 if (ast_call(o->chan, tmpchan, 0)) {
219                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
220                                                         o->stillgoing = 0;
221                                                         ast_hangup(o->chan);
222                                                         o->chan = NULL;
223                                                         numbusies++;
224                                                 }
225                                         }
226                                         continue;
227                                 }
228                                 f = ast_read(winner);
229                                 if (f) {
230                                         if (f->frametype == AST_FRAME_CONTROL) {
231                                                 switch(f->subclass) {
232                                             case AST_CONTROL_ANSWER:
233                                                         /* This is our guy if someone answered. */
234                                                         if (!peer) {
235                                                                 if (option_verbose > 2)
236                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
237                                                                 peer = o->chan;
238                                                                 *allowredir_in = o->allowredirect_in;
239                                                                 *allowredir_out = o->allowredirect_out;
240                                                                 *allowdisconnect = o->allowdisconnect;
241                                                         }
242                                                         break;
243                                                 case AST_CONTROL_BUSY:
244                                                         if (option_verbose > 2)
245                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
246                                                         in->hangupcause = o->chan->hangupcause;
247                                                         ast_hangup(o->chan);
248                                                         o->chan = NULL;
249                                                         o->stillgoing = 0;
250                                                         if (in->cdr)
251                                                                 ast_cdr_busy(in->cdr);
252                                                         numbusies++;
253                                                         break;
254                                                 case AST_CONTROL_CONGESTION:
255                                                         if (option_verbose > 2)
256                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
257                                                         in->hangupcause = o->chan->hangupcause;
258                                                         ast_hangup(o->chan);
259                                                         o->chan = NULL;
260                                                         o->stillgoing = 0;
261                                                         if (in->cdr)
262                                                                 ast_cdr_busy(in->cdr);
263                                                         numbusies++;
264                                                         break;
265                                                 case AST_CONTROL_RINGING:
266                                                         if (option_verbose > 2)
267                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
268                                                         if (!sentringing && !moh) {
269                                                                 ast_indicate(in, AST_CONTROL_RINGING);
270                                                                 sentringing++;
271                                                                 ringind++;
272                                                         }
273                                                         break;
274                                                 case AST_CONTROL_PROGRESS:
275                                                         if (option_verbose > 2)
276                                                                 ast_verbose ( VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
277                                                         ast_indicate(in, AST_CONTROL_PROGRESS);
278                                                         break;
279                                                 case AST_CONTROL_OFFHOOK:
280                                                         /* Ignore going off hook */
281                                                         break;
282                                                 case -1:
283                                                         if (option_verbose > 2)
284                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
285                                                         ast_indicate(in, -1);
286                                                         break;
287                                                 default:
288                                                         ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
289                                                 }
290                                         } else if (single && (f->frametype == AST_FRAME_VOICE) && 
291                                                                 !(outgoing->ringbackonly || outgoing->musiconhold)) {
292                                                 if (ast_write(in, f)) 
293                                                         ast_log(LOG_WARNING, "Unable to forward frame\n");
294                                         } else if (single && (f->frametype == AST_FRAME_IMAGE) && 
295                                                                 !(outgoing->ringbackonly || outgoing->musiconhold)) {
296                                                 if (ast_write(in, f))
297                                                         ast_log(LOG_WARNING, "Unable to forward image\n");
298                                         }
299                                         ast_frfree(f);
300                                 } else {
301                                         in->hangupcause = o->chan->hangupcause;
302                                         ast_hangup(o->chan);
303                                         o->chan = NULL;
304                                         o->stillgoing = 0;
305                                 }
306                         }
307                         o = o->next;
308                 }
309                 if (winner == in) {
310                         f = ast_read(in);
311 #if 0
312                         if (f && (f->frametype != AST_FRAME_VOICE))
313                                         printf("Frame type: %d, %d\n", f->frametype, f->subclass);
314                         else if (!f || (f->frametype != AST_FRAME_VOICE))
315                                 printf("Hangup received on %s\n", in->name);
316 #endif
317                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
318                                 /* Got hung up */
319                                 *to=-1;
320                                 return NULL;
321                         }
322                         if (f && (f->frametype == AST_FRAME_DTMF) && *allowdisconnect &&
323                                 (f->subclass == '*')) {
324                             if (option_verbose > 3)
325                                 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
326                                 *to=0;
327                                 return NULL;
328                         }
329                         if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF)))  {
330                                 if (ast_write(outgoing->chan, f))
331                                         ast_log(LOG_WARNING, "Unable to forward voice\n");
332                                 ast_frfree(f);
333                         }
334                 }
335                 if (!*to && (option_verbose > 2))
336                         ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
337         }
338         if (moh) {
339                 ast_moh_stop(in);
340         } else if (ringind) {
341                 ast_indicate(in, -1);
342         }
343
344         return peer;
345         
346 }
347
348 static int dial_exec(struct ast_channel *chan, void *data)
349 {
350         int res=-1;
351         struct localuser *u;
352         char info[256], *peers, *timeout, *tech, *number, *rest, *cur;
353         char  privdb[256] = "", *s;
354         char  announcemsg[256] = "", *ann;
355         struct localuser *outgoing=NULL, *tmp;
356         struct ast_channel *peer;
357         int to;
358         int allowredir_in=0;
359         int allowredir_out=0;
360         int allowdisconnect=0;
361         int privacy=0;
362         int announce=0;
363         int resetcdr=0;
364         char numsubst[AST_MAX_EXTENSION];
365         char restofit[AST_MAX_EXTENSION];
366         char *transfer = NULL;
367         char *newnum;
368         char callerid[256], *l, *n;
369         char *url=NULL; /* JDG */
370         struct ast_var_t *current;
371         struct varshead *headp, *newheadp;
372         struct ast_var_t *newvar;
373         int go_on=0;
374         
375         if (!data) {
376                 ast_log(LOG_WARNING, "Dial requires an argument (technology1/number1&technology2/number2...|optional timeout)\n");
377                 return -1;
378         }
379         
380         LOCAL_USER_ADD(u);
381         
382         strncpy(info, (char *)data, sizeof(info) - 1);
383         peers = info;
384         if (peers) {
385                 timeout = strchr(info, '|');
386                 if (timeout) {
387                         *timeout = '\0';
388                         timeout++;
389                         transfer = strchr(timeout, '|');
390                         if (transfer) {
391                                 *transfer = '\0';
392                                 transfer++;
393                                 /* JDG */
394                                 url = strchr(transfer, '|');
395                                 if (url) {
396                                         *url = '\0';
397                                         url++;
398                                         ast_log(LOG_DEBUG, "DIAL WITH URL=%s_\n", url);
399                                 } else 
400                                         ast_log(LOG_DEBUG, "SIMPLE DIAL (NO URL)\n");
401                                 /* /JDG */
402                         }
403                 }
404         } else
405                 timeout = NULL;
406         if (!peers || !strlen(peers)) {
407                 ast_log(LOG_WARNING, "Dial argument takes format (technology1/number1&technology2/number2...|optional timeout)\n");
408                 goto out;
409         }
410         
411
412         if (transfer) {
413                 /* XXX ANNOUNCE SUPPORT */
414                 if ((ann = strstr(transfer, "A("))) {
415                         announce = 1;
416                         strncpy(announcemsg, ann + 2, sizeof(announcemsg) - 1);
417                         /* Overwrite with X's what was the announce info */
418                         while(*ann && (*ann != ')')) 
419                                 *(ann++) = 'X';
420                         if (*ann)
421                                 *ann = 'X';
422                         /* Now find the end of the privdb */
423                         ann = strchr(announcemsg, ')');
424                         if (ann)
425                                 *ann = '\0';
426                         else {
427                                 ast_log(LOG_WARNING, "Transfer with Announce spec lacking trailing ')'\n");
428                                 announce = 0;
429                         }
430                 }
431                 /* Extract privacy info from transfer */
432                 if ((s = strstr(transfer, "P("))) {
433                         privacy = 1;
434                         strncpy(privdb, s + 2, sizeof(privdb) - 1);
435                         /* Overwrite with X's what was the privacy info */
436                         while(*s && (*s != ')')) 
437                                 *(s++) = 'X';
438                         if (*s)
439                                 *s = 'X';
440                         /* Now find the end of the privdb */
441                         s = strchr(privdb, ')');
442                         if (s)
443                                 *s = '\0';
444                         else {
445                                 ast_log(LOG_WARNING, "Transfer with privacy lacking trailing ')'\n");
446                                 privacy = 0;
447                         }
448                 } else if (strchr(transfer, 'P')) {
449                         /* No specified privdb */
450                         privacy = 1;
451                 } else if (strchr(transfer, 'C')) {
452                         resetcdr = 1;
453                 }
454         }
455         if (resetcdr && chan->cdr)
456                 ast_cdr_reset(chan->cdr, 0);
457         if (!strlen(privdb) && privacy) {
458                 /* If privdb is not specified and we are using privacy, copy from extension */
459                 strncpy(privdb, chan->exten, sizeof(privdb) - 1);
460         }
461         if (privacy) {
462                 if (chan->callerid)
463                         strncpy(callerid, chan->callerid, sizeof(callerid));
464                 else
465                         strcpy(callerid, "");
466                 ast_callerid_parse(callerid, &n, &l);
467                 if (l) {
468                         ast_shrink_phone_number(l);
469                 } else
470                         l = "";
471                 ast_log(LOG_NOTICE, "Privacy DB is '%s', privacy is %d, clid is '%s'\n", privdb, privacy, l);
472         }
473         cur = peers;
474         do {
475                 /* Remember where to start next time */
476                 rest = strchr(cur, '&');
477                 if (rest) {
478                         *rest = 0;
479                         rest++;
480                 }
481                 /* Get a technology/[device:]number pair */
482                 tech = cur;
483                 number = strchr(tech, '/');
484                 if (!number) {
485                         ast_log(LOG_WARNING, "Dial argument takes format (technology1/[device:]number1&technology2/[device:]number2...|optional timeout)\n");
486                         goto out;
487                 }
488                 *number = '\0';
489                 number++;
490                 tmp = malloc(sizeof(struct localuser));
491                 if (!tmp) {
492                         ast_log(LOG_WARNING, "Out of memory\n");
493                         goto out;
494                 }
495                 memset(tmp, 0, sizeof(struct localuser));
496                 if (transfer) {
497                         if (strchr(transfer, 't'))
498                                 tmp->allowredirect_in = 1;
499                         else    tmp->allowredirect_in = 0;
500                         if (strchr(transfer, 'T'))
501                                 tmp->allowredirect_out = 1;
502                         else    tmp->allowredirect_out = 0;
503                         if (strchr(transfer, 'r'))
504                                 tmp->ringbackonly = 1;
505                         else    tmp->ringbackonly = 0;
506                         if (strchr(transfer, 'm'))
507                                 tmp->musiconhold = 1;
508                         else    tmp->musiconhold = 0;
509                         if (strchr(transfer, 'H'))
510                                 allowdisconnect = tmp->allowdisconnect = 1;
511                         else    allowdisconnect = tmp->allowdisconnect = 0;
512                         if(strchr(transfer, 'g'))
513                                 go_on=1;
514                 }
515                 strncpy(numsubst, number, sizeof(numsubst)-1);
516                 /* If we're dialing by extension, look at the extension to know what to dial */
517                 if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
518                         strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
519                         snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", chan->exten,restofit);
520                         if (option_debug)
521                                 ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
522                 }
523                 /* Request the peer */
524                 tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
525                 if (!tmp->chan) {
526                         /* If we can't, just go on to the next call */
527                         ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", tech);
528                         if (chan->cdr)
529                                 ast_cdr_busy(chan->cdr);
530                         free(tmp);
531                         cur = rest;
532                         continue;
533                 }
534                 if (strlen(tmp->chan->call_forward)) {
535                         char tmpchan[256];
536                         if (option_verbose > 2)
537                                 ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
538                         snprintf(tmpchan, sizeof(tmpchan),"%s@%s", tmp->chan->call_forward, tmp->chan->context);
539                         ast_hangup(tmp->chan);
540                         tmp->chan = ast_request("Local", chan->nativeformats, tmpchan);
541                         if (!tmp->chan) {
542                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s'\n", tmpchan);
543                                 free(tmp);
544                                 cur = rest;
545                                 continue;
546                         }
547                 }
548                 /* If creating a SIP channel, look for a variable called */
549                 /* VXML_URL in the calling channel and copy it to the    */
550                 /* new channel.                                          */
551                 if (strcasecmp(tech,"SIP")==0)
552                 {
553                         headp=&chan->varshead;
554                         AST_LIST_TRAVERSE(headp,current,entries) {
555                                 if (strcasecmp(ast_var_name(current),"VXML_URL")==0)
556                                 {
557                                         newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
558                                         newheadp=&tmp->chan->varshead;
559                                         AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
560                                         break;
561                                 }
562                         }
563                 }
564                 /* Check for ALERT_INFO in the SetVar list.  This is for   */
565                 /* SIP distinctive ring as per the RFC.  For Cisco 7960s,  */
566                 /* SetVar(ALERT_INFO=<x>) where x is an integer value 1-5. */
567                 /* However, the RFC says it should be a URL.  -km-         */
568
569                 if (strcasecmp(tech,"SIP")==0)
570                 {
571                         headp=&chan->varshead;
572                         AST_LIST_TRAVERSE(headp,current,entries) {
573                                 /* Search for ALERT_INFO */
574                                 if (strcasecmp(ast_var_name(current),"ALERT_INFO")==0)
575                                 {
576                                         newvar=ast_var_assign(ast_var_name(current),ast_var_value(current));
577                                         newheadp=&tmp->chan->varshead;
578                                         AST_LIST_INSERT_HEAD(newheadp,newvar,entries);
579                                         break;
580                                 }
581                         }
582                 }
583                 
584                 tmp->chan->appl = "AppDial";
585                 tmp->chan->data = "(Outgoing Line)";
586                 tmp->chan->whentohangup = 0;
587                 if (tmp->chan->callerid)
588                         free(tmp->chan->callerid);
589                 if (tmp->chan->ani)
590                         free(tmp->chan->ani);
591                 if (chan->callerid)
592                         tmp->chan->callerid = strdup(chan->callerid);
593                 else
594                         tmp->chan->callerid = NULL;
595                 /* Copy language from incoming to outgoing */
596                 strcpy(tmp->chan->language, chan->language);
597                 if (!strlen(tmp->chan->musicclass))
598                         strncpy(tmp->chan->musicclass, chan->musicclass, sizeof(tmp->chan->musicclass) - 1);
599                 if (chan->ani)
600                         tmp->chan->ani = strdup(chan->ani);
601                 else
602                         tmp->chan->ani = NULL;
603                 /* Pass hidecallerid setting */
604                 tmp->chan->restrictcid = chan->restrictcid;
605                 /* Pass callingpres setting */
606                 tmp->chan->callingpres = chan->callingpres;
607                 /* Presense of ADSI CPE on outgoing channel follows ours */
608                 tmp->chan->adsicpe = chan->adsicpe;
609                 /* pass the digital flag */
610                 ast_dup_flag(tmp->chan, chan, AST_FLAG_DIGITAL);
611                 /* Place the call, but don't wait on the answer */
612                 res = ast_call(tmp->chan, numsubst, 0);
613
614                 /* Save the info in cdr's that we called them */
615                 if (chan->cdr)
616                         ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
617
618                 /* check the restuls of ast_call */
619                 if (res) {
620                         /* Again, keep going even if there's an error */
621                         if (option_debug)
622                                 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
623                         else if (option_verbose > 2)
624                                 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
625                         ast_hangup(tmp->chan);
626                         free(tmp);
627                         cur = rest;
628                         continue;
629                 } else
630                         if (option_verbose > 2)
631                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
632                 /* Put them in the list of outgoing thingies...  We're ready now. 
633                    XXX If we're forcibly removed, these outgoing calls won't get
634                    hung up XXX */
635                 tmp->stillgoing = -1;
636                 tmp->next = outgoing;
637                 outgoing = tmp;
638                 /* If this line is up, don't try anybody else */
639                 if (outgoing->chan->_state == AST_STATE_UP)
640                         break;
641                 cur = rest;
642         } while(cur);
643         
644         if (timeout && strlen(timeout))
645                 to = atoi(timeout) * 1000;
646         else
647                 to = -1;
648         peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect);
649         if (!peer) {
650                 if (to) 
651                         /* Musta gotten hung up */
652                         res = -1;
653                  else 
654                         /* Nobody answered, next please? */
655                         res=0;
656                 
657                 goto out;
658         }
659         if (peer) {
660                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
661                    we will always return with -1 so that it is hung up properly after the 
662                    conversation.  */
663                 hanguptree(outgoing, peer);
664                 outgoing = NULL;
665                 /* If appropriate, log that we have a destination channel */
666                 if (chan->cdr)
667                         ast_cdr_setdestchan(chan->cdr, peer->name);
668                 if (peer->name)
669                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
670                 if (numsubst)
671                         pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", numsubst);
672                 /* Make sure channels are compatible */
673                 res = ast_channel_make_compatible(chan, peer);
674                 if (res < 0) {
675                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
676                         ast_hangup(peer);
677                         return -1;
678                 }
679                 /* JDG: sendurl */
680                 if( url && strlen(url) && ast_channel_supports_html(peer) ) {
681                         ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", url);
682                         ast_channel_sendurl( peer, url );
683                 } /* /JDG */
684                 if (announce && announcemsg)
685                 {
686                         int res2;
687                         // Start autoservice on the other chan
688                         res2 = ast_autoservice_start(chan);
689                         // Now Stream the File
690                         if (!res2)
691                                 res2 = ast_streamfile(peer,announcemsg,peer->language);
692                         if (!res2)
693                                 res2 = ast_waitstream(peer,"");
694                         // Ok, done. stop autoservice
695                         res2 = ast_autoservice_stop(chan);
696                 }
697                 res = ast_bridge_call(chan, peer, allowredir_in, allowredir_out, allowdisconnect);
698
699                 if (res != AST_PBX_NO_HANGUP_PEER)
700                         ast_hangup(peer);
701         }       
702 out:
703         hanguptree(outgoing, NULL);
704         LOCAL_USER_REMOVE(u);
705         
706         if((go_on>0) && (!chan->_softhangup))
707             res=0;
708             
709         return res;
710 }
711
712 int unload_module(void)
713 {
714         STANDARD_HANGUP_LOCALUSERS;
715         return ast_unregister_application(app);
716 }
717
718 int load_module(void)
719 {
720         int res;
721         res = ast_register_application(app, dial_exec, synopsis, descrip);
722         return res;
723 }
724
725 char *description(void)
726 {
727         return tdesc;
728 }
729
730 int usecount(void)
731 {
732         int res;
733         STANDARD_USECOUNT(res);
734         return res;
735 }
736
737 char *key()
738 {
739         return ASTERISK_GPL_KEY;
740 }