Merged revisions 53810 via svnmerge from
[asterisk/asterisk.git] / main / dial.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2007, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@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 Dialing API
22  *
23  * \author Joshua Colp <jcolp@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/time.h>
34 #include <signal.h>
35 #include <errno.h>
36 #include <unistd.h>
37
38 #include "asterisk/logger.h"
39 #include "asterisk/channel.h"
40 #include "asterisk/options.h"
41 #include "asterisk/utils.h"
42 #include "asterisk/lock.h"
43 #include "asterisk/linkedlists.h"
44 #include "asterisk/dial.h"
45 #include "asterisk/pbx.h"
46
47 /*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
48 struct ast_dial {
49         int num;                                           /*! Current number to give to next dialed channel */
50         enum ast_dial_result status;                       /*! Status of dial */
51         void *options[AST_DIAL_OPTION_MAX];                /*! Global options */
52         AST_LIST_HEAD_NOLOCK(, ast_dial_channel) channels; /*! Channels being dialed */
53         pthread_t thread;                                  /*! Thread (if running in async) */
54 };
55
56 /*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
57 struct ast_dial_channel {
58         int num;                               /*! Unique number for dialed channel */
59         const char *tech;                      /*! Technology being dialed */
60         const char *device;                    /*! Device being dialed */
61         void *options[AST_DIAL_OPTION_MAX];    /*! Channel specific options */
62         int cause;                             /*! Cause code in case of failure */
63         struct ast_channel *owner;             /*! Asterisk channel */
64         AST_LIST_ENTRY(ast_dial_channel) list; /*! Linked list information */
65 };
66
67 /*! \brief Typedef for dial option enable */
68 typedef void *(*ast_dial_option_cb_enable)(void *data);
69
70 /*! \brief Typedef for dial option disable */
71 typedef int (*ast_dial_option_cb_disable)(void *data);
72
73 /* Structure for 'ANSWER_EXEC' option */
74 struct answer_exec_struct {
75         char app[AST_MAX_APP]; /* Application name */
76         char *args;            /* Application arguments */
77 };
78
79 /* Enable function for 'ANSWER_EXEC' option */
80 static void *answer_exec_enable(void *data)
81 {
82         struct answer_exec_struct *answer_exec = NULL;
83         char *app = ast_strdupa((char*)data), *args = NULL;
84
85         /* Not giving any data to this option is bad, mmmk? */
86         if (ast_strlen_zero(app))
87                 return NULL;
88
89         /* Create new data structure */
90         if (!(answer_exec = ast_calloc(1, sizeof(*answer_exec))))
91                 return NULL;
92         
93         /* Parse out application and arguments */
94         if ((args = strchr(app, '|'))) {
95                 *args++ = '\0';
96                 answer_exec->args = ast_strdup(args);
97         }
98
99         /* Copy application name */
100         ast_copy_string(answer_exec->app, app, sizeof(answer_exec->app));
101
102         return answer_exec;
103 }
104
105 /* Disable function for 'ANSWER_EXEC' option */
106 static int answer_exec_disable(void *data)
107 {
108         struct answer_exec_struct *answer_exec = data;
109
110         /* Make sure we have a value */
111         if (!answer_exec)
112                 return -1;
113
114         /* If arguments are present, free them too */
115         if (answer_exec->args)
116                 free(answer_exec->args);
117
118         /* This is simple - just free the structure */
119         free(answer_exec);
120
121         return 0;
122 }
123
124 /* Application execution function for 'ANSWER_EXEC' option */
125 static void answer_exec_run(struct ast_channel *chan, char *app, char *args)
126 {
127         struct ast_app *ast_app = pbx_findapp(app);
128
129         /* If the application was not found, return immediately */
130         if (!ast_app)
131                 return;
132
133         /* All is well... execute the application */
134         pbx_exec(chan, ast_app, args);
135
136         return;
137 }
138
139 /*! \brief Options structure - maps options to respective handlers (enable/disable). This list MUST be perfectly kept in order, or else madness will happen. */
140 static const struct ast_option_types {
141         enum ast_dial_option option;
142         ast_dial_option_cb_enable enable;
143         ast_dial_option_cb_disable disable;
144 } option_types[] = {
145         { AST_DIAL_OPTION_RINGING, NULL, NULL },                                  /*! Always indicate ringing to caller */
146         { AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*! Execute application upon answer in async mode */
147         { AST_DIAL_OPTION_MAX, NULL, NULL },                                      /*! Terminator of list */
148 };
149
150 /* free the buffer if allocated, and set the pointer to the second arg */
151 #define S_REPLACE(s, new_val)           \
152         do {                            \
153                 if (s)                  \
154                         free(s);        \
155                 s = (new_val);          \
156         } while (0)
157
158 /*! \brief Maximum number of channels we can watch at a time */
159 #define AST_MAX_WATCHERS 256
160
161 /*! \brief Macro for finding the option structure to use on a dialed channel */
162 #define FIND_RELATIVE_OPTION(dial, dial_channel, ast_dial_option) (dial_channel->options[ast_dial_option] ? dial_channel->options[ast_dial_option] : dial->options[ast_dial_option])
163
164 /*! \brief Macro that determines whether a channel is the caller or not */
165 #define IS_CALLER(chan, owner) (chan == owner ? 1 : 0)
166
167 /*! \brief New dialing structure
168  * \note Create a dialing structure
169  * \return Returns a calloc'd ast_dial structure, NULL on failure
170  */
171 struct ast_dial *ast_dial_create(void)
172 {
173         struct ast_dial *dial = NULL;
174
175         /* Allocate new memory for structure */
176         if (!(dial = ast_calloc(1, sizeof(*dial))))
177                 return NULL;
178
179         /* Initialize list of channels */
180         AST_LIST_HEAD_INIT_NOLOCK(&dial->channels);
181
182         /* Initialize thread to NULL */
183         dial->thread = AST_PTHREADT_NULL;
184
185         return dial;
186 }
187
188 /*! \brief Append a channel
189  * \note Appends a channel to a dialing structure
190  * \return Returns channel reference number on success, -1 on failure
191  */
192 int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
193 {
194         struct ast_dial_channel *channel = NULL;
195
196         /* Make sure we have required arguments */
197         if (!dial || !tech || !device)
198                 return -1;
199
200         /* Allocate new memory for dialed channel structure */
201         if (!(channel = ast_calloc(1, sizeof(*channel))))
202                 return -1;
203
204         /* Record technology and device for when we actually dial */
205         channel->tech = tech;
206         channel->device = device;
207
208         /* Grab reference number from dial structure */
209         channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
210
211         /* Insert into channels list */
212         AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
213
214         return channel->num;
215 }
216
217 /*! \brief Helper function that does the beginning dialing */
218 static int begin_dial(struct ast_dial *dial, struct ast_channel *chan)
219 {
220         struct ast_dial_channel *channel = NULL;
221         int success = 0, res = 0;
222
223         /* Iterate through channel list, requesting and calling each one */
224         AST_LIST_TRAVERSE(&dial->channels, channel, list) {
225                 char numsubst[AST_MAX_EXTENSION];
226
227                 /* Copy device string over */
228                 ast_copy_string(numsubst, channel->device, sizeof(numsubst));
229
230                 /* Request that the channel be created */
231                 if (!(channel->owner = ast_request(channel->tech, 
232                         chan ? chan->nativeformats : AST_FORMAT_AUDIO_MASK, numsubst, &channel->cause))) {
233                         continue;
234                 }
235
236                 channel->owner->appl = "AppDial2";
237                 channel->owner->data = "(Outgoing Line)";
238                 channel->owner->whentohangup = 0;
239
240                 /* Inherit everything from he who spawned this Dial */
241                 if (chan) {
242                         ast_channel_inherit_variables(chan, channel->owner);
243
244                         /* Copy over callerid information */
245                         S_REPLACE(channel->owner->cid.cid_num, ast_strdup(chan->cid.cid_num));
246                         S_REPLACE(channel->owner->cid.cid_name, ast_strdup(chan->cid.cid_name));
247                         S_REPLACE(channel->owner->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
248                         S_REPLACE(channel->owner->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
249         
250                         ast_string_field_set(channel->owner, language, chan->language);
251                         ast_string_field_set(channel->owner, accountcode, chan->accountcode);
252                         channel->owner->cdrflags = chan->cdrflags;
253                         if (ast_strlen_zero(channel->owner->musicclass))
254                                 ast_string_field_set(channel->owner, musicclass, chan->musicclass);
255         
256                         channel->owner->cid.cid_pres = chan->cid.cid_pres;
257                         channel->owner->cid.cid_ton = chan->cid.cid_ton;
258                         channel->owner->cid.cid_tns = chan->cid.cid_tns;
259                         channel->owner->adsicpe = chan->adsicpe;
260                         channel->owner->transfercapability = chan->transfercapability;
261                 }
262
263                 /* Actually call the device */
264                 if ((res = ast_call(channel->owner, numsubst, 0))) {
265                         ast_hangup(channel->owner);
266                         channel->owner = NULL;
267                 } else {
268                         success++;
269                         if (option_verbose > 2)
270                                 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
271                 }
272         }
273
274         /* If number of failures matches the number of channels, then this truly failed */
275         return success;
276 }
277
278 /*! \brief Helper function that finds the dialed channel based on owner */
279 static struct ast_dial_channel *find_relative_dial_channel(struct ast_dial *dial, struct ast_channel *owner)
280 {
281         struct ast_dial_channel *channel = NULL;
282
283         AST_LIST_TRAVERSE(&dial->channels, channel, list) {
284                 if (channel->owner == owner)
285                         break;
286         }
287
288         return channel;
289 }
290
291 /*! \brief Helper function that handles control frames WITH owner */
292 static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr, struct ast_channel *chan)
293 {
294         if (fr->frametype == AST_FRAME_CONTROL) {
295                 switch (fr->subclass) {
296                 case AST_CONTROL_ANSWER:
297                         if (option_verbose > 2)
298                                 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", channel->owner->name, chan->name);
299                         AST_LIST_REMOVE(&dial->channels, channel, list);
300                         AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
301                         dial->status = AST_DIAL_RESULT_ANSWERED;
302                         break;
303                 case AST_CONTROL_BUSY:
304                         if (option_verbose > 2)
305                                 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
306                         ast_hangup(channel->owner);
307                         channel->owner = NULL;
308                         break;
309                 case AST_CONTROL_CONGESTION:
310                         if (option_verbose > 2)
311                                 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
312                         ast_hangup(channel->owner);
313                         channel->owner = NULL;
314                         break;
315                 case AST_CONTROL_RINGING:
316                         if (option_verbose > 2)
317                                 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
318                         ast_indicate(chan, AST_CONTROL_RINGING);
319                         break;
320                 case AST_CONTROL_PROGRESS:
321                         if (option_verbose > 2)
322                                 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress, passing it to %s\n", channel->owner->name, chan->name);
323                         ast_indicate(chan, AST_CONTROL_PROGRESS);
324                         break;
325                 case AST_CONTROL_VIDUPDATE:
326                         if (option_verbose > 2)
327                                 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", channel->owner->name, chan->name);
328                         ast_indicate(chan, AST_CONTROL_VIDUPDATE);
329                         break;
330                 case AST_CONTROL_PROCEEDING:
331                         if (option_verbose > 2)
332                                 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding, passing it to %s\n", channel->owner->name, chan->name);
333                         ast_indicate(chan, AST_CONTROL_PROCEEDING);
334                         break;
335                 case AST_CONTROL_HOLD:
336                         if (option_verbose > 2)
337                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", chan->name);
338                         ast_indicate(chan, AST_CONTROL_HOLD);
339                         break;
340                 case AST_CONTROL_UNHOLD:
341                         if (option_verbose > 2)
342                                 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", chan->name);
343                         ast_indicate(chan, AST_CONTROL_UNHOLD);
344                         break;
345                 case AST_CONTROL_OFFHOOK:
346                 case AST_CONTROL_FLASH:
347                         break;
348                 case -1:
349                         /* Prod the channel */
350                         ast_indicate(chan, -1);
351                         break;
352                 default:
353                         break;
354                 }
355         }
356
357         return;
358 }
359
360 /*! \brief Helper function that handles control frames WITHOUT owner */
361 static void handle_frame_ownerless(struct ast_dial *dial, struct ast_dial_channel *channel, struct ast_frame *fr)
362 {
363         /* If we have no owner we can only update the status of the dial structure, so only look at control frames */
364         if (fr->frametype != AST_FRAME_CONTROL)
365                 return;
366
367         switch (fr->subclass) {
368         case AST_CONTROL_ANSWER:
369                 if (option_verbose > 2)
370                         ast_verbose( VERBOSE_PREFIX_3 "%s answered\n", channel->owner->name);
371                 AST_LIST_REMOVE(&dial->channels, channel, list);
372                 AST_LIST_INSERT_HEAD(&dial->channels, channel, list);
373                 dial->status = AST_DIAL_RESULT_ANSWERED;
374                 break;
375         case AST_CONTROL_BUSY:
376                 if (option_verbose > 2)
377                         ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", channel->owner->name);
378                 ast_hangup(channel->owner);
379                 channel->owner = NULL;
380                 break;
381         case AST_CONTROL_CONGESTION:
382                 if (option_verbose > 2)
383                         ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", channel->owner->name);
384                 ast_hangup(channel->owner);
385                 channel->owner = NULL;
386                 break;
387         case AST_CONTROL_RINGING:
388                 if (option_verbose > 2)
389                         ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", channel->owner->name);
390                 dial->status = AST_DIAL_RESULT_RINGING;
391                 break;
392         case AST_CONTROL_PROGRESS:
393                 if (option_verbose > 2)
394                         ast_verbose (VERBOSE_PREFIX_3 "%s is making progress\n", channel->owner->name);
395                 dial->status = AST_DIAL_RESULT_PROGRESS;
396                 break;
397         case AST_CONTROL_PROCEEDING:
398                 if (option_verbose > 2)
399                         ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding\n", channel->owner->name);
400                 dial->status = AST_DIAL_RESULT_PROCEEDING;
401                 break;
402         default:
403                 break;
404         }
405
406         return;
407 }
408
409 /*! \brief Helper function that basically keeps tabs on dialing attempts */
410 static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_channel *chan)
411 {
412         int timeout = -1, count = 0;
413         struct ast_channel *cs[AST_MAX_WATCHERS], *who = NULL;
414         struct ast_dial_channel *channel = NULL;
415         struct answer_exec_struct *answer_exec = NULL;
416
417         /* Switch dialing status to trying */
418         dial->status = AST_DIAL_RESULT_TRYING;
419
420         /* If the "always indicate ringing" option is set, change status to ringing and indicate to the owner if present */
421         if (dial->options[AST_DIAL_OPTION_RINGING]) {
422                 dial->status = AST_DIAL_RESULT_RINGING;
423                 if (chan)
424                         ast_indicate(chan, AST_CONTROL_RINGING);
425         }
426
427         /* Go into an infinite loop while we are trying */
428         while ((dial->status != AST_DIAL_RESULT_UNANSWERED) && (dial->status != AST_DIAL_RESULT_ANSWERED) && (dial->status != AST_DIAL_RESULT_HANGUP) && (dial->status != AST_DIAL_RESULT_TIMEOUT)) {
429                 int pos = 0;
430                 struct ast_frame *fr = NULL;
431
432                 /* Set up channel structure array */
433                 pos = count = 0;
434                 if (chan)
435                         cs[pos++] = chan;
436
437                 /* Add channels we are attempting to dial */
438                 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
439                         if (channel->owner) {
440                                 cs[pos++] = channel->owner;
441                                 count++;
442                         }
443                 }
444
445                 /* If we have no outbound channels in progress, switch status to unanswered and stop */
446                 if (!count) {
447                         dial->status = AST_DIAL_RESULT_UNANSWERED;
448                         break;
449                 }
450
451                 /* Just to be safe... */
452                 if (dial->thread == AST_PTHREADT_STOP)
453                         break;
454
455                 /* Wait for frames from channels */
456                 who = ast_waitfor_n(cs, pos, &timeout);
457
458                 /* Check to see if our thread is being cancelled */
459                 if (dial->thread == AST_PTHREADT_STOP)
460                         break;
461
462                 /* If we are not being cancelled and we have no channel, then timeout was tripped */
463                 if (!who)
464                         continue;
465
466                 /* Find relative dial channel */
467                 if (!chan || !IS_CALLER(chan, who))
468                         channel = find_relative_dial_channel(dial, who);
469
470                 /* Attempt to read in a frame */
471                 if (!(fr = ast_read(who))) {
472                         /* If this is the caller then we switch status to hangup and stop */
473                         if (chan && IS_CALLER(chan, who)) {
474                                 dial->status = AST_DIAL_RESULT_HANGUP;
475                                 break;
476                         }
477                         ast_hangup(who);
478                         channel->owner = NULL;
479                         continue;
480                 }
481
482                 /* Process the frame */
483                 if (chan)
484                         handle_frame(dial, channel, fr, chan);
485                 else
486                         handle_frame_ownerless(dial, channel, fr);
487
488                 /* Free the received frame and start all over */
489                 ast_frfree(fr);
490         }
491
492         /* Do post-processing from loop */
493         if (dial->status == AST_DIAL_RESULT_ANSWERED) {
494                 /* Hangup everything except that which answered */
495                 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
496                         if (!channel->owner || channel->owner == who)
497                                 continue;
498                         ast_hangup(channel->owner);
499                         channel->owner = NULL;
500                 }
501                 /* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
502                 if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC)))
503                         answer_exec_run(who, answer_exec->app, answer_exec->args);
504         } else if (dial->status == AST_DIAL_RESULT_HANGUP) {
505                 /* Hangup everything */
506                 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
507                         if (!channel->owner)
508                                 continue;
509                         ast_hangup(channel->owner);
510                         channel->owner = NULL;
511                 }
512         }
513
514         return dial->status;
515 }
516
517 /*! \brief Dial async thread function */
518 static void *async_dial(void *data)
519 {
520         struct ast_dial *dial = data;
521
522         /* This is really really simple... we basically pass monitor_dial a NULL owner and it changes it's behavior */
523         monitor_dial(dial, NULL);
524
525         return NULL;
526 }
527
528 /*! \brief Execute dialing synchronously or asynchronously
529  * \note Dials channels in a dial structure.
530  * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
531  */
532 enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
533 {
534         enum ast_dial_result res = AST_DIAL_RESULT_TRYING;
535
536         /* Ensure required arguments are passed */
537         if (!dial || (!chan && !async)) {
538                 ast_log(LOG_DEBUG, "invalid #1\n");
539                 return AST_DIAL_RESULT_INVALID;
540         }
541
542         /* If there are no channels to dial we can't very well try to dial them */
543         if (AST_LIST_EMPTY(&dial->channels)) {
544                 ast_log(LOG_DEBUG, "invalid #2\n");
545                 return AST_DIAL_RESULT_INVALID;
546         }
547
548         /* Dial each requested channel */
549         if (!begin_dial(dial, chan))
550                 return AST_DIAL_RESULT_FAILED;
551
552         /* If we are running async spawn a thread and send it away... otherwise block here */
553         if (async) {
554                 dial->status = AST_DIAL_RESULT_TRYING;
555                 /* Try to create a thread */
556                 if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) {
557                         /* Failed to create the thread - hangup all dialed channels and return failed */
558                         ast_dial_hangup(dial);
559                         res = AST_DIAL_RESULT_FAILED;
560                 }
561         } else {
562                 res = monitor_dial(dial, chan);
563         }
564
565         return res;
566 }
567
568 /*! \brief Return channel that answered
569  * \note Returns the Asterisk channel that answered
570  * \param dial Dialing structure
571  */
572 struct ast_channel *ast_dial_answered(struct ast_dial *dial)
573 {
574         if (!dial)
575                 return NULL;
576
577         return ((dial->status == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
578 }
579
580 /*! \brief Return status of dial
581  * \note Returns the status of the dial attempt
582  * \param dial Dialing structure
583  */
584 enum ast_dial_result ast_dial_status(struct ast_dial *dial)
585 {
586         return dial->status;
587 }
588
589 /*! \brief Cancel async thread
590  * \note Cancel a running async thread
591  * \param dial Dialing structure
592  */
593 enum ast_dial_result ast_dial_join(struct ast_dial *dial)
594 {
595         pthread_t thread;
596
597         /* If the dial structure is not running in async, return failed */
598         if (dial->thread == AST_PTHREADT_NULL)
599                 return AST_DIAL_RESULT_FAILED;
600
601         /* Record thread */
602         thread = dial->thread;
603
604         /* Stop the thread */
605         dial->thread = AST_PTHREADT_STOP;
606
607         /* Now we signal it with SIGURG so it will break out of it's waitfor */
608         pthread_kill(thread, SIGURG);
609
610         /* Finally wait for the thread to exit */
611         pthread_join(thread, NULL);
612
613         /* Yay thread is all gone */
614         dial->thread = AST_PTHREADT_NULL;
615
616         return dial->status;
617 }
618
619 /*! \brief Hangup channels
620  * \note Hangup all active channels
621  * \param dial Dialing structure
622  */
623 void ast_dial_hangup(struct ast_dial *dial)
624 {
625         struct ast_dial_channel *channel = NULL;
626
627         if (!dial)
628                 return;
629         
630         AST_LIST_TRAVERSE(&dial->channels, channel, list) {
631                 if (channel->owner) {
632                         ast_hangup(channel->owner);
633                         channel->owner = NULL;
634                 }
635         }
636
637         return;
638 }
639
640 /*! \brief Destroys a dialing structure
641  * \note Destroys (free's) the given ast_dial structure
642  * \param dial Dialing structure to free
643  * \return Returns 0 on success, -1 on failure
644  */
645 int ast_dial_destroy(struct ast_dial *dial)
646 {
647         int i = 0;
648         struct ast_dial_channel *channel = NULL;
649
650         if (!dial)
651                 return -1;
652         
653         /* Hangup and deallocate all the dialed channels */
654         AST_LIST_TRAVERSE(&dial->channels, channel, list) {
655                 /* Disable any enabled options */
656                 for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
657                         if (!channel->options[i])
658                                 continue;
659                         if (option_types[i].disable)
660                                 option_types[i].disable(channel->options[i]);
661                         channel->options[i] = NULL;
662                 }
663                 /* Hang up channel if need be */
664                 if (channel->owner) {
665                         ast_hangup(channel->owner);
666                         channel->owner = NULL;
667                 }
668                 /* Free structure */
669                 free(channel);
670         }
671        
672         /* Disable any enabled options globally */
673         for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
674                 if (!dial->options[i])
675                         continue;
676                 if (option_types[i].disable)
677                         option_types[i].disable(dial->options[i]);
678                 dial->options[i] = NULL;
679         }
680
681         /* Free structure */
682         free(dial);
683
684         return 0;
685 }
686
687 /*! \brief Enables an option globally
688  * \param dial Dial structure to enable option on
689  * \param option Option to enable
690  * \param data Data to pass to this option (not always needed)
691  * \return Returns 0 on success, -1 on failure
692  */
693 int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data)
694 {
695         /* If the option is already enabled, return failure */
696         if (dial->options[option])
697                 return -1;
698
699         /* Execute enable callback if it exists, if not simply make sure the value is set */
700         if (option_types[option].enable)
701                 dial->options[option] = option_types[option].enable(data);
702         else
703                 dial->options[option] = (void*)1;
704
705         return 0;
706 }
707
708 /*! \brief Enables an option per channel
709  * \param dial Dial structure
710  * \param num Channel number to enable option on
711  * \param option Option to enable
712  * \param data Data to pass to this option (not always needed)
713  * \return Returns 0 on success, -1 on failure
714  */
715 int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
716 {
717         struct ast_dial_channel *channel = NULL;
718
719         /* Ensure we have required arguments */
720         if (!dial || AST_LIST_EMPTY(&dial->channels))
721                 return -1;
722         
723         /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
724         if (AST_LIST_LAST(&dial->channels)->num != num) {
725                 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
726                         if (channel->num == num)
727                                 break;
728                 }
729         } else {
730                 channel = AST_LIST_LAST(&dial->channels);
731         }
732
733         /* If none found, return failure */
734         if (!channel)
735                 return -1;
736
737         /* If the option is already enabled, return failure */
738         if (channel->options[option])
739                 return -1;
740
741         /* Execute enable callback if it exists, if not simply make sure the value is set */
742         if (option_types[option].enable)
743                 channel->options[option] = option_types[option].enable(data);
744         else
745                 channel->options[option] = (void*)1;
746
747         return 0;
748 }
749
750 /*! \brief Disables an option globally
751  * \param dial Dial structure to disable option on
752  * \param option Option to disable
753  * \return Returns 0 on success, -1 on failure
754  */
755 int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option)
756 {
757         /* If the option is not enabled, return failure */
758         if (!dial->options[option])
759                 return -1;
760
761         /* Execute callback of option to disable if it exists */
762         if (option_types[option].disable)
763                 option_types[option].disable(dial->options[option]);
764
765         /* Finally disable option on the structure */
766         dial->options[option] = NULL;
767
768         return 0;
769 }
770
771 /*! \brief Disables an option per channel
772  * \param dial Dial structure
773  * \param num Channel number to disable option on
774  * \param option Option to disable
775  * \return Returns 0 on success, -1 on failure
776  */
777 int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option)
778 {
779         struct ast_dial_channel *channel = NULL;
780
781         /* Ensure we have required arguments */
782         if (!dial || AST_LIST_EMPTY(&dial->channels))
783                 return -1;
784
785         /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
786         if (AST_LIST_LAST(&dial->channels)->num != num) {
787                 AST_LIST_TRAVERSE(&dial->channels, channel, list) {
788                         if (channel->num == num)
789                                 break;
790                 }
791         } else {
792                 channel = AST_LIST_LAST(&dial->channels);
793         }
794
795         /* If none found, return failure */
796         if (!channel)
797                 return -1;
798
799         /* If the option is not enabled, return failure */
800         if (!channel->options[option])
801                 return -1;
802
803         /* Execute callback of option to disable it if it exists */
804         if (option_types[option].disable)
805                 option_types[option].disable(channel->options[option]);
806
807         /* Finally disable the option on the structure */
808         channel->options[option] = NULL;
809
810         return 0;
811 }